5 Commits

Author SHA1 Message Date
Experiments DB Dev 4a048fda88 feat: permanent calendar with editable day modal and per-subject bar chart
- Calendar moved out of List/Group tab toggle — always visible below cross-
  subject analytics (ExperimentAnalysisCharts)
- Day modal shows all subjects: existing data as read-only + Edit button,
  missing data as + Add button; both open DailyStatusForm inline
- Status changes/creates propagate up to parent via onStatusChange/onStatusCreate
  and calendar counts recompute locally (no extra API round-trip)
- Bar chart (recharts) at bottom: Total/Success/Failure bars per subject plus
  % complete text, grouped by subject name
- Tests updated: 17 ExperimentCalendar tests, 76 total passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 11:30:26 -04:00
Experiments DB Dev fe23085e0f fix: resolve DailyStatusForm test stall and add label accessibility
- Use module-level EMPTY_TEMPLATE constant as default prop to prevent
  useEffect infinite loop (new [] each render changed identity every cycle)
- Add htmlFor to date and dynamic field labels for proper a11y association
- Add role=alert to date error paragraph so tests can find it
- Update tests to pass a template with builtin fields (required by template-
  driven component design) and mock experimentsApi
- Add --max-old-space-size=8192 to test scripts to prevent OOM on full suite

All 72 frontend tests now pass across 7 suites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 10:41:17 -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 5874ed8374 feat(tests): Jest backend (38 tests), Jest RTL frontend (28 tests), Playwright E2E spec 2026-04-15 13:23:48 -04:00
Experiments DB Dev c32a5d200d feat(frontend): React UI — pages, forms, audit log section, Tailwind, Vite build 2026-04-15 13:18:31 -04:00