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:
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "session_files"
|
||||
ADD COLUMN "matched_identifier" TEXT,
|
||||
ADD COLUMN "animal_id_string_snap" TEXT,
|
||||
ADD COLUMN "animal_name_snap" TEXT;
|
||||
@@ -49,15 +49,18 @@ model DailyStatus {
|
||||
}
|
||||
|
||||
model SessionFile {
|
||||
id String @id @default(uuid())
|
||||
daily_status_id String
|
||||
daily_status DailyStatus @relation(fields: [daily_status_id], references: [id], onDelete: Cascade)
|
||||
filename String
|
||||
file_size BigInt
|
||||
file_type String?
|
||||
last_modified BigInt?
|
||||
notes String?
|
||||
created_at DateTime @default(now())
|
||||
id String @id @default(uuid())
|
||||
daily_status_id String
|
||||
daily_status DailyStatus @relation(fields: [daily_status_id], references: [id], onDelete: Cascade)
|
||||
filename String
|
||||
file_size BigInt
|
||||
file_type String?
|
||||
last_modified BigInt?
|
||||
matched_identifier String? // the animal ID/name substring that matched in the filename
|
||||
animal_id_string_snap String? // snapshot of animal.animal_id_string at registration time
|
||||
animal_name_snap String? // snapshot of animal.animal_name at registration time
|
||||
notes String?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
@@map("session_files")
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user