Commit Graph
2 Commits
Author SHA1 Message Date
hamedandClaude Opus 5 b3c331f0cb perf(reports): read every resource's calendar in one batch, and close the owed tests
Writing the query-count test that task 14 owed showed the growth was real: one
resource cost 10 queries, six cost 33 — about five per resource, because the
available-minutes figure walked each resource's calendar on its own.

Holidays, tenant overrides and branch hours are identical for every resource in
a report, so they now load once outside the loop; shifts and exceptions load for
all resources in one query each. The batched path is a new method rather than a
change to rawAvailability, which the booking engine also calls. The test pins
the shape of the growth, not an exact count.

Also landed:

- app:segment:seed-templates with beauty, dental and physio presets. Building
  four segments and their requirements by hand is the first thing a new clinic
  must do and the most tedious; this gives them something to edit instead of an
  empty page. It refuses to touch a service that already has segments unless
  --force, and it will not invent resource types the tenant never defined.
- book-all is all-or-nothing, proven rather than asserted: with a calendar open
  one day a week and a 1-2 day protocol gap, session one finds a slot and
  session two cannot, and every session must come back planned.
- credit_refundable: false takes the credit back with a negative adjustment and
  deletes nothing — the ledger stays append-only.
- the segments editor has frontend tests, including that it sends back what the
  user sees and renders read-only without the permission.

useBranches now returns [] for a non-array payload instead of throwing
"branches.map is not a function" and taking the page down with it.

BookingLocationsScanTest built a Clinic around a Doctor loaded from a different
manager, which Doctrine treats as a new entity; it flushed fine most runs and
failed on cascade in others. It now loads the doctor from the same manager.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 14:22:22 +03:30
hamedandClaude Opus 5 d813843fcd feat(branch): admin UI for branch working hours and rooms, plus real API docs
Three pages, all on the existing design system: BranchesPage lists the current
environment's booking locations with their working-hours and active-room counts,
and two subpages edit the week and the rooms. The list page deliberately does not
create or rename a branch — clinic and doctor detail pages already do that, and
duplicating it would give one physical place two edit surfaces. Route permission
reuses `appointment_settings` rather than inventing a new one.

Two real bugs fell out of exercising this end to end:

`days` was serialising as a JSON *array*, not an object keyed "0".."6" — keys 0..6
are sequential so json_encode collapses them to a list. The client reads days["0"]
either way, so nothing looked broken, but the response shape was unstable: one
missing day would flip the same field to an object. The controller now casts to
stdClass and WorkingHoursTest::testDaysIsAJsonObjectNotAnArray pins it. Found by
curling the endpoint for the docs, not by any test.

`<input type="time">` caps at 23:59, so it can neither display nor produce the
legal end value 1440. An all-day range would have vanished from the form and been
corrupted by the first save. Ranges now carry an explicit end-of-day flag, with a
round-trip test proving 1440 survives.

docs/api/branch.md documents all eight endpoints with responses captured from real
curl runs against ddev, including the 422 and 404 bodies. doctor.md records that
active/timezone now appear on all nine existing address endpoints (additive), and
tenancy.md gains the two lessons this task taught: an aggregate child whose root is
itself declared global inherits no environment and needs a real pair, and
TenantFilter is not a substitute for an explicit ownership check because hard
isolation only applies to a *chosen* context.

Verified: phpunit 1067 tests / 2974 assertions green; slot-mode frozen contract
green; phpstan 14 errors before and after, none in touched files; tsc clean;
vitest 87 files / 612 tests green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 16:48:49 +03:30