8 Commits

Author SHA1 Message Date
Experiments DB Dev b0c6217cb4 fix(backend): widen plot_config size cap to fit a full hiddenSubjects list
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 10:30:06 -04:00
Experiments DB Dev e9511bdac3 feat(backend): persist per-experiment plot_config via PUT /:id/plot-config
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 10:14:50 -04:00
Experiments DB Dev fe4e89f497 feat(backend): PATCH /animals/:id/csv-config endpoint
Implement TDD for new route that accepts CSV configuration with validated buckets.
Route uses auditMiddleware to log config changes and delegates validation to
validateCsvConfig helper from Task 2.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 07:49:00 -04:00
Experiments DB Dev 1ae55591f4 feat(backend): add csv_analysis_config validator 2026-05-01 07:47:17 -04:00
Experiments DB Dev ee2cf19b74 test: add analysisOnly regression tests; fix cache isolation in tests
New file tests/experimentDailyStatuses.test.js — 9 tests covering
GET /api/experiments/:id/daily-statuses:
  - 404 on unknown experiment
  - all statuses returned when no filter
  - analysisOnly=true keeps only non-null analysis_summary records
  - analysisOnly=true returns [] when none have analysis_summary
  - the exact null/object mix that caused the production 500 now passes
  - analysisOnly=false (explicit) returns all records
  - ?date= param is forwarded to Prisma correctly
  - empty-array response on zero statuses
  - returned records include expected fields

Fixed tests/calendar.test.js: existing tests were silently broken by the
cache added in the perf commit. Both test files now mock lib/cache to
always miss, so each test exercises the real route logic in isolation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 15:11:21 -04:00
Experiments DB Dev 9535f86970 feat: add experiment calendar view with per-day subject counts
New ExperimentCalendar component added as a third view mode (List / Group / Calendar)
on the Experiment Detail page.

Backend:
- GET /api/experiments/:id/calendar?field=<fieldIdOrBuiltinKey>
  Returns { field, days: { "YYYY-MM-DD": count } } where count = number of
  subjects with a non-null/non-empty value for the chosen field on that date.
  Supports both builtin fields (vitals, treatment, notes, experiment_description)
  and custom fields addressed by fieldId UUID.

Frontend:
- ExperimentCalendar component: navigable monthly grid, field selector
  (defaults to first field with "weight" in label, else first active field),
  blue badges showing subject count per day, click to open modal with all
  subjects' data for that day.
- Integrated into ExperimentDetail as displayMode "calendar", persisted
  in localStorage alongside the existing list/group modes.
- experimentsApi.getCalendar() added to API client.

Tests:
- backend/tests/calendar.test.js: 8 unit tests (404, empty days, builtin
  count, custom field count, whitespace ignored, multi-month, field echo,
  missing param).
- frontend/tests/ExperimentCalendar.test.jsx: 13 RTL tests covering
  rendering, default field selection, count badges, month navigation,
  field-change re-fetch, day click modal, and multi-subject display.

All 47 backend + 13 calendar frontend tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:26:35 -04:00
Experiments DB Dev 9b3c883bf0 fix(security): rate limiting, CORS restriction, tableName allowlist, non-root Docker, migration entrypoint, aria-live 2026-04-15 13:25:18 -04:00
Experiments DB Dev 5874ed8374 feat(tests): Jest backend (38 tests), Jest RTL frontend (28 tests), Playwright E2E spec 2026-04-15 13:23:48 -04:00