feat: store matching metadata on session file registration

Each saved file now records three additional fields:
  matched_identifier    — the literal animal_id_string or animal_name
                          substring that matched in the filename
  animal_id_string_snap — snapshot of animal.animal_id_string at
                          registration time
  animal_name_snap      — snapshot of animal.animal_name at
                          registration time

This lets future consumers (scripts, exports, re-matching) identify
the subject from the file record alone, even if animal data changes.
The matched identifier is also shown in the drop preview UI (↳ 2852).

Tests: 25 total (+2 for new payload fields).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Experiments DB Dev
2026-04-23 13:41:36 -04:00
parent 5cd6d2a8a3
commit 52d5fca5d1
5 changed files with 111 additions and 43 deletions
+11 -7
View File
@@ -2,7 +2,8 @@ const router = require('express').Router();
const prisma = require('../lib/prisma');
// POST /api/daily-statuses/:id/files — register file metadata (batch)
// Body: [{ filename, file_size, file_type, last_modified, notes }, ...]
// Body: [{ filename, file_size, file_type, last_modified,
// matched_identifier, animal_id_string_snap, animal_name_snap, notes }, ...]
router.post('/daily-statuses/:id/files', async (req, res, next) => {
try {
const status = await prisma.dailyStatus.findUnique({ where: { id: req.params.id } });
@@ -26,12 +27,15 @@ router.post('/daily-statuses/:id/files', async (req, res, next) => {
files.map((f) =>
prisma.sessionFile.create({
data: {
daily_status_id: req.params.id,
filename: f.filename.trim(),
file_size: BigInt(Math.round(f.file_size)),
file_type: f.file_type ?? null,
last_modified: f.last_modified != null ? BigInt(Math.round(f.last_modified)) : null,
notes: f.notes ?? null,
daily_status_id: req.params.id,
filename: f.filename.trim(),
file_size: BigInt(Math.round(f.file_size)),
file_type: f.file_type ?? null,
last_modified: f.last_modified != null ? BigInt(Math.round(f.last_modified)) : null,
matched_identifier: f.matched_identifier ?? null,
animal_id_string_snap: f.animal_id_string_snap ?? null,
animal_name_snap: f.animal_name_snap ?? null,
notes: f.notes ?? null,
},
})
)