# Clinical Platform — Execution Ledger

**Feature:** unified clinical platform (Clinic + Nutrition + Dental + Hospital + GYN on one shared clinical core).
**Source plan:** `plans/clinical-platform-master-plan.html` (sources: `plans/clinical-platform/master-plan.md` phases table, `design-visit-shell.md`, `design-data-layers.md`, `design.md`, `design-gyn-integration.md`, `legacy-obgy-options-analysis.md`, `visit-shell-prototype.html`).
**Install:** moonui3 — BE `/home/moonui3/moon-erp-be`, FE `/home/moonui3/public_html/moon-erp`, branch `hazemdev3`, dev DB `moonui3_dev_be`.
**Owner acceptance:** each phase ships working and is tested by the owner on `https://moonui3.elbaset.com/app/`; the new visit shell runs next to the old screen behind `clinic.visit_shell` until he approves. The GYN client can go live when every ★ phase is ✅.

## Owner directives (binding)
- 2026-10-22: execute the whole plan, every phase, **without stopping and without asking** (owner is away). Parallel Opus agents for speed. Consult **Fable** on UI and hard design problems.
- Merge to `main` after each phase (memory `clinical-platform-owner-moonui3`). Deploy `/app` after every FE change (memory). Never ship/publish to clients.
- Each specialty keeps its identity: nutrition board and dental workspace stay the default exactly; unification is in the shared layer only.
- Pick-don't-type option display (legacy OBGY findings): one `lookup_key` catalog, inline-add, per-doctor favourites, pickers behind buttons; never per-field lookup tables, never CSV multi-select.
- Order ≠ execution: lab/rad/rx cards create orders only; LIS/pharmacy execute; results return auto or by manual external entry.
- Drugs come from the formulary (`clinic_drugs`) optionally linked to a product per `clinic.pharmacy_source`; labs from LIS.

## Execution rules
- **Writers:** sub-agents write code but never run git/composer/migrate; the orchestrator commits, migrates dev (same step), and merges. Concurrent agents only on **explicitly disjoint file sets**; at most one agent per shared hot file (routes/api.php, HistoryService, Encounter model, consultation component).
- **Tests:** targeted Pest files run with `/opt/cpanel/ea-php82/root/usr/bin/php vendor/bin/pest <files>` (sqlite :memory:); no full-module suites mid-flight (skill override). FE: `npx ng build --base-href /app/` must pass.
- Helpers in Pest files are prefixed per WP (global-collision memory).
- `[FIN]` = money/GL/schema of shared core → design review (Fable/advisor; architect agent as fallback).

