import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import multer from 'multer'; import express from 'express'; const router = express.Router(); import { DataTypes } from 'sequelize'; import defineAttachment from '../../models/attachments.js'; import defineRunCaseAttachment from '../../models/runCaseAttachments.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default function (sequelize) { const Attachment = defineAttachment(sequelize, DataTypes); const RunCaseAttachment = defineRunCaseAttachment(sequelize, DataTypes); // Create uploads folder if it does not exist const uploadDir = path.join(__dirname, '../../public/uploads'); if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); } const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, uploadDir); }, filename: async (req, file, cb) => { const ext = path.extname(file.originalname); const baseName = path.basename(file.originalname, ext); let fileName = `${baseName}${ext}`; // Check if a file with the same name already exists let fileExists = true; let fileIndex = 1; while (fileExists) { const filePath = path.join(uploadDir, fileName); if (fs.existsSync(filePath)) { // If a file with the same name exists, add an index and rename the file fileName = `${baseName}_${fileIndex}${ext}`; fileIndex++; } else { fileExists = false; } } cb(null, fileName); }, }); const upload = multer({ storage }); // ponytail: no auth middleware, mirroring the sibling /attachments upload route // (see routes/attachments/new.js TODO). Upgrade path: add verifyProjectReporterFromRunCaseId. router.post('/', upload.array('files', 10), async (req, res) => { const t = await sequelize.transaction(); try { const runCaseId = req.query.runCaseId; if (!runCaseId) { return res.status(400).json({ error: 'runCaseId is required' }); } const files = req.files; if (files.length === 0) { return res.status(400).json({ error: 'No files uploaded' }); } const attachmentsData = files.map((file) => ({ title: file.originalname, filename: file.filename, })); const newAttachments = await Attachment.bulkCreate(attachmentsData, { transaction: t, }); const runCaseAttachmentsData = newAttachments.map((attachment) => ({ runCaseId: runCaseId, attachmentId: attachment.id, })); await RunCaseAttachment.bulkCreate(runCaseAttachmentsData, { transaction: t }); await t.commit(); res.json(newAttachments); } catch (error) { console.error(error); await t.rollback(); res.status(500).json({ error: 'Internal server error' }); } }); return router; }