fixing the submit pqq answer api
This commit is contained in:
@@ -291,10 +291,28 @@ submitPQQ_Answer:
|
||||
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||
- 'node_modules/@aws-sdk/client-s3/**'
|
||||
- 'node_modules/@aws-sdk/s3-request-presigner/**'
|
||||
- 'node_modules/@aws-sdk/types/**'
|
||||
- 'node_modules/@aws-sdk/middleware-logger/**'
|
||||
- 'node_modules/@aws-sdk/util-utf8-node/**'
|
||||
- 'node_modules/@aws-sdk/util-utf8-browser/**'
|
||||
- 'node_modules/@smithy/**'
|
||||
- 'node_modules/tslib/**'
|
||||
# Remove these large/unnecessary packages:
|
||||
- 'node_modules/fast-xml-parser/**' # Remove if not used
|
||||
- 'node_modules/lambda-multipart-parser/**' # You're using busboy directly
|
||||
- 'node_modules/busboy/**'
|
||||
# Remove these AWS utility packages (included in main SDK):
|
||||
- 'node_modules/@aws-crypto/**'
|
||||
# - 'node_modules/uuid/**' # AWS SDK includes its own
|
||||
# - 'node_modules/@aws/util-uri-escape/**'
|
||||
# - 'node_modules/@aws/util-middleware/**'
|
||||
- 'node_modules/@aws/smithy-client/**'
|
||||
events:
|
||||
- httpApi:
|
||||
path: /host/Activity_Hub/OnBoarding/submit-pqq-answer
|
||||
method: post
|
||||
method: patch
|
||||
|
||||
updatePQQ_LastAnswer:
|
||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/getPQQScore.handler
|
||||
|
||||
@@ -70,45 +70,43 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
|
||||
// 2) Content-Type check
|
||||
const contentType = event.headers["content-type"] || event.headers["Content-Type"];
|
||||
if (!contentType?.startsWith("multipart/form-data"))
|
||||
if (!contentType?.includes("multipart/form-data"))
|
||||
throw new ApiError(400, "Content-Type must be multipart/form-data");
|
||||
|
||||
if (!event.isBase64Encoded)
|
||||
throw new ApiError(400, "Body must be base64 encoded");
|
||||
|
||||
const bodyBuffer = Buffer.from(event.body!, "base64");
|
||||
// 3) Body decoding (FIXED – same as addCompanyDetails)
|
||||
const bodyBuffer = event.isBase64Encoded
|
||||
? Buffer.from(event.body!, "base64")
|
||||
: Buffer.from(event.body!, "binary");
|
||||
|
||||
const fields: any = {};
|
||||
const files: Array<{ buffer: Buffer; mimeType: string; fileName: string; fieldName: string }> = [];
|
||||
|
||||
// 3) Parse multipart data
|
||||
// 4) Parse multipart data (FIXED – using bb.write + bb.end exactly like working lambda)
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const bb = Busboy({ headers: { 'content-type': contentType } });
|
||||
|
||||
bb.on('file', (fieldname, file, info) => {
|
||||
const { filename, mimeType } = info;
|
||||
|
||||
// Skip if no filename (empty file field)
|
||||
|
||||
if (!filename) {
|
||||
file.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks: Buffer[] = [];
|
||||
let totalSize = 0;
|
||||
const MAX_SIZE = 5 * 1024 * 1024; // 5 MB
|
||||
let size = 0;
|
||||
const MAX_SIZE = 5 * 1024 * 1024;
|
||||
|
||||
file.on('data', (chunk) => {
|
||||
totalSize += chunk.length;
|
||||
if (totalSize > MAX_SIZE) {
|
||||
file.resume();
|
||||
return reject(new ApiError(400, `File ${filename} exceeds 5MB limit.`));
|
||||
file.on("data", (chunk) => {
|
||||
size += chunk.length;
|
||||
if (size > MAX_SIZE) {
|
||||
file.destroy(new Error(`File ${filename} exceeds 5MB limit.`));
|
||||
return;
|
||||
}
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
file.on('end', () => {
|
||||
// Only add file if we have data
|
||||
file.on("end", () => {
|
||||
if (chunks.length > 0) {
|
||||
files.push({
|
||||
buffer: Buffer.concat(chunks),
|
||||
@@ -119,16 +117,14 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
}
|
||||
});
|
||||
|
||||
file.on('error', (err) => {
|
||||
reject(new ApiError(400, `File upload error: ${err.message}`));
|
||||
});
|
||||
file.on("error", (err) =>
|
||||
reject(new ApiError(400, `File upload error: ${err.message}`))
|
||||
);
|
||||
});
|
||||
|
||||
bb.on('field', (fieldname, val) => {
|
||||
// Handle empty or null values
|
||||
if (val === '' || val === 'null' || val === 'undefined') {
|
||||
fields[fieldname] = null;
|
||||
} else {
|
||||
bb.on("field", (fieldname, val) => {
|
||||
if (val === '' || val === 'null' || val === 'undefined') fields[fieldname] = null;
|
||||
else {
|
||||
try {
|
||||
fields[fieldname] = JSON.parse(val);
|
||||
} catch {
|
||||
@@ -137,26 +133,21 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
}
|
||||
});
|
||||
|
||||
bb.on('close', () => {
|
||||
console.log("✅ Busboy parsing completed");
|
||||
console.log("📌 Fields:", fields);
|
||||
console.log("📁 Files:", files.length);
|
||||
resolve();
|
||||
});
|
||||
bb.on("close", () => resolve());
|
||||
bb.on("error", (err) =>
|
||||
reject(new ApiError(400, `Multipart parsing error: ${err.message}`))
|
||||
);
|
||||
|
||||
bb.on('error', (err) => {
|
||||
console.error("❌ Busboy error:", err);
|
||||
reject(new ApiError(400, `Multipart parsing error: ${err.message}`));
|
||||
});
|
||||
|
||||
bb.end(bodyBuffer);
|
||||
// IMPORTANT FIX for HTTP API
|
||||
bb.write(bodyBuffer);
|
||||
bb.end();
|
||||
});
|
||||
|
||||
// 4) Extract required fields - only activityXid, pqqQuestionXid, pqqAnswerXid are required
|
||||
const activityXid = Number(fields.activityXid);
|
||||
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
||||
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
||||
|
||||
|
||||
// Comments and files are optional
|
||||
const comments = fields.comments || null;
|
||||
|
||||
@@ -204,7 +195,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
|
||||
if (files.length > 0) {
|
||||
console.log("📤 Processing file uploads...");
|
||||
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const existingFile = existingSupportingFiles[i] || null;
|
||||
@@ -243,7 +234,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
if (existingSupportingFiles.length > files.length) {
|
||||
const filesToDelete = existingSupportingFiles.slice(files.length);
|
||||
console.log(`🗑️ Deleting ${filesToDelete.length} unused supporting files`);
|
||||
|
||||
|
||||
for (const fileToDelete of filesToDelete) {
|
||||
await pqqService.deleteSupportingFile(fileToDelete.id);
|
||||
// Also delete from S3
|
||||
@@ -254,7 +245,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
}
|
||||
} else {
|
||||
console.log("📭 No files provided in request");
|
||||
|
||||
|
||||
// If no files provided but existing files exist, delete them (cleanup)
|
||||
if (existingSupportingFiles.length > 0) {
|
||||
console.log(`🗑️ No new files provided, deleting ${existingSupportingFiles.length} existing files`);
|
||||
@@ -269,7 +260,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
|
||||
// 9) Prepare response
|
||||
const responseMessage = existingHeader ? "PQQ answer updated successfully" : "PQQ answer submitted successfully";
|
||||
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
@@ -290,8 +281,8 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
||||
total: uploadedFiles.length
|
||||
},
|
||||
operation: existingHeader ? 'updated' : 'created',
|
||||
fileOperation: files.length > 0 ?
|
||||
(existingSupportingFiles.length > 0 ? 'replaced' : 'added') :
|
||||
fileOperation: files.length > 0 ?
|
||||
(existingSupportingFiles.length > 0 ? 'replaced' : 'added') :
|
||||
(existingSupportingFiles.length > 0 ? 'removed' : 'unchanged')
|
||||
}
|
||||
})
|
||||
|
||||
@@ -46,7 +46,7 @@ export const handler = safeHandler(async (
|
||||
},
|
||||
body: JSON.stringify({
|
||||
success: true,
|
||||
message: "Bank branches retrieved successfully",
|
||||
message: "Cities retrieved successfully",
|
||||
data: branches
|
||||
}),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user