Commit Graph
5 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 000cf70761 feat(resources): warn before switching a resource off, and pick dates in Jalali
The deactivation warning was blocked on task 07: there was no way to count "the
appointments on this resource" until occupancy rows linked the two. They do
now, so GET /resource/{uuid} returns upcoming_appointments. It stays off the
list endpoint, where it would be one count query per row.

It is a warning, not a block, and the wording says so: switching a resource off
does not cancel anything, it only removes the resource from future searches.
The panel shows it the moment the "active" box is unticked.

The calendar's exception range still used <input type="date">, which is
Gregorian. Operators say dates in Jalali, and the mental conversion is exactly
where an exception gets recorded a day off. PersianDateInput takes the same
YYYY-MM-DD string, so this is a drop-in swap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 13:45:25 +03:30
hamedandClaude Opus 5 4d722830e3 feat(resource): calendar UI, holiday admin, backfill and interval algebra
Completes task 03. The resource calendar page edits weekly shifts, records leave and
maintenance, and previews two weeks of availability with a Persian reason for every
empty day — showing the raw server key ("outside_branch_hours") to a user would have
been a meaningless message. The preview is labelled raw on the page itself, because
booked appointments are not subtracted yet and mistaking it for bookable time leads
to overbooking.

The interval algebra moved to src/Shared/Time/TimeInterval.php with twelve unit
tests: tasks 05 and 06 need the same union/intersect/subtract, and a second
implementation is how two subtly different definitions of "overlap" get born. The
half-open [start, end) contract is what makes a shift ending at 13:00 and one
starting at 13:00 not overlap.

AvailabilityQueryCountTest locks the query count flat: one day and ninety days cost
exactly the same number of queries. Without it the first refactor can put a query
inside the day loop and a 90-day response quietly becomes hundreds of queries —
something only production would reveal.

app:resource:calendar:backfill derives shifts from existing WeeklySchedule sessions,
so the resources created in task 02 are not left with empty calendars. It skips any
resource a user has already configured, which is also what makes it idempotent. The
weekly schedule itself is untouched: this is a copy, not a migration.

Also added --replace to the holiday import. upsert keys on the date, so a row written
with a *wrong* date can never correct itself — re-running just creates the right row
beside the wrong one. That is exactly what happened after fixing the Jalali
conversion bug, and it was caught while capturing real responses for the docs.

Deferred with reasons recorded in the checklist: seasonal shift validity (two
nullable columns can be added later without backfill, so "needed from day one" does
not hold), and a Jalali date picker in the exception form.

1154 tests / 3229 assertions. phpstan at its 14-error baseline, none in touched
files. tsc clean, vitest 622 tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 18:28:48 +03:30
hamed 70739691d1 Add checklists for tasks 11 to 14 covering credit ledger, treatment course, cancellation policies, and event utilization
- Created checklist for task 11: Package and Credit Ledger
- Created checklist for task 12: Treatment Course
- Created checklist for task 13: Cancellation Policy, No-Show, and Waitlist
- Created checklist for task 14: Domain Events and Utilization Reports
2026-07-30 12:12:45 +03:30
hamed 021d0eb6b2 feat: implement cancellation policy, no-show tracking, and waitlist management
- Add implementation notes for cancellation and waitlist features.
- Create task documentation outlining goals, current status, and acceptance criteria for cancellation policy and resource utilization reporting.
- Establish architecture for domain events and outbox pattern to ensure reliable event publishing.
- Define database schema for domain events and necessary queries for resource utilization and plan accuracy reports.
- Implement detailed implementation notes covering edge cases, testing strategies, and documentation requirements.
2026-07-30 11:43:58 +03:30