## Baseline (pre-existing failures — not ours)
- Role/screen suites (verified with PERM's files stashed, 2026-10-22): ClinicRoleManagementTest ×3 (role save now adds screen.clinic.*), RoleApiTest ×2, RoleLifecycleTest ×1, RoleTenantScopingTest ×2, ScreenPermissionTest ×1 ("production_rnd already exists").
- AuthApiTest › can register a new user (register() is closed → 403). AppointmentTest › queue index returns live queue (done visits stay on board since ISS-9102). VitalsFoldInTest fails when run alone (uses vitalsActor() from VitalsTest).
- `Modules/Core/tests/Feature/SessionApiTest.php` › "login captures ip and user_agent" → 403 account_inactive (CORE-063 merge). Fails with our changes reverted.

## WP table

| WP | Scope | Repo | Depends | Review | Migr | Status | Commits |
|----|-------|------|---------|--------|------|--------|---------|
| P0 | Foundation: encounters.kind/admission_id, signed-visit order lock, attachments morph/external/private, docs w/o encounter, MedicationFrequency, PharmacySource | BE | — | self | yes | ✅ | 622738b66 |
| SEC1-1 | Deactivate≠delete, disable kills sessions (EnsureUserActive), token expiry | BE | — | self | no | ✅ | eb11b0c8d |
| SEC1-2 | Signed download URLs | BE | — | — | — | ✅ n/a (downloads already auth+permission, no ?token=) | — |
| SEC1-3 | MFA (TOTP) + recovery codes + idle logout + FE enrollment/challenge | BE+FE | SEC1-1 | Fable(UX) | yes | ✅ Sec1MfaTest 15 + auth suites green; ng build ✅; browser check pending deploy | BE 7b1626369 · FE b8294006 |
| D0 | Pack re-apply fix, engine columns, isolation scope, gyn_ob type, reader filter | BE | P0 | self | yes | ✅ (isolation effective after AF2 7551cca82; dev check: 0 nut_/dent_ left as core) | ad6889f95 f826f80a8 09c82c275 e53368038 |
| E1a | show_if/module_key/repeat_group/lookup_key/is_private + engine-v2 input types | BE | D0 | self | yes | ✅ | d2bddeb9f |
| E1b-d | ShowIfEvaluator, lookup catalog+favourites, ComputedRegistry, show_if-aware required enforcement, v2 types crash fix | BE | E1a | self | yes | ✅ | dd0f292fd |
| AUDIT | Read-only review of P0..E1a vs plan | BE | — | Opus | — | ✅ 2026-10-22 — 3 HIGH, 5 MED, LOWs (see Decisions) | — |
| AF1 | H1 duplicate pharmacy_source def (flipped default) + fallback→products; H2 global token expiry would kill LIS bridge tokens → per-token expires_at on interactive login; M1 assertNotLocked→assertEditable; M2 decide-here on cancelled encounter; SEC1 lows (self-deactivate, txn, message) | BE | AUDIT | self | no | ✅ P0 test 12, Sec1 6, UserApi 13 green; decide-here-on-cancelled guard has no test | d0944a478 |
| AF2 | H3 isolation backfill (nut_/dent_/gyn), pack stamps clinical_type + keeps clinic edits, registration reader filter, EncounterHistory column-based; M3 encounters.kind from admissions; M4 report writers keyed (company,ref_key) + dedupe | BE | AUDIT | self | yes | ✅ 11 new + 358 related green; + open() accepts kind/admission_id, ClinicalIntent::externalDocument by ref_key | 7551cca82 |
| AF3 | M5 attachments: apply is_private, link-only rows, kind vocab, attachable allow-list | BE | AUDIT | self | no | ✅ 14+3 suites green; follow-ups AF3b | d0944a478 |
| PERM | Grant all new platform permissions: catalogue + StandardRolesSeeder (doctor/nurse/reception + new radiologist, rad_technologist) + ClinicPermissionDependencies + GrantClinicalPlatformPermissionsSeeder + bridge migration + routed tests | BE | P1,P3,S1-BE,E1e | self | yes | ✅ PermPlatformRoutesTest 7; bridge ran on dev; labels regenerated | 73e762be0 · 5c8c8f9e(FE) |
| AF3b | ConsultBoardReader photos() private filter; fields into ClinicPatientAttachmentResource | BE | AF3 | self | no | ✅ 23 green | e737588c8 |
| S1-BE | visit_shell / allow_doctor_override / visit_layouts / visit_layout_doctor settings, VisitLayoutController (GET, PUT client, PUT doctor), perms clinic.layout.manage + clinic.fields.private | BE | P0 | self | no | ✅ S1VisitLayoutApiTest 5 green | d0944a478 |
| E1e | Answers store: repeat_index+value_json+source+LogsActivity; private fields (clinic.fields.private) on read+save; computed stamped on save; HistoryQuestion API exposes/accepts v2 columns | BE | E1b-d | self | yes | ✅ 9 + history suites green; + show() private 404, request rules | 2d370635c |
| P1 | (P1-BE ✅ e6e9d85b6 · P1-BE2 ✅ 9c3c408a3 · P1-FE 🔄 2026-10-22) Rx v2: sentence/structured items, clinic_drug_id xor drug_id per pharmacy_source, edit before print, subject=spouse, unified drug search, PDF | BE+FE | P0 | Fable(UX) | yes | ⬜ | |
| S1 | Visit shell: card catalog + resolveLayout (default→client→doctor→context) + layout editor + flow for general + sign/finish, shared pick-don't-type pickers, behind clinic.visit_shell | FE(+BE settings) | P0,D0,E1 | **Fable** | no | ✅ FE built + deployed main-O7PJGYWX.js (BE d0944a478); Fable review ✅ "ship after fixes" (scratchpad/fable-review/REVIEW.md: 3×P0 debug copy/dup favourites/orphan kbd, 5×P1 chrome/tags/hosted panels/phone/tablet); fix pass ✅ FE 086d37ee (deployed main-VOK3Q7VD.js, I18N 20261022plat2; S1b FE + P5 documents card in shell); S1b ✅ BE f4cd1661c (encounter_findings + exam_note + complaint lookup_id; routes wired; Encounter::complaints withPivot; complaint sync now assertEditable; S1bEncounterFindingsTest 7 + ComplaintCatalog + VisitHistory = 21 green; dev migrated 280000–280002) · FE files (exam/complaint card, visit-data.service, i18n) commit with the fix pass | BE d0944a478 · FE a20910a2 |
| D1 | clinical_observations store + migration of vitals + dual-write + prefill height + trend + specialty measures | BE+FE | D0 | self | yes | ✅ 208 green; dev: 24 vitals defs (seeder never ran for existing installs → fixed + create-only + updater list), 9 readings imported | BE 6a4fec27b · FE 97c08367 |
| D2 | (D2a ✅ f8860b8da: D2aFactsTest 21 + pack/nutrition fixes; dev migrated 170000–170010 (2 alerts, 16 alert lookups, 11 condition + 4 alert questions); D2b 🔄 agent 2026-10-22) patient_alerts, chronic conditions table, home meds (kind=home), shared pregnancy/smoking/marital, clinical_notes(+private), audit, stamp at sign; unified header | BE+FE | D1,P1 | Fable(header) | yes | ⬜ | |
| C1 | clinical_episodes, clinical_procedures(+mode), follow_up_tasks, ClinicReferral ext, ClinicalSummaryService, PatientRecordService, timeline card | BE+FE | E1,D2 | self | yes | ⬜ | |
| G1 | GYN profile pack: husband, alerts, history, menstrual, prev pregnancies + G/P/A/L header, categories, team, first-visit step, clinic summary, max lab grid | BE+FE | C1,S1 | **Fable** | yes | ⬜ | |
| G2 | GYN core modules (fibroid FIGO, AUB, endo, adeno, polyp, PCOS, pelvic pain, adnexal RMI, onco+MDT, cervical, vulval) + summaries | BE+FE | G1 | Fable | yes | ⬜ | |
| SEC2 | access_audit, audit on all clinic models, admin≠medical, patient data scope, upload/download/export perms, de-identified export | BE+FE | C1,G1 | self | yes | ⬜ | |
| SEC3 | Encrypt national id/phone/address/private notes with searchable blind index; encrypted off-server backup + restore drill | BE | SEC2 | architect | yes | ⬜ | |
| G3 | Fertility: assessment, semen WHO 2021, prior ART, OI/IUI/IVF/FET cycles, diag lap, husband as linked patient | BE+FE | G2 | Fable | yes | ⬜ | |
| P5 | (✅ BE 1ad99125d + integration 46118cb62 (perms clinic.documents.*, settings print.engine/sick_leave_max_days, sequence names, bridge 290000 ran on dev; P5PermissionsTest 4) · FE 086d37ee; reported: P5ClinicalDocumentsTest 19 + P5TemplateRenderer 10 + P1/P3 = 62 green; routes wired; dev migrated 200000/200002 (5 templates); perms/settings/sequences integration agent 🔄; decision: keep clinic.clinical-templates.view|manage names) Documents: sick leave, medical report, certificate, discharge summary, UDS report — templates, serial, PDF | BE+FE | P0 | self | yes | ⬜ | |
| G4 | GYN operations on clinical_procedures + Clavien, discharge meds, auto follow-ups, op summary, centre/hospital mode | BE+FE | C1,P5 | Fable | yes | ⬜ | |
| D3 | patient_intakes, shared+specialty intake steps, incomplete badge, periodic confirm | BE+FE | D2 | Fable | yes | ⬜ | |
| G5 | Obstetrics: pregnancies, antenatal from observations, high-risk, VTE score+alert, labour/delivery/CS/postpartum, expected births report | BE+FE | G1,D1 | Fable | yes | ⬜ | |
| S2 | Nutrition board + dental workspace as card layouts (defaults identical to today) | FE | S1 | Fable | no | ⬜ | |
| P2 | (P2a agent ✅ reported: 46+18 tests green; Fable [FIN] review ✅ APPROVE WITH FIXES (scratchpad/fin-review/P2a.md: flag default mismatch made the new path untested, flag-off drift of linked rows, dose-time default re-resolution, PRN idempotency, dose→issue link for undo, dose unit = base unit, discharge shadow, slot validation) → fix pass 🔄 (decisions: default false, PRN 15-min guard, legacy path also decoupled); was open: flag hospital.mar_on_prescriptions default true breaks current free-text nursing panel until P2b → orchestrator leaning default false; routes nursing.items.administer/stop + 2 setting rows to wire; P2b must save via admissions/{a}/med-orders; P2b after) Inpatient meds on prescription kind=inpatient, dose billing + stock issue, discharge Rx | BE+FE | P1 | self | yes | ⬜ | |
| S3 | Inpatient context in the shell: MAR, nursing rounds (NEWS2), discharge | FE | P2,S1 | Fable | no | ⬜ | |
| P3 | ExecuteCatalogItem single executor, reception "external lab" mode, full rad lifecycle + cancel/refund/coverage, inpatient orders, rad roles | BE+FE | P0 | self | yes | ✅ 17 new + 243 related green; routes/events wired by orchestrator | BE da48132da · FE da0d2933 |
| G6 | Urogyn: LUTS/SUI/OAB+bladder diary, exam, POP-Q staging, UDS report, voiding, fistula, mesh, PROMs | BE+FE | G2,D1,P5 | Fable | yes | ⬜ | |
| P4 | (agent ✅ reported: 184 passed; BLOCKER found+fixed by orchestrator: ClinicClaimCoverage::adjudicatedShares overwrote split-line shares → now sums (42 claim/accrual tests green); Fable [FIN] review ✅ APPROVE WITH FIXES (scratchpad/fin-review/P4.md: package weight column, NPHIES items per claim line, cancelled package unit, backfill cost, part identity, negative allocate) → fix pass 🔄; steps 5+7 deferred to after P5/C1b) Results without visit, patient lab history, rad report template+images+PDF, claim codes | BE+FE | P3 | self | yes | ⬜ | |
| G7 | Sexual health (private perm), FSFI/FSDS-R, couple summary w/o private, de-identified research export | BE+FE | G2,SEC2 | Fable | yes | ⬜ | |
| D4 | Nursing rounds on observations, InBody, hospital dx single table, optional triage | BE+FE | D1 | self | yes | ⬜ | |
| P6 | (P6a ✅ 914a343e4: 18 tests + Rx regression 44 green; dev migrated 250000/250001; orchestrator added Prescription::isEditable() false once dispensing started; pending: POS perms pos.pharmacy.view/dispense + clinic.prescriptions.dispense + pharmacist preset, flip pharmacy.* is_implemented (+POSComingSoon counts 39→35); P6b FE 🔄 agent) POS pharmacy pending-Rx worklist, sale marks dispensed | BE+FE | P3,P1 | self | yes | ⬜ | |

★ = needed for the GYN client: P0 ✅, SEC1 (1✅ 2✅ 3⬜), D0 ✅, E1 (a–d ✅, e⬜), S1, P1, D1, D2, C1, G1, G2, SEC2, SEC3.

## DAG / parallel waves
- **Wave 1:** E1e (BE: history answers/questions files) ∥ P1-BE (BE: prescription files — disjoint) ∥ S1 (FE + Fable design) ∥ AUDIT (read-only).
- **Wave 2:** D1 (BE vitals/observations) ∥ P1-FE ∥ SEC1-3.
- **Wave 3:** D2 → C1 → G1 → G2 (serial, BE+FE), SEC2 ∥ P5 ∥ P3.
- **Wave 4:** SEC3, G3–G7, S2, S3, P2, P4, P6, D3, D4.

## Decisions log
- 2026-10-22 Briefs written for P2a/b, P4, P6a/b, D4.1–4, S2a–c, S3 (25 code facts pinned, e.g. hospital frequency codes bid/tid/qid/hs ≠ bd/tds/qds/qhs; pharmacy.* settings are is_implemented=false; DropLab/RadReport listeners still skip no-encounter; GYN FE key 'gyn' vs BE 'gyn_ob'). Fixed VisitLayoutController dropping cards[].props/tabs (edd49ac68). Order constraints: D4.1 never concurrent with P2a (NursingService); S2a after the Fable fix pass on visit-shell; P2b/P6b after their BE.
- 2026-10-22 [FIN] review gate: P2a and P4 get a Fable design review of their money/stock/claim changes before commit.
- 2026-10-22 Fixed the shared pre-push hook (BE e31d3fb4c, FE 97c08367): `grep -q` under pipefail SIGPIPE'd and refused pushes that DID carry a bullet.
- 2026-10-22 /app deployed main-O7PJGYWX.js (S1, P1-FE/FE2, SEC1-3 FE, P3 FE, D1 FE). clinic.visit_shell stays OFF; the shell is reachable directly at /app/clinic/encounter/{id}/shell.
- 2026-10-22 Rad acquire route accepts clinic.rad-studies.update OR clinic.rad-reports.enter (no one loses access); reception gets clinic.rad-orders.cancel (handles the refund).
- 2026-10-22 Briefs written for D2a–c, C1a–c, G1a–b, G2a–b (10 sub-WPs, order D2a→…→G2b), SEC2, SEC3, P5, D3; planner running for P2, P4, P6, D4, S2, S3. Brief-level decisions: new Modules/Gyn module; lmp visit-scope prefill 35d; GYN options English term in both value_ar/value_en; writes to feature-off GYN groups → 422; D2a fixes lookup_key fields failing select validation; SEC3 opt-in per install (MOON_PII_ENCRYPTION), exact-match search on encrypted phone/national id; SEC2 admin-medical strip is an owner-run command on existing installs.
- 2026-10-22 ar-php needs ext-calendar only for Hijri dates; client PHP 8.3 lacks it but shaping doesn't use it and composer platform-check is off.
- 2026-10-22 main fast-forwarded to 2d370635c (E1 complete, D0 effective, AF1–3, P1-BE) via `git push origin hazemdev3:main` — no checkout while agents edit the tree.
- 2026-10-22 Arabic in server PDFs: DomPDF can't shape Arabic (LIS reports already only switch labels). Fix ONCE in the shared print engine (P5 / design.md §4.6) with `khaled.alshamaa/ar-php` utf8Glyphs shaping for every clinical PDF (prescription, rad report, documents, LIS), not per document.
- 2026-10-22 Permission grants for existing installs/roles (StandardRolesSeeder doctor/nurse/reception, ClinicPermissionDependencies, Grant…Seeder + bridge migration) are batched into one WP PERM after P3 and SEC1-3 report their permissions.
- 2026-10-22 A dev `migrate` during AF2 also applied in-flight migrations of P1 (120000/120001), SEC1-3 (150000), P3 (160000/160001); checksums saved in scratchpad/applied-migrations.sha1 and the agents told to add NEW files for further schema changes. Compare checksums before committing their WPs.
- 2026-10-22 H2: NO global Sanctum expiry (it cuts long-lived service tokens incl. the LIS bridge 'static token' mode, which pastes an ordinary login token). Interactive logins get per-token expires_at from `sanctum.interactive_expiration` (env SANCTUM_TOKEN_EXPIRATION), default 0 = non-expiring. SEC1-3 adds dedicated non-expiring service tokens; after that the default can become 14 days.
- 2026-10-22 Locked-encounter HTTP code stays 422 (EncounterLockedException); design.md's 409 to be aligned in docs.
- 2026-10-22 Deciding a requested intent AFTER signing stays allowed (reception completes the signed doctor's request); only a CANCELLED encounter refuses.
- 2026-10-22 SEC1-3 MFA needs a TOTP library; preferred `pragmarx/google2fa` (battle-tested) over hand-rolled crypto. Requires composer require (network) — attempt in Wave 2; if composer can't fetch, fall back to a minimal RFC 6238 implementation with test vectors from the RFC and record it here.
- 2026-10-22 Lookup favourites use forceDelete on un-favourite (BaseModel soft-deletes + unique index would otherwise block re-favouriting).
- 2026-10-22 show_if empty `any` fails open (shown), matching the FE prototype engine.

## Audit findings 2026-10-22 (all assigned)
H1/H2/M1/M2/SEC1-lows → AF1 · H3/M3/M4/pack-overwrite → AF2 · M5 attachments → AF3 · M5 routes 13 + frequency map + frequency_code → P1 · enum label translations → AF1 (after P1 lands, lang/clinic.php) · 422 vs 409 for locked: keep 422 (EncounterLockedException already 422 everywhere; design doc to be aligned) · HistoryQuestion resource/requests v2 columns → E1e · module Tests ns registered in prod by module-autoload: acceptable (harmless PSR-4 map), noted.

## Deferrals
- SEC1-3: enrolment for require_2fa_roles is a redirect + banner, not a hard guard (needs core/guards/auth.guard.ts) — default policy is [] so nobody is affected yet.
- SEC1-3: User model could use an `encrypted` cast for the 2FA columns instead of service-side encryption (columns are $hidden now).
- SEC1-3: new login/me contract (two_factor_required/challenge, security block) must be adopted by the mobile app.
- SEC1: once service tokens are in use, flip sanctum.interactive_expiration default to 14 days.
- 2026-10-22 Wave 3 dispatched: D2b, C1a, SEC2 (BE) ∥ S2a, P6b (FE) ∥ P4 FIN fix pass ∥ P2a Fable FIN review. Decisions: keep P3 template perm names clinic.clinical-templates.*; owner holds clinic.documents.backdate (owner = all), admin gets documents print+void; hospital.mar_on_prescriptions definition default FALSE until P2b ships (code fallback still true — align in the P2a fix pass).
- 2026-10-22 P2a ✅ 87a5efdd7 after Fable FIN fixes (P2InpatientMedsTest 25 + Hospital/Rx regression 50 green). Dev: 230000 failed silently on the first run in a loop, so 230002 no-op'd; re-ran 230000 then 230002 (migrations row deleted + re-run; idempotent) → 2 orders linked, 1 inpatient Rx, 2 charging rows. Hospital setting definitions seeded (mar_on_prescriptions false). P2b FE 🔄.
- 2026-10-22 P4 ✅ 674a7bb31 after Fable FIN fixes (P4 20 + P4 NPHIES items 3 + claim/accrual suites green). Decision: NPHIES submit 422s a claim with a line that has no code at all (was: silently dropped) — codes refreshed from catalog at submit. Dev migrated 240000–240002 (2 visit-less documents backfilled). Deferred: P4 step 5 (rad images in the P5 PDF) and step 7 (record section, after C1b).
- 2026-10-22 P6b FE done (uncommitted, waits for P2b/S2a to finish so the FE tree builds clean); P6 BE integration agent 🔄 (perms + pharmacist preset + settings flip + held-order link + session keys + qty cap).
- 2026-10-22 D2b ✅ b5b8418ea (D2bHeaderSnapshot 14 + summary/facts/encounter 57 green; MySQL smoke: patient 20006 header shows penicillin allergy + anticoagulation + diabetes; 20003 note + Augmentin). Decision: header still reads the legacy free-text `allergies` answer (derived alerts, deduped) because text answers never create alert rows — revisit in D3. Gap: ClinicProfilePacks dental chronic/allergy flags carry no storage/meta → fix in D3. D2c FE 🔄 (Opus + one Fable consult on header).
- 2026-10-22 S2a FE + P6b FE committed 4f3edfe8 (not deployed yet — deploy after P2b/D2c build clean). S2a: nutrition shell needs `PUT clinic/visit-layout/client {clinical_type:'nutrition', features:{shell:true}}` + visit_shell on; e2e identity harness written, NOT run (needs E2E creds + a nutrition encounter; capture classic baselines before S2b). BE tab/props validation ef1d0f968. Saves stay locked for non-general types (S2 Decision 7).
- 2026-10-22 C1a ✅ 14889ec2e (C1aEntities 12 + neighbours 64 green; dev migrated 300000–300005 + Hospital 300010; 19 team lookups; unique index swapped on MySQL). Decision: global scope on PatientHistoryAnswer hides record-scoped answers from patient/encounter readers (recordScoped() opts out). Gaps: Operation.php fillable clinical_template_id (G4); PatientRecordService + extend() registry is C1b. Perms/setting clinic.procedures.mode → integration agent.
- 2026-10-22 P2b ✅ FE 854f1ffb + BE 7693c314d (MAR flag in chart payload; drugs/search also for hospital.nursing.record). Gaps (deferred): PATCH prescription-items/{item}/charging; form/dosage_form_id on Hospital order; issue_unit_id UI. Fable not consulted for the MAR dialog.
- 2026-10-22 /app deployed main-GQIWLGJR.js from a clean worktree of FE ce66713c (I18N 20261022plat3): S2a, P6b, P2b live (all behind flags/settings).
- 2026-10-22 SEC2 reported (22+6 tests). Dev migrated 310000/310001 (middleware was already live in the tree, fails open). Routes + media AND-permissions wired (uncommitted) — attachment tests need the media keys in the catalogue → commit with the integration pass (P6 + C1a + SEC2 perms, admin≠medical on fresh installs, schedules).
- 2026-10-22 D2c ✅ FE b5d70794 (+ SEC2 FE screens) + BE 90e1b35fa (addenda author, header id). Classic consultation header now passes encounterId. Deployed main-WKY4V4EC.js (I18N 20261022plat4). Gaps (deferred): alert origin clinic/department; snapshot doesn't stamp specialty slot (GA-at-sign) → G5; patient-file page doesn't refresh after quick-add / cards not mounted there; lookup inline-add needs clinic.history.manage.
- 2026-10-22 Process: SEC3 twice left the shared tree unbootable (command registered before class; MySQL-only collation in a migration broke SQLite) → all suites failed with 0 assertions; told the agent to keep every save bootable. Lesson for briefs: "write new files first, wire last; migrations must run on SQLite".
- 2026-10-22 Wave 4 running: C1b, SEC3 (architect review first), D4, integration (P6 + C1a + SEC2 perms/settings/schedules).
- 2026-10-22 D4 ✅ 61fe19c5b (D4 tests 70 + Hospital 70 + Nutrition 129 + observations/queue 114 green per agent; orchestrator re-ran D4/Admission/D1 36 green). Dev migrated 350000–350005 (1 round linked; 0 admitting dx — no admission has diagnosis text). Orchestrator added: ACVPU C in ClinicObservationDefinitionSeeder, AdmissionController::update syncs admitting dx, triage route (uncommitted, goes with C1b/SEC2 routes). Risk noted: ObservationService::encounterSetId() puts clinic vitals-panel saves into the newest non-device set → on an admission encounter that is the latest nursing round (doctor edit changes the round) — fix in S3. Known pre-existing failure: AppointmentTest queue-index-excludes-done vs QueueController ISS-2026-9102.
- 2026-10-22 C1b reported (C1bSummaryRecord 7 + neighbours 83). Routes + RouteMap audit entries wired (uncommitted). Waits for the integration pass (perms incl. clinic.summary.generate, summary sequence name).
- 2026-10-22 Wave 5 dispatched: G1a (BE), C1c (FE).
- 2026-10-22 Integration (P6 + C1a + SEC2 + D4 perms/settings/schedules) done by agent; orchestrator removed clinic.prescriptions.dispense from admin (prereq clinic.prescriptions.view is medical) in RolePermissionSeeder + POS bridge. 77 tests green. Dev: bridges 320000/320001 ran; Core/Clinic/Hospital setting definitions seeded (pharmacy.* unlocked, triage, procedures.mode, vitals_on_observations).
- 2026-10-22 SEC3 review (scratchpad/fin-review/SEC3.md): FIX FIRST — H1 bidx unique → 1062 on normalization twins (encryption OFF), H2 missing bidx columns → every LIS patient form 500, H3 manifest + per-file prune deletes newest remote dump; M1 redaction when off; M2 recovery kit over HTTP. Fix pass 🔄 (same agent). Dev: ran 340000 immediately because SEC3 code is live in the tree (H2 would 500 dev patient forms). 340001/340002 held.
- Commit plan: one commit for SEC2 + C1b + integration + SEC3 after the SEC3 fixes (shared files PatientController / ClinicExportController / providers can't be split cleanly).
- 2026-10-22 C1c ✅ FE 4826f8ee + BE gaps 15d7a6aff (episode_id on EncounterResource, procedures ?encounter_id, operations catalog readable with clinic.procedures.edit). Deployed main-YOBJDGUW.js (I18N plat5). Gaps deferred: team-referral fields on encounters/{id}/referrals resource (card uses record API); hospital surgeries list for clinic doctors in center/hospital mode; screen-catalog.generated.ts needs regenerating for follow-ups/due + team/caseload; timeline type labels for G3/G5.
- 2026-10-22 ✅ 41e7570c4 combined commit: SEC2 + C1b + SEC3 (after independent review FIX FIRST → H1–H3/M1–M2 fixed) + integration (P6/C1a/SEC2/D4 perms, settings, schedules). 194/195 in the combined sweep; the 1 failure (C1b private-field) did not reproduce alone or in 4 orderings — likely G1a mid-edit of HistoryService in the shared tree. Dev: 340000/340001/340002 migrated, sec3:pii-reindex --missing-only → 20006 rows indexed, 0 conflicts. FE dcadeeca (SEC3 screens) deployed main-MVEXYW4D.js (I18N plat6).
- 2026-10-22 main fast-forwarded to hazemdev3 on both repos (BE 41e7570c4, FE dcadeeca). G1a / D3 / S3 still uncommitted in the tree.
- Deferred from SEC3: SnapshotEncounterHistory raw select copies ciphertext of private answers when encryption is ON (G1a is editing that file now — fix after); DbDumper splitStatements backslash bug + whole-dump-in-memory (MoonStack updater); plaintext copies outside lab_patients (business_partners/loyalty/sms/NPHIES logs); restore drill not yet run on MySQL (needs an empty moonui3_restore_drill DB + DB_RESTORE_DRILL_DATABASE).
- 2026-10-22 G1a ✅ 971a4c749 (Gyn tests 22 + regression 195 per agent; orchestrator: perms gyn.* into the catalogue with admin excluded via adminMedicalPermissions(), GrantGynPermissionsSeeder on the installer list, labels regenerated after adding ROLES words gyn/file/obhx/sexual to FE i18n (FE commit pending with the next FE batch)). Dev: 360000/360001/360010/360020 migrated; `gyn:install-pack --company=1` → 146 fields, 557 lookups, 20 complaints (dev has no gyn_ob department, so 360010 skipped). Re-run of the earlier C1b flake set: 99/99 green (flake was G1a mid-edit). Unverified: MoonStack packaging of the new Gyn module; Gyn show_if hook ≈3 queries per context build in every clinic (perf follow-up).
- 2026-10-22 Wave 6: G1b (FE, + Fable design review) ∥ G2a (BE). D3 + S3 still running.
- 2026-10-22 D3 ✅ BE 56e85d560 (part of D3's files had already landed inside 41e7570c4 — they were untracked when the combined commit was built) + FE 59e94608. Decision: clinic.intake.enabled default FALSE (on = every existing patient missing allergies/conditions/meds shows «ملف ناقص»; 15 of 26 on dev). Permission clinic.intake.skip (doctor/nurse; anchor clinic.encounters.sign) + bridge 370002. Dev migrated 370000–370002 (26 intakes, 15 pending), setting definitions seeded. Gaps: packs need in_intake/fill_role (0 on dev) → split stations would lock 49/66 fields to doctor; header makes 2 intake GETs.
- 2026-10-22 S3 ✅ FE 59e94608 + BE fixes in 56e85d560 (encounterSetId excludes nursing-round sets; admissions/{id} readable by clinical/nursing record). Nursing tab pixel-identical (harness, mocked API). Redirect of inpatient/day-case to the shell only when visit_shell is on. Gap: no triage fields on EncounterResource/appointment payload.
- 2026-10-22 /app deployed main-V537OT33.js (I18N plat7). G1b (FE) + G2a (BE) running.
- 2026-10-22 G2a ✅ 0cfa28869 (G2a 19 + Gyn/regression 106 per agent; orchestrator re-ran Gyn + C1a/Af2/C1b 68 green). Orchestrator added TeamLookupSeed (Clinic/Support) + installer call — companies created after C1a had no `team` lookups → MDT action 422. Dev: 380000 migrated; gyn:install-pack --company=1 → +123 fields, +372 lookups. Decision: gyn.answered_modules ignores derived answers (Pap mirror no longer forces the cervical line).
- 2026-10-22 G3a (fertility BE, brief written by the agent first) dispatched; GYN BE WPs run one at a time (shared Modules/Gyn files). G2b waits for G1b (both GYN FE).
- 2026-10-22 G1b ✅ FE df64e0e6 (+ BE 448118cf6: shared show_if vectors Pest test 52/52 + complaint resource code). Fable review REVIEW-GYN.md: 4 P0 + 13 P1 applied. TS show_if engine 54/54 vs the PHP reference. Deployed main-NKZLBH2L.js (I18N plat8). To test GYN on dev: create a department of type «نسا وتوليد», turn on clinic.visit_shell, book a visit there (company 1 has the GYN pack: 275 questions). Gaps: FE show_if context lacks episode categories + condition codes (G5 vte); rx subject (spouse) not supported by PrescriptionComponent; schema cached per session; nested picker over the obhx dialog unverified.
- 2026-10-22 G2b (FE, + Fable review) dispatched; G3a BE running.
- 2026-10-22 G3a ✅ 094eed591 (G3a 16 + Gyn 57 + regression; orchestrator: gyn.cycles.view/.manage into GYN_PERMISSIONS (admin excluded), dependency manage → view + clinic.history.record, ROLES word «cycles», labels; 116 green). Brief tasks/G3-fertility.md written. Decision: treatment cycles = clinical_episodes kind=treatment_cycle + record-scoped answers (NO treatment_cycles / cycle_monitoring tables) → design-gyn-integration.md §2 and G1 decision 2 are stale (update KB). Dev: 390000–390002 migrated, install-pack +169 fields. Gaps: write guard can't see the target record (OI/IVF fields could land on a non-cycle episode); fertility/couple summary types not hidden by the feature switch (Clinic availableTypes ignores features).
- 2026-10-22 G4a (operations BE, writes its brief first) dispatched.
- 2026-10-22 S2c (dental as cards; the brief's S2c — the brief's S2b "nutrition board split into 14 cards" NOT started: needs the screenshot harness with E2E creds first) ✅ FE 12ec01de; changelog db96e8d3a. Deviations: dent_alerts kept in default; shared diagnosis/rx carry the shell head; rails hidden on both tabs; dent_fmx/dent_plan not shipped.
- 2026-10-22 G2b ✅ FE d59df5ab (+ changelog). Vectors 28/28 computed + 54 show_if. Fable P0-1 + all P1 applied; P0-2 (team card not refreshing after a banner/MDT referral) closed by the orchestrator: VisitShellBus 'team' event → teamTick → team card refreshToken. Deployed main-LYBNAUXS.js (I18N plat10). Gaps: TeamReferralResource has no team label; summary heads use the full C1b preview (1.5 s debounce) — a per-module summary read would be cheaper.
- 2026-10-22 G3b (fertility FE + Fable review) dispatched; G4a BE running.
- 2026-10-22 G4a ✅ 00d7baff8 (G4a 11 + Gyn/regression 116 per agent; orchestrator re-ran 86 green). Brief tasks/G4-gyn-operations.md. Orchestrator: gyn_nurse/gyn_sonographer roles get clinic.procedures.view. Dev: 400000 migrated, install-pack +105 fields, 57 hospital_operations rows (gyn_ob). Incident: dev BE fatal for a few minutes (static render() clash in OperationTemplate) — fixed by the agent. Open: discharge preset drug lines are the agent's clinical defaults → doctor to confirm.
- 2026-10-22 G5a (obstetrics BE, writes its brief) dispatched; G3b FE running; G4b FE after G3b.
- 2026-10-22 G3b ✅ FE cf5a4443 (vectors G2a 28 + G3a 32 + show_if 54; Fable 2 P0 + P1 applied). Deployed main-FYJYXS5E.js (I18N plat11). BE gaps (deferred to a GYN cleanup pass): cycle close validates outcome via GynSchema::codesOf but outcomes are lookup-backed (clinic-added outcomes can't close); attachEncounter silently re-homes a visit attached to another episode (EncounterResource now has episode_id — FE could warn); spouse endpoints not feature-gated, no gender check.
- 2026-10-22 G4b (operations FE + Fable) dispatched; G5a BE running.
- 2026-10-22 G5a ✅ 58e2a780b (G5a 13 + Gyn/regression 156 per agent; orchestrator: gyn.pregnancy.view/.manage + dependency + ROLES words pregnancy/births + labels; re-run 131 green). Brief tasks/G5-obstetrics.md. Dev: 410000/410001 migrated, install-pack +188 fields, 4 observation definitions, 2 delivery catalog rows. Decision: pregnancy = episode (design-gyn §2 pregnancies/antenatal_visits tables stale). Perf follow-ups: header VTE lookup per visit (N queries); show_if hook +2–4 queries on gyn_ob; every new encounter in any clinic +1 query (pregnancy check). Doctor to confirm: antenatal schedule offsets, VTE thresholds. Rh sign mismatch (U+2212 vs ASCII '-') in GynComputed::patientRh.
- 2026-10-22 G6a (urogyn BE, writes its brief) dispatched; G4b FE running; G5b FE after G4b.
- 2026-10-22 G4b ✅ FE dae05a6d (+ changelog). Fable P0 + 10 P1 applied. Deployed main-IZF63HJ5.js (I18N plat12). Notes: saved GYN layouts (client/doctor) don't pick up new default cards (only required ones re-insert) → add «العمليات» from the catalog or migrate settings; gyn_followup overlaps the shared followup card (owner to decide); P1 composer has no prefill input (G4b fills via public API) → add a proper prefill input later.
- 2026-10-22 G5b (obstetrics FE + Fable) dispatched; G6a BE running.
- 2026-10-22 G6a ✅ f1a655da2 (G6a 12 + Gyn 93 + regression per agent; orchestrator re-ran Gyn + P5 112 green). Brief tasks/G6-urogyn.md. Dev: 420000 migrated, install-pack +234 fields + 34 PROM questions. Decisions: POP-Q points = answers + stage computed (deviates from design-gyn §2 / decision 19 — owner to confirm); no gyn.urogyn.* / gyn.uds.sign permissions (P5 clinic.documents.issue signs the UDS report); urogyn follow-up schedule 6 w/3/6/12 m = code defaults for the doctor to confirm; PROM item wording paraphrased (licensed instruments).
- 2026-10-22 G7a (sexual health + research export BE, writes its brief) dispatched; G5b FE running; G6b FE after G5b.
- 2026-10-22 G5b ✅ FE cf923bab (+ changelog). Vectors G5a 56/56 (+ G2a 28, G3a 32, show_if 54). Fable 2 P0 + 12 P1 applied. Deployed main-U4X6GMAV.js (I18N plat13). BE gap (GYN cleanup pass): no write path for fetal measurements (FHR/FH/EFW/centile/AFI/CL) — UpdateVitalsRequest whitelist 422s them; delivery read model drops repeat rows; expected-births doctor filter not exposed. Unverified: UTC visitDate vs company date near midnight; performed_at via browser clock.
- 2026-10-22 G6b (urogyn FE + Fable) dispatched; G7a BE running. Queued: GYN cleanup pass (fetal measurements write path, cycle close lookup outcomes, attachEncounter re-home guard, spouse gender/feature gate, Rh sign, header/perf follow-ups) → then Phase C (final review sweep, per-module suites, KB/RESUME).
- 2026-10-22 G7a ✅ 676d4dce6 (G7a 19 + Gyn 112 + Sec2/Sec3/C1b/E1e 65 per agent; orchestrator re-ran 141 green; RouteMap audits api.gyn.sexual.show). Brief tasks/G7-sexual-health-research.md. Dev: 430000 migrated, install-pack +106 fields, 32 private score items. Owner decision pending: give gyn_consultant/gyn_doctor clinic.export.deidentified? (not granted). PRIVACY GAPS found (Clinic): ClinicExportController de-identified + include_private leaks private textarea/red-flag codes without gyn.sexual.view; EncounterHistory/PatientProfileField/PatientRecord/Snapshot readers check only clinic.fields.private → GYN cleanup + privacy pass 🔄 (read-guard hook, export fix, fetal-measurement write path, G3b gaps, Rh sign, delivery babies, VTE perf).
- 2026-10-22 G6b ✅ FE c3f60505 (+ changelog). Vectors G6a 80/80 (all sets green). Fable 2 P0 + 10 P1 applied (shared form fixes: raw repeat keys hidden, row titles translated). Deployed main-NQUX3MVG.js (I18N plat14). Left for owner: a few English UDS section heads.
- 2026-10-22 G7b (sexual-health + research FE, + Fable with privacy focus) dispatched; GYN cleanup + privacy BE pass running.
- 2026-10-22 GYN cleanup + privacy pass ✅ a77650fcf (Gfix 14 + Gyn 126 + Clinic readers 137 + others 104 per agent; orchestrator re-ran 252 + Gfix 14 green). Decision: antenatal observations writable by nurses too (clinic.vitals.record, per G5 decision 13). FieldReadGuard hides sexual-health from non-gyn.sexual.view readers everywhere; de-identified export blanks textarea + drops strict codes. Remaining risks: de-identified export still emits structured value_json (tables/repeat) that could hold free text; HistoryQuestionController shows private field definitions (labels) to clinic.fields.private holders; old Rh '-' rows until next save.
- 2026-10-22 Phase C started: final cross-WP review sweep (read-only) 🔄; G7b FE running (also wires fetal cells, Rh, attach force, delivery rows).
- 2026-10-22 Phase C final sweep (scratchpad/fin-review/FINAL-SWEEP.md): WARNING — HIGH: ~37 patient GET routes not in the SEC2 RouteMap (no data scope / no audit: all api.gyn reads + several Clinic reads); 6 data backfills not non-fatal (170006, 230002, 350004, 370001, 140001, 110001). MEDIUM: code-less admitting dx becomes primary → NPHIES 422 / insured sign block / claim primary NULL; mariadb driver in 130000/300005; 100003 not re-runnable. Clean: permissions all catalogued, boot guards, money/stock seams (ward vs POS kinds disjoint), migration ordering/index names, private readers. → final fix pass 🔄.
- 2026-10-22 G7b ✅ FE 7d4fcb59 (+ changelog). Vectors all sets green (G7a 26/26). Fable 2 P0 + P1 applied (honest private-content copy). Orchestrator: route /clinic/reports/gyn-research-export + nav item, amber «الملخص فيه محتوى خاص» note in the summary card while include-private is on, I18N plat15. Deployed main-2N33QCGS.js. Not done: CardDef.priv dark styling for standalone private catalog cards (shared visit-card) — deferred.
- 2026-10-22 Final sweep fixes ✅ b96fd40a5 (Fin tests 15 + Sec2 + Gyn + D4 = 170 green). RouteMap covers every patient-data GET under the audit middleware (+ guard test); backfills non-fatal; principal diagnosis fix; mariadb; 100003 re-runnable; attach 422 code. Left unmapped (owner policy): Hospital admissions.bill / rs.menu / surgeries.show, nutrition shopping-list.
- 2026-10-22 ✅ PLAN COMPLETE on hazemdev3; main fast-forwarded (BE b96fd40a5, FE 7d4fcb59); /app main-2N33QCGS.js. End state + open decisions in RESUME.md.
