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:
@@ -249,8 +249,8 @@ describe('remove files before saving', () => {
|
||||
// ── Saving ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('saving metadata', () => {
|
||||
it('calls sessionFilesApi.create with correct payload for each subject', async () => {
|
||||
const file = makeFile(`${DATE}_2852_trials.csv`); // size = 1 byte (content 'x')
|
||||
it('calls sessionFilesApi.create with correct payload including matching metadata', async () => {
|
||||
const file = makeFile(`${DATE}_2852_trials.csv`);
|
||||
const savedFile = makeSavedFile('f1', 's-a1', file.name, String(file.size));
|
||||
sessionFilesApi.create.mockResolvedValue([savedFile]);
|
||||
|
||||
@@ -264,9 +264,34 @@ describe('saving metadata', () => {
|
||||
's-a1',
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
filename: `${DATE}_2852_trials.csv`,
|
||||
file_size: file.size,
|
||||
file_type: 'CSV',
|
||||
filename: `${DATE}_2852_trials.csv`,
|
||||
file_size: file.size,
|
||||
file_type: 'CSV',
|
||||
matched_identifier: '2852',
|
||||
animal_id_string_snap: '2852',
|
||||
animal_name_snap: 'Rat 2852',
|
||||
}),
|
||||
])
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('sets matched_identifier to animal_name when file matched by name', async () => {
|
||||
const animal = { id: 'b1', animal_name: 'Rat A', animal_id_string: null };
|
||||
const row = { animal, status: { id: 's-b1', animal_id: 'b1', date: `${DATE}T00:00:00.000Z` } };
|
||||
sessionFilesApi.create.mockResolvedValue([]);
|
||||
render(<FileDropZone rows={[row]} date={DATE} />);
|
||||
dropFiles([makeFile(`${DATE}_Rat_A_trials.csv`)]);
|
||||
await waitFor(() => screen.getByTestId('save-btn'));
|
||||
fireEvent.click(screen.getByTestId('save-btn'));
|
||||
await waitFor(() =>
|
||||
expect(sessionFilesApi.create).toHaveBeenCalledWith(
|
||||
's-b1',
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
matched_identifier: 'Rat A',
|
||||
animal_id_string_snap: null,
|
||||
animal_name_snap: 'Rat A',
|
||||
}),
|
||||
])
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user