diff --git a/src/index.js b/src/index.js index 615ecfc0..6a3e9987 100644 --- a/src/index.js +++ b/src/index.js @@ -1196,119 +1196,246 @@ fastify.post('/api/uploads-user/:customerId', async (request, reply) => { }); -fastify.post("/api/uploads-electricty-work/:customerId/:installationId", async (request, reply) => { - try { - const { customerId, installationId } = request.params; - const files = await request.files(); // Await files properly +// fastify.post("/api/uploads-electricty-work/:customerId/:installationId", async (request, reply) => { +// try { +// const { customerId, installationId } = request.params; +// const files = await request.files(); // Await files properly - if (!files || files.length === 0) { - return reply.code(400).send({ error: "No files uploaded" }); - } +// if (!files || files.length === 0) { +// return reply.code(400).send({ error: "No files uploaded" }); +// } - const bucketName = "arminta_profile_pictures"; - const publicUrls = []; +// const bucketName = "arminta_profile_pictures"; +// const publicUrls = []; - for await (const file of files) { - const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; - const filePath = `electricty_work_picture/${uniqueFileName}`; +// for await (const file of files) { +// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; +// const filePath = `electricty_work_picture/${uniqueFileName}`; - console.log(`Uploading file: ${file.filename} → ${filePath}`); +// console.log(`Uploading file: ${file.filename} → ${filePath}`); - const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); +// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); - file.file.pipe(writeStream); +// file.file.pipe(writeStream); - await new Promise((resolve, reject) => { - writeStream.on("finish", async () => { - try { - await storage.bucket(bucketName).file(filePath).makePublic(); - const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; - publicUrls.push(publicUrl); - console.log(`File uploaded: ${publicUrl}`); - resolve(); - } catch (error) { - console.error("Failed to make file public:", error); - reject(error); - } - }); +// await new Promise((resolve, reject) => { +// writeStream.on("finish", async () => { +// try { +// await storage.bucket(bucketName).file(filePath).makePublic(); +// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; +// publicUrls.push(publicUrl); +// console.log(`File uploaded: ${publicUrl}`); +// resolve(); +// } catch (error) { +// console.error("Failed to make file public:", error); +// reject(error); +// } +// }); - writeStream.on("error", (err) => { - console.error("Failed to upload file:", err); - reject(err); - }); +// writeStream.on("error", (err) => { +// console.error("Failed to upload file:", err); +// reject(err); +// }); +// }); +// } + +// // Update MongoDB: Convert URLs to { url: "..." } objects +// const updatedRecord = await ElectrictyWorkPictures.findOneAndUpdate( +// { customerId, installationId }, +// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images +// { new: true, upsert: true } +// ); + +// reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); +// } catch (err) { +// console.error("Upload Error:", err); +// reply.code(500).send({ error: "An error occurred", details: err.message }); +// } +// }); + +fastify.post( + "/api/uploads-electricty-work/:customerId/:installationId", + { preHandler: upload.any() }, // allow multiple files + async (request, reply) => { + try { + const { customerId, installationId } = request.params; + const files = request.files; + + if (!files || files.length === 0) { + return reply.code(400).send({ error: "No files uploaded" }); + } + + const bucketName = "arminta_profile_pictures"; + const publicUrls = []; + + for (const file of files) { + const uniqueFileName = `${Date.now()}-${Math.random() + .toString(36) + .substring(7)}-${file.originalname}`; + const filePath = `electricty_work_picture/${uniqueFileName}`; + + // ✅ Handle buffer vs path depending on multer storage + const fileBuffer = file.buffer + ? file.buffer // memoryStorage + : await fs.promises.readFile(file.path); // diskStorage + + await storage.bucket(bucketName).file(filePath).save(fileBuffer); + + await storage.bucket(bucketName).file(filePath).makePublic(); + const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; + publicUrls.push(publicUrl); + + console.log(`✅ Uploaded: ${publicUrl}`); + } + + // Update MongoDB + const updatedRecord = await ElectrictyWorkPictures.findOneAndUpdate( + { customerId, installationId }, + { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } }, + { new: true, upsert: true } + ); + + return reply.send({ + success: true, + pictures: publicUrls, + details: updatedRecord, }); + } catch (err) { + console.error("❌ Upload Error:", err); + return reply.code(500).send({ error: "Upload failed", details: err.message }); } + } +); - // Update MongoDB: Convert URLs to { url: "..." } objects - const updatedRecord = await ElectrictyWorkPictures.findOneAndUpdate( - { customerId, installationId }, - { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images - { new: true, upsert: true } - ); +// fastify.post("/api/uploads-manualTestVideo-work/:customerId/:installationId", async (request, reply) => { +// try { +// const { customerId, installationId } = request.params; +// const files = await request.files(); // Await files properly - reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); - } catch (err) { - console.error("Upload Error:", err); - reply.code(500).send({ error: "An error occurred", details: err.message }); - } -}); +// if (!files || files.length === 0) { +// return reply.code(400).send({ error: "No files uploaded" }); +// } -fastify.post("/api/uploads-manualTestVideo-work/:customerId/:installationId", async (request, reply) => { - try { - const { customerId, installationId } = request.params; - const files = await request.files(); // Await files properly +// const bucketName = "arminta_profile_pictures"; +// const publicUrls = []; - if (!files || files.length === 0) { - return reply.code(400).send({ error: "No files uploaded" }); - } +// for await (const file of files) { +// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; +// const filePath = `electricty_work_picture/${uniqueFileName}`; - const bucketName = "arminta_profile_pictures"; - const publicUrls = []; +// console.log(`Uploading file: ${file.filename} → ${filePath}`); - for await (const file of files) { - const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; - const filePath = `electricty_work_picture/${uniqueFileName}`; +// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); - console.log(`Uploading file: ${file.filename} → ${filePath}`); +// file.file.pipe(writeStream); - const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); +// await new Promise((resolve, reject) => { +// writeStream.on("finish", async () => { +// try { +// await storage.bucket(bucketName).file(filePath).makePublic(); +// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; +// publicUrls.push(publicUrl); +// console.log(`File uploaded: ${publicUrl}`); +// resolve(); +// } catch (error) { +// console.error("Failed to make file public:", error); +// reject(error); +// } +// }); - file.file.pipe(writeStream); +// writeStream.on("error", (err) => { +// console.error("Failed to upload file:", err); +// reject(err); +// }); +// }); +// } - await new Promise((resolve, reject) => { - writeStream.on("finish", async () => { - try { - await storage.bucket(bucketName).file(filePath).makePublic(); - const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; - publicUrls.push(publicUrl); - console.log(`File uploaded: ${publicUrl}`); - resolve(); - } catch (error) { - console.error("Failed to make file public:", error); - reject(error); - } +// // Update MongoDB: Convert URLs to { url: "..." } objects +// const updatedRecord = await ManualTestVideo.findOneAndUpdate( +// { customerId, installationId }, +// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images +// { new: true, upsert: true } +// ); + +// reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); +// } catch (err) { +// console.error("Upload Error:", err); +// reply.code(500).send({ error: "An error occurred", details: err.message }); +// } +// }); + +fastify.post( + "/api/uploads-manualTestVideo-work/:customerId/:installationId", + { preHandler: upload.any() }, // Multer handles multiple files + async (request, reply) => { + try { + const { customerId, installationId } = request.params; + const files = request.files; // Multer stores files here + + if (!files || files.length === 0) { + return reply.code(400).send({ error: "No files uploaded" }); + } + + const bucketName = "arminta_profile_pictures"; + const publicUrls = []; + + for (const file of files) { + const uniqueFileName = `${Date.now()}-${Math.random() + .toString(36) + .substring(7)}-${file.originalname}`; + const filePath = `manual_test_video/${uniqueFileName}`; + + console.log(`Uploading video: ${file.originalname} → ${filePath}`); + + // Create a write stream for large video files + const gcsFile = storage.bucket(bucketName).file(filePath); + const stream = gcsFile.createWriteStream({ + metadata: { contentType: file.mimetype }, // Keep correct video type + resumable: false, }); - writeStream.on("error", (err) => { - console.error("Failed to upload file:", err); - reject(err); + // Write buffer to GCS stream + stream.end(file.buffer); + + await new Promise((resolve, reject) => { + stream.on("finish", async () => { + try { + await gcsFile.makePublic(); + const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; + publicUrls.push(publicUrl); + console.log(`✅ Uploaded: ${publicUrl}`); + resolve(); + } catch (err) { + reject(err); + } + }); + stream.on("error", (err) => { + console.error("Upload Error:", err); + reject(err); + }); }); - }); - } + } - // Update MongoDB: Convert URLs to { url: "..." } objects - const updatedRecord = await ManualTestVideo.findOneAndUpdate( - { customerId, installationId }, - { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images - { new: true, upsert: true } - ); + // Update MongoDB: store array of { url: "..." } + const updatedRecord = await ManualTestVideo.findOneAndUpdate( + { customerId, installationId }, + { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } }, + { new: true, upsert: true } + ); - reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); - } catch (err) { - console.error("Upload Error:", err); - reply.code(500).send({ error: "An error occurred", details: err.message }); + return reply.send({ + success: true, + videos: publicUrls, + details: updatedRecord, + }); + } catch (err) { + console.error("Upload Error:", err); + return reply + .code(500) + .send({ error: "Upload failed", details: err.message }); + } } -}); +); fastify.post("/api/uploads-plumbing-work/:customerId/:installationId", async (request, reply) => { try { @@ -1367,62 +1494,62 @@ fastify.post("/api/uploads-plumbing-work/:customerId/:installationId", async (re } }); -fastify.post("/api/uploads-material-recieved/:customerId/:installationId", async (request, reply) => { - try { - const { customerId, installationId } = request.params; - const files = await request.files(); // Await files properly +// fastify.post("/api/uploads-material-recieved/:customerId/:installationId", async (request, reply) => { +// try { +// const { customerId, installationId } = request.params; +// const files = await request.files(); // Await files properly - if (!files || files.length === 0) { - return reply.code(400).send({ error: "No files uploaded" }); - } +// if (!files || files.length === 0) { +// return reply.code(400).send({ error: "No files uploaded" }); +// } - const bucketName = "arminta_profile_pictures"; - const publicUrls = []; +// const bucketName = "arminta_profile_pictures"; +// const publicUrls = []; - for await (const file of files) { - const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; - const filePath = `plumbing_work_picture/${uniqueFileName}`; +// for await (const file of files) { +// const uniqueFileName = `${Date.now()}-${Math.random().toString(36).substring(7)}-${file.filename}`; +// const filePath = `plumbing_work_picture/${uniqueFileName}`; - console.log(`Uploading file: ${file.filename} → ${filePath}`); +// console.log(`Uploading file: ${file.filename} → ${filePath}`); - const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); +// const writeStream = storage.bucket(bucketName).file(filePath).createWriteStream(); - file.file.pipe(writeStream); +// file.file.pipe(writeStream); - await new Promise((resolve, reject) => { - writeStream.on("finish", async () => { - try { - await storage.bucket(bucketName).file(filePath).makePublic(); - const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; - publicUrls.push(publicUrl); - console.log(`File uploaded: ${publicUrl}`); - resolve(); - } catch (error) { - console.error("Failed to make file public:", error); - reject(error); - } - }); +// await new Promise((resolve, reject) => { +// writeStream.on("finish", async () => { +// try { +// await storage.bucket(bucketName).file(filePath).makePublic(); +// const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; +// publicUrls.push(publicUrl); +// console.log(`File uploaded: ${publicUrl}`); +// resolve(); +// } catch (error) { +// console.error("Failed to make file public:", error); +// reject(error); +// } +// }); - writeStream.on("error", (err) => { - console.error("Failed to upload file:", err); - reject(err); - }); - }); - } +// writeStream.on("error", (err) => { +// console.error("Failed to upload file:", err); +// reject(err); +// }); +// }); +// } - // Update MongoDB: Convert URLs to { url: "..." } objects - const updatedRecord = await MaterialRecievedPictures.findOneAndUpdate( - { customerId, installationId }, - { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images - { new: true, upsert: true } - ); +// // Update MongoDB: Convert URLs to { url: "..." } objects +// const updatedRecord = await MaterialRecievedPictures.findOneAndUpdate( +// { customerId, installationId }, +// { $push: { pictureUrl: { $each: publicUrls.map(url => ({ url })) } } }, // Append new images +// { new: true, upsert: true } +// ); - reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); - } catch (err) { - console.error("Upload Error:", err); - reply.code(500).send({ error: "An error occurred", details: err.message }); - } -}); +// reply.send({ success: true, pictures: publicUrls, details: updatedRecord }); +// } catch (err) { +// console.error("Upload Error:", err); +// reply.code(500).send({ error: "An error occurred", details: err.message }); +// } +// }); // fastify.post("/api/installLogin", { @@ -1537,7 +1664,61 @@ fastify.post("/api/uploads-material-recieved/:customerId/:installationId", async // }, // }); +fastify.post( + "/api/uploads-material-recieved/:customerId/:installationId", + { preHandler: upload.any() }, // use 'files' field for multiple uploads + async (request, reply) => { + try { + const { customerId, installationId } = request.params; + const files = request.files; // multer-style files array + + if (!files || files.length === 0) { + return reply.code(400).send({ error: "No files uploaded" }); + } + + const bucketName = "arminta_profile_pictures"; + const publicUrls = []; + + for (const file of files) { + // Generate unique file name + const uniqueFileName = `${Date.now()}-${Math.random() + .toString(36) + .substring(7)}-${file.originalname}`; + const filePath = `plumbing_work_picture/${uniqueFileName}`; + + // Read file buffer + const fileBuffer = await fs.promises.readFile(file.path); + + // Upload to GCS + await storage.bucket(bucketName).file(filePath).save(fileBuffer); + // Make file public + await storage.bucket(bucketName).file(filePath).makePublic(); + + const publicUrl = `https://storage.googleapis.com/${bucketName}/${filePath}`; + publicUrls.push(publicUrl); + } + + // Save/Update in DB + const updatedRecord = await MaterialRecievedPictures.findOneAndUpdate( + { customerId, installationId }, + { $push: { pictureUrl: { $each: publicUrls.map((url) => ({ url })) } } }, // Append images + { new: true, upsert: true } + ); + + return reply.send({ + success: true, + pictures: publicUrls, + details: updatedRecord, + }); + } catch (err) { + request.log.error(err); + return reply + .code(500) + .send({ error: "Upload failed", details: err.message }); + } + } +); fastify.post("/api/installLogin", { schema: { description: "Login as Installation Manager",