Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .claude/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -1342,3 +1342,16 @@ System User token before go-live` (warn). Best-effort, never throws, never
(`cmd | tail -1`, `prisma validate | grep`). Use pipefail or unpiped
gates. Local `npm run build` needs SKIP_ENV_VALIDATION=true; prisma
validate needs any DATABASE_URL set.

## 2026-06-13 — Phase 41–44 wave shipped; handover + next build
- Phases 41–44 merged (PRs #256/#252/#253/#254). Contract fully delivered;
audit closed. State + outstanding backlog + env gotchas captured in
docs/HANDOVER_2026-06-13.md; CLAUDE.md current-state header refreshed to 0–44
(it had drifted to 34–39).
- Session-limit crash recovery confirmed: background build agents killed ~25 min
in by the usage limit were resumed from their git worktrees after reset with
zero work lost. Prefer resumable chunks + frequent commits for long waves.
- Next build chosen by Freddie: FEATURE WAVE (deferral backlog) — vet
geolocation opt-in (KI-016 L), customer stable self-update (D-1, the one
sanctioned customer-write — confirm scope), correction-learning loop (§16),
/reports total-billed double-count cleanup. NOT started yet.
9 changes: 5 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ EquiSmile is an **AI-assisted workflow and scheduling system** for an equine den

Primary repo: `RJK134/Equismile`

## Current build state (as of 2026-06-12, session close)
## Current build state (as of 2026-06-13, session close)

- **➡️ Pre-demo operations: `docs/DEMO_GO_LIVE_CHECKLIST.md`** — one-click DB migrate+seed via GitHub Actions (§A, incl. the migration-drift remedy §A.1), Google Maps keys with the build-cache-off redeploy gotcha (§B), WhatsApp/Meta with the `/admin/simulator` fallback (§C), and the demo script walking Patrick's eight priorities. Full go-live context + Vetup integration plan: `docs/CLIENT_PRESENTATION_HANDOVER.md`.
- **Phases 34–39 are merged to `main`** (PRs #208…#246). Functional surface now includes: credential logins landing on `/my-day`; the Vetup multi-file ETL (`npm run vetup:import`, `docs/VETUP_IMPORT_RUNBOOK.md`); models `VetupVisitArchive`/`Product`/`Vaccination`/`Review`; vaccinations with bilingual certificate PDFs; `/admin/products`, `/admin/controlled-register`, `/admin/data-quality`; Vetup balances on customers + reports; vet-tap-gated reviews with the public `/[locale]/review/[token]` page; dental fiche §17 auto-report + §1 vet datalist; microchip capture on completion; recall colour badges; reports stats (finding frequency, recall split); emergency automation-hold banner; n8n workflows 08–12 (09–11 inactive, `BLOCKED-ON-VETUP-API`); Vetup exports (only-new / delta / appointments agenda). **Patrick Vangele is a system ADMIN, not a practitioner** (no calendar column, not in booking dropdowns). **Phase 38** (PR #234) added the unified task centre, supervised qualification, follow-up presets, staff-availability filtering and competition-horse recall priority. **Phase 39** (PR #244, hardened by #246) added the EquiSmile-side operational layer: **§20 invoicing** UI (list + AR/overdue + manual create, over the existing Swiss QR-bill / CAMT.054 backend), **§21 inventory** (`StockMovement` ledger + low-stock dashboard at `/admin/inventory`, `stockManagedLocally` opt-out from the Vetup overwrite), and **§23** an interactive tap-a-tooth dental odontogram over `ClinicalFinding`.
- **Phases 40–44 are also merged to `main`** (PRs #248…#258). **Phase 40** (#248): My Day day-view appointment merge, batch "book all horses at a yard", BugBot credential guard. **Phase 41** (#256): §20 invoicing completion — **credit notes** (immutable, AR-netted, QR-less PDFs) + **invoice amendment** (amend-and-reissue with a `SUPERSEDED` supersede chain); migration `20260612220000`. **Phase 42** (#252): **cancellation gap-fill** (Jun-10 deferral D-2) — a cancelled/rescheduled CONFIRMED slot within 21d raises a task-centre task proposing the top-5 nearby due-recall candidates with `/appointments/new` deep-links; pure haversine ranking, no schema change, vet approves everything. **Phase 43** (#253): **`/admin/ops`** read-only operations roll-up (D-3) + KI-015 (checklist findings folded into `/reports`). **Phase 44** (#254): `Horse.bornAt` + Vetup DOB import (KI-008), unpositioned odontogram findings, `customer-upserted` n8n emit (KI-017, producer-side only), `n8n/13` Gmail IMAP intake; migration `20260612210000`. Production migrated for both new migrations. **➡️ Next-session handover + outstanding backlog: `docs/HANDOVER_2026-06-13.md`.**
- **✅ Production drift repair MERGED (PR #225).** Production was historically `prisma db push`-ed, so `Staff.locale` is physically NOT NULL while the schema says nullable → demo seed dies with P2011 after the five credential personas. The PR carries the alignment migration (`20260610091500…`, no-op on healthy DBs — verified by local repro) + a read-only `db-drift-report.yml`. **Applied on merge:** `migrate-production.yml` ran `prisma migrate deploy`; then **Seed demo database** (production) + the **Database drift report** confirmed clean — prod is migrated, seeded, and the recurring "click a client/horse → 500" class is structurally fixed. Ops workflows (all keyed on repo secret `PRODUCTION_DATABASE_URL`, set and verified): `migrate-production.yml`, `seed-demo-database.yml`, `resolve-migration-drift.yml` (`prisma migrate resolve --applied` — never hand-INSERT into `_prisma_migrations`), `db-drift-report.yml`.
- **Auth:** email + password (Auth.js Credentials, JWT); persona cards = active `Staff` rows with a `passwordHash`, so prod must be migrated + seeded or there are no logins. Temp password `EquiSmile2026!` (re-seeding resets it). Five credential logins: Kathelijne (admin/practitioner), Natacha + Margaux (vets, fr) and Patrick Vangele + Richard Knapp (system admins, en).
- Phase history 0–39: `docs/BUILD_PLAN.md`. Active issues/caveats: `docs/KNOWN_ISSUES.md` (KI-013…KI-026). MVP scope: `docs/SCOPE_CLARIFICATIONS.md`. Contract `docs/CONTRACT_DRAFT_v3.md` (FH-ES-2026-005); costs `docs/RUNNING_COSTS.md`; support `docs/SUPPORT_MODEL.md`.
- **CI gotcha — self-built BugBot.** A repo "BugBot PR Review" GitHub Action (`anthropics/claude-code-action`, added 2026-06-12 in `4e1eaec`) runs on every PR and **fails red with "Invalid API key" until the `ANTHROPIC_API_KEY` repo secret is set** — it dies at SDK init before reviewing, so it is **not** a code signal. The real merge gates are `check` (typecheck/lint/test/build), `docker`, `security`, GitGuardian; the substantive AI review comes from the hosted **Cursor Bugbot** (`cursor[bot]`). See KI-026.
- **Latest session handover (2026-06-12):** `docs/HANDOVER_2026-06-12.md` — full state + a copy-paste prompt for the next chat instance, with this build's record link.
- Phase history 0–44: `docs/BUILD_PLAN.md`. Active issues/caveats: `docs/KNOWN_ISSUES.md` (KI-013…KI-027; KI-008/KI-015/KI-017 resolved in the Phase 41–44 wave). MVP scope: `docs/SCOPE_CLARIFICATIONS.md`. Contract `docs/CONTRACT_DRAFT_v3.md` (FH-ES-2026-005); costs `docs/RUNNING_COSTS.md`; support `docs/SUPPORT_MODEL.md`.
- **CI — self-built BugBot now WORKS.** The repo "BugBot PR Review" GitHub Action (`anthropics/claude-code-action`) used to fail red with "Invalid API key"; the `ANTHROPIC_API_KEY` repo secret was set 2026-06-12 and it now reviews green end-to-end (verified live on #249 and the Phase 41–44 PRs). The substantive AI review remains the hosted **Cursor Bugbot** (`cursor[bot]`) — treat its Medium+ findings as real and fix before merge. Real merge gates: `check` (typecheck/lint/test/build), `docker`, `security`, GitGuardian. See KI-026/KI-027.
- **Latest session handover (2026-06-13):** `docs/HANDOVER_2026-06-13.md` — full state after the Phase 41–44 wave, the chosen next build (feature-wave deferral backlog), external blockers, env gotchas, and a copy-paste prompt for the next chat instance. (Prior: `docs/HANDOVER_2026-06-12.md`.)

## Doc-first principle

Expand Down
128 changes: 128 additions & 0 deletions docs/HANDOVER_2026-06-13.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# EquiSmile — Build handover (2026-06-13)

Full state after the 2026-06-12/13 overnight wave (Phases 41–44), plus a
copy-paste prompt for the next Claude instance. Successor to
`docs/HANDOVER_2026-06-12.md`.

A fresh instance can either read this file directly (it is structured for that)
or be given §1–§9 below verbatim as a starting prompt.

---

You are picking up EquiSmile: an AI-assisted workflow + scheduling system for an
equine dental veterinary business — mobile-first, single-practice, internal use.
The vet is the decision-maker on every customer-visible action. It is NOT an
autonomous scheduler, NOT a customer self-service portal, NOT a clinical decision
system. Primary repo: RJK134/EquiSmile.

## 1. Read first (doc-first, in this order)
1. `CLAUDE.md` — current-state header refreshed 2026-06-13 to Phases 0–44.
2. `.claude/memory.md` — env gotchas; note the 2026-06-12 entries (multi-agent
build pattern, git-proxy push failures, gate plumbing) and the 2026-06-13 one.
3. `AGENTS.md` — Cursor Cloud / cgroup / DEMO_MODE notes.
4. `docs/BUILD_PLAN.md` — phase history, now 0–44.
5. `docs/KNOWN_ISSUES.md` — KI-008, KI-015, KI-017 resolved 2026-06-12.
6. `docs/SCOPE_CLARIFICATIONS.md` — MVP vs out-of-scope.
7. `docs/PRODUCTION_READINESS_AUDIT_RESPONSE.md` — fully closed (all 22 items).
8. `docs/DEMO_GO_LIVE_CHECKLIST.md` + `docs/CLIENT_PRESENTATION_HANDOVER.md` —
go-live ops + Vetup plan + Patrick's eight priorities.
9. `docs/HANDOVER_2026-06-12.md` — the prior handover.

## 2. Current state (2026-06-13)
- Contract FH-ES-2026-005 FULLY DELIVERED. 2026-04-18 audit FULLY CLOSED.
- Phases 0–44 merged to main. The 2026-06-12/13 wave (all merged by Richard):
- **#256 Phase 41** — credit notes + invoice amendment (SUPERSEDED supersede
chain, AR netted, QR-less credit-note PDFs). Migration
`20260612220000_phase41_credit_notes`.
- **#252 Phase 42** — cancellation gap-fill (Jun-10 deferral D-2): a cancelled
OR rescheduled CONFIRMED slot within 21d (env `GAP_FILL_WINDOW_DAYS`) raises
a task-centre task proposing the top-5 nearby due-recall candidates with
`/appointments/new` deep-links. Pure haversine ranking in `lib/gap-fill`. No
schema change. Vet approves everything; nothing auto-booked.
- **#253 Phase 43** — `/admin/ops` read-only operations roll-up (D-3) + KI-015
(DentalChart.checklist JSON findings folded into `/reports` at read time).
- **#254 Phase 44** — `Horse.bornAt` + Vetup DOB import (KI-008); unpositioned
odontogram findings (§23 deferral); `customer-upserted` n8n emit (KI-017,
producer only — consumer workflow 10 still Vetup-blocked); `n8n/13` Gmail
IMAP intake workflow. Migration `20260612210000_phase44_horse_born_at`.
- Plus #249 (Phase 40 Bugbot follow-up) and #258 (CI migration idempotency).
- Production already migrated (`migrate-production.yml` ran green for #254 + #256).
- Test suite ≈ 2,780 (union of the four streams; next CI prints the exact figure).
- Auth: email+password, 5 credential personas, temp password `EquiSmile2026!`.

## 3. NEXT BUILD — chosen priority: FEATURE WAVE (deferral backlog)
Freddie chose this on 2026-06-13. Four independent items. Confirm scope before
starting (esp. item 2 — it is the one customer-facing write in an internal-first
app). Build as one batched PR, or a small multi-agent worktree wave like the last
one (one agent per item, isolated worktrees, reserved migration timestamps +
per-stream i18n namespaces):
1. **Vet geolocation opt-in (KI-016 L)** — opt-in live vet location on the
planner to sharpen route proposals. No external API for the toggle itself.
2. **Customer stable self-update (D-1)** — let a customer update their yard
address (pre-confirm gate + inbound "update my stable" parse). SANCTIONED
exception to internal-first; confirm it is still wanted.
3. **Correction-learning loop (§16)** — shrink the supervised-AI 5% over time by
learning from vet edits to AI-drafted qualification messages.
4. **`/reports` "total billed" double-count cleanup** — it aggregates by
`issuedAt` with no status filter, so an amended invoice counts the SUPERSEDED
original + replacement (CANCELLED already double-counts there). Decide: filter
to live documents, or document as intended.

## 4. Rest of the backlog (NOT chosen — context)
- **Full intake→confirmation e2e (KI-016 O)** — the demo spine; strongest
demo-hardening candidate if the demo date moves up.
- **Invoicing tail**: multi-currency, recurring billing, refunds of received
money — deemed low-value for a single CHF practice; leave as deferred notes.

## 5. External blockers — NO code unblocks these (don't try)
- **Meta WhatsApp Cloud API** business verification → real send, AUTO
qualification, emergency push.
- **n8n hosting** (Railway ~CHF5/mo) → cron reminders + emergency push; workflows
08 + 12 + 13 work once hosted; 09–11 are `BLOCKED-ON-VETUP-API`.
- **Vetup API** → two-way sync; workflows 09–11; the KI-017 consumer.
- **Real STT (D-4)** → needs an OpenAI/Gemini key + Meta media access.

## 6. Go-live config (NOT code) — per `docs/DEMO_GO_LIVE_CHECKLIST.md`
DB / Auth / Google Maps (browser key is build-time inlined → redeploy with build
cache OFF) / SMTP / WhatsApp / n8n / Vetup data load (`npm run vetup:import`).

`n8n/13-gmail-imap-intake.json` is import-ready (3 nodes, ships inactive,
placeholder credentials): enable Gmail IMAP, create a Gmail App Password, fill
the IMAP credential, point the HTTP node at the same `N8N_API_KEY` Header-Auth
credential the WhatsApp workflow uses, mark existing unread inbox mail read, then
activate.

## 7. ENVIRONMENT GOTCHAS — read before you build
1. **Session usage limits** can kill long background agents ~25 min in.
Mitigation: agents work in git worktrees → resume after the limit resets, zero
work lost. Build in resumable chunks; commit often.
2. **Git proxy** (127.0.0.1 local_proxy): the FIRST push to a new branch works,
but UPDATE-pushes to an existing branch can 403 / "remote end hung up" while
git prints "Everything up-to-date". Workaround: push via GitHub MCP
`push_files`, OR push to a temp ref + open an internal PR + rebase-merge it.
ALWAYS verify pushes via ls-remote / the API; never trust the push command's
text output.
3. **Local gates**: `npm run build` needs `SKIP_ENV_VALIDATION=true`; `npx prisma
validate` needs any `DATABASE_URL` set. Don't pipe gates through tail/grep
without `set -o pipefail` — pipes swallow the real exit code. Never run
`prisma format` (it reflows the whole non-canonical schema).
4. **Self-built BugBot** ("BugBot PR Review" action) now WORKS — the
`ANTHROPIC_API_KEY` repo secret was set 2026-06-12. The substantive AI review
is Cursor Bugbot (`cursor[bot]`) — treat its Medium+ findings as real and fix
before merge. Real merge gates: `check` / `docker` / `security` / GitGuardian.

## 8. Non-negotiables (`CLAUDE.md`)
- Gates every phase: lint, typecheck, test, prisma validate, build. Mobile at
390px. British English. EN/FR i18n key parity.
- PR batching: one session = one branch = one PR; no tiny follow-up PRs — update
the existing PR. Branch naming `feature/<phase>-<short-name>` (next is 45).
- Additive, reversible migrations only; never edit a shipped migration.
- Vet is decision-maker; nothing auto-booked; all outbound customer messaging
logged and validated.
- **Final merge is always left to Richard / Freddie.**
- Append anything you learn to `.claude/memory.md` as you go — don't wait.

## 9. Suggested first actions
1. Do the doc-first read (§1).
2. Confirm the §3 feature-wave scope with Freddie/Richard (flag D-1 explicitly).
3. Branch `feature/45-…`, build to all gates green, open the PR, leave the merge.
Loading