feat: upload test record attachments per run case
Allow testers to attach evidence files to a single test case within a specific test run, proving the test was actually executed. Attachments are scoped to the RunCase (per-execution), not the shared case definition. Backend: - runCaseAttachments join table + model (CASCADE on runCase/attachment) - POST/GET /runcaseattachments routes (reuse /attachments download+delete) Frontend: - new "Test record" tab in the run case detail pane with drag-and-drop upload, scoped to reporters; i18n for all 6 locales Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
35
backend/routes/runcaseattachments/index.js
Normal file
35
backend/routes/runcaseattachments/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
import { DataTypes } from 'sequelize';
|
||||
import defineAttachment from '../../models/attachments.js';
|
||||
import defineRunCase from '../../models/runCases.js';
|
||||
|
||||
export default function (sequelize) {
|
||||
const Attachment = defineAttachment(sequelize, DataTypes);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
RunCase.belongsToMany(Attachment, { through: 'runCaseAttachments', foreignKey: 'runCaseId', otherKey: 'attachmentId' });
|
||||
Attachment.belongsToMany(RunCase, { through: 'runCaseAttachments', foreignKey: 'attachmentId', otherKey: 'runCaseId' });
|
||||
|
||||
// ponytail: no auth middleware, mirroring the sibling /attachments routes (TODO there).
|
||||
router.get('/', async (req, res) => {
|
||||
const { runCaseId } = req.query;
|
||||
if (!runCaseId) {
|
||||
return res.status(400).json({ error: 'runCaseId is required' });
|
||||
}
|
||||
|
||||
try {
|
||||
const runCase = await RunCase.findByPk(runCaseId, {
|
||||
include: [{ model: Attachment }],
|
||||
});
|
||||
if (!runCase) {
|
||||
return res.status(404).send('RunCase not found');
|
||||
}
|
||||
res.json(runCase.Attachments);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send('Internal Server Error');
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
Reference in New Issue
Block a user