# Visit-shell completion — LEDGER

Started 2026-10-23. Source: the prototype review `his-analysis/visit-shell-prototype-review.html` (132 ✅ · 57 ⚠ · 20 ❌ · 10 📝 + 6 bugs) and its slice tables (scratchpad/proto-review/*.md, copied into this folder as review-*.md).

**Owner request (verbatim):**
- «كمل كل الي ناقص واعمل كل حاجة ومتسبش حاجة واشتغل بتوصياتك كمان اضافه للعناصر عيزه بشكل سهل ميكونش من شاشات تانيه علشان يبقي سهل كمل ومتوقفش الا لما تخلص وممكن تستشير فابل لو عايز»
- «كمان الشق بتاع التصميم تأكد انه مظبوط وخلّي فابل يكون مراجع كل حاجة يبقى شبه التحليل»

**Acceptance (owner):** opening general / GYN / dental / nutrition / inpatient visits on moonui3 /app matches the prototype. Every review row is closed or explicitly decided. Adding/editing catalog values and configuring fields/elements happens in place (picker dialog, «✎ تخصيص الشاشة»).

## Decisions (orchestrator recommendations, adopted per the owner's «اشتغل بتوصياتك»)
1. Insured visit: the diagnosis card is forced (re-inserted, cannot be hidden). Hard block only for no coded primary dx (same rule as the BE).
2. Doctors can add AND manage catalog values in place: new perms `clinic.lookups.add` / `clinic.lookups.manage` for clinical doctor roles; nurse gets add.
3. Clinic vs center: one «نوع المنشأة» selector (`clinic.facility_type`) that sets the 4 existing settings at once; the 4 stay individually editable (custom).
4. GYN multi-selects: JSON stays the source of truth; a link-row mirror table is added for reporting (spec guard b).
5. GYN summary private content: keep the explicit opt-in for `clinic.fields.private` holders (with the amber note). Never in Couple.
6. Settings UX: no separate «Program Setting» screen. Field rules / elements / specialty features / shell switch / doctor override are edited IN the shell's «✎ تخصيص الشاشة» mode (per-card ⚙ + a type panel). `/clinic/settings` keeps the global switches.
7. Inpatient ordering = intent only if the Hospital billing flow already supports it (W1-BE-A investigates).
8. Fable reviews every UI WP against the prototype (owner asked), plus one final whole-design review vs the analysis. P0/P1 applied.
9. Tests: new/changed test files only (no full module suites); `ng build` every FE WP; /app deployed after each FE wave (owner tests live).

## WP table
| WP | Scope | Repo | Wave | Review | Migration | Status | Commits |
|---|---|---|---|---|---|---|---|
| W1-BE-A | insurance shape, lab flags, Rh alert, signer, stay header endpoint, stay bill [FIN read], server flow state, inpatient ordering | BE | 1 | self | yes | ✅ | BE aacaac484 |
| W1-BE-B | general complaint + exam seed, inline-add validation, lookup PATCH/reorder/DELETE, perms add/manage, ICD favourites + chapters | BE | 1 | self | yes | ✅ | BE aacaac484 |
| W1-BE-A2 | [FIN] admission encounters bill to the stay folio (stray ServiceOrder bug found by BE-A) + repair command on dev | BE | 1 | Fable FIN | no | ✅ Fable FIN APPROVE WITH FIXES → fixes applied | BE aacaac484 + f008e9e47 |
| W1-FE-1 | shell bugs B1-B6, GYN inpatient dups, insured dx forced, editor fixes, ctx cards in edit, summaries refresh, route gate, signer | FE | 1 | Fable | — | ✅ (Fable review pending, at wave deploy) | FE 10d02f96 |
| W2-FE-2 | picker everywhere: in-place catalog management in the picker dialog, diagnosis picker (★, chapters), lab/rad chips+button mode, exam rule by code, cache/403 fixes, GYN short lists ★ | FE | 2 | Fable | — | ✅ (Fable review at wave deploy) | FE 0931e8cb · BE in aacaac484 |
| W2-FS-3 | vitals packs (specialty + context) + modes, WHR, GYN antenatal vitals, inpatient RR/AVPU/pain/O2/IO, round I/O inputs | FE+BE | 2 | Fable | maybe | ✅ | FE 5fc82df9 · BE aacaac484 |
| W2-BE-C | layout settings API: client+doctor fields/elements/features, facility type, per-type shell switch definitions, complaint duration/HPI storage, diagnosis text mode storage | BE | 2 | self | maybe | ✅ | BE aacaac484 |
| W2-FE-6 | S2b nutrition board → 14 cards (classic identical), products-sold, dental plan + FMX cards, unlock nutrition/dental saves | FE(+BE small) | 2 | Fable + screenshot diff | — | ✅ (Fable review at wave deploy) | FE 6a79cf67 · BE aacaac484 |
| W3-FE-4 | in-place settings in «تخصيص الشاشة» (per-card ⚙ fields/elements, type panel features/shell/doctor-override, client vs doctor scope) + element consumers (hdr.*, complaint quick/hpi/duration, lab.prev, rx.interact, dx.secondary, dx text mode) + layer colouring + source tags | FE | 3 | Fable (design first) | — | ✅ (Fable review now) | FE 279b10c3 |
| W3-BE-D | multi-select link-row mirror + backfill, nutrition intake codes (goal/goal weight/activity), dental intake dedupe | BE | 3 | self | yes | ✅ | BE aacaac484 |
| W4-FE-5 | inpatient header (attending, LOS) + «حساب الإقامة» card, server flow state, collapsed summaries (history/docs/previous), phone bill/orders, 44px, quick bar pickers, sign+print rx/orders, followup inline, catalog cards results/photos/meds/intake, nutrition inpatient rx | FE | 4 | Fable | — | ✅ (Fable review at wave deploy) | FE 1f7ffdbe |
| W5-FE-7 | Fable live-review fixes (forced-card tag, vitals grid like prototype + summary, one waist store, lis 404, inpatient single entry form, dates, header alerts-only, finish insured line…) | FE | 5 | Fable (final) | — | ✅ | FE 887145ee · BE c5ed456c9 |
| W5-BE-E | BE follow-ups: hidden values render for all, restore clash, mirror freshness (pii-encrypt, direct writers, nightly), facility settings refresh | BE(+tiny FE) | 5 | self | — | ✅ | BE 9fae23849 · FE (next) |
| W6-BE-F | GYN complaints: Arabic labels + «شكاوى النسا» category (pack + data migration), specialty rows first in the picker | BE | 6 | self | yes | ✅ | BE 007409760 · FE with W5-FE-7 commit |
| FIN | Fable whole-design review vs prototype + fix pass, final build/deploy, KB, changelog | all | 5 | Fable | — | 🔄 Fable FINAL verification running | |

## DAG
W1 (BE-A ∥ BE-B ∥ FE-1, disjoint files) → W2 (FE-2 ∥ FS-3 ∥ BE-C ∥ FE-6) → W3 (FE-4 needs BE-C; BE-D) → W4 (FE-5 needs BE-A) → FIN. visit-shell.component.* has one owner per wave (W1 FE-1, W3 FE-4, W4 FE-5; FE-6 asks the orchestrator for the save-unlock line).

## Log
- 2026-10-23 Plan written; dispatched W1-BE-A, W1-BE-B, W1-FE-1, W2-FE-6, W2-FS-3, W3-BE-D (disjoint files) + Fable design consult (design/FABLE-inplace-settings.md). Waiting: W2-BE-C (after BE-A: EncounterResource), W2-FE-2 + W3-FE-4 (after Fable spec + FE-1), W4-FE-5.

## Deferrals
(none yet)
- 2026-10-23 Fable design spec ✅ design/FABLE-inplace-settings.md. Orchestrator decisions on its §6 open items: header elements are stored per clinical type (like every other rule); nurse = add only (no manage); keep facility type as a «second door» in the type panel (needs clinic.settings.manage) besides /clinic/settings; "used" for delete = any answer (JSON + mirror), complaint/finding link or child value — favourites don't count. Decision 7 lock narrowed: only `layout` saves stay locked for types not yet split; rules/features/shell save for every type. Lookup API extras (restore, with_usage, 409) sent to W1-BE-B.

- 2026-10-23 W1-FE-1 ✅ FE 10d02f96 (checks: resolve-layout 34, inpatient ctx 41, dental 16 green; ng build green). Decisions: forced diagnosis for insured applies to EVERY type (BE blocks all types); editing an insured visit saves the dx card into the clinic layout (accepted). Gaps → W3/W4: vitals + diagnosis panels have no `saved` output (pulse/summary). Changelog bullet pending (BE commit).
- 2026-10-23 W1-BE-A ✅ code (W1BeaVisitShellDataTest 12 + FinRouteMap/PatientSummary/D2bHeader 28 green; dev migrated 2026_11_20_100001 shell_state). Endpoints: clinic/encounters/{id}/stay, /stay-bill (read-only, AdmissionReader::row — nights not caught up = lags like the Hospital list; accepted, no writes on read), /shell-state. I9 NOT changed: BE-A found admission encounters order onto a stray empty ServiceOrder (EncounterStarted listener) instead of the Folio stay bill — 7/8 dev admissions → new [FIN] WP W1-BE-A2 (recommended fix: one resolver preferring the folio, listener skip/reuse, repair command). Commits: BE files of several agents interleave (api.php, EncounterResource, Encounter.php) → BE committed per wave, not per agent.- 2026-10-23 W2-FS-3 ✅ FE 5fc82df9 (+ binding/i18n already in 10d02f96) · BE code (W2fs3VitalsPacksTest 15 + Vitals/D1/D4 regression 52 green; dev migrated 330001). Decisions: context pack also for emergency (seeder rule); LMP read-only with «افتح الحمل» link (pregnancy record is the source).
- 2026-10-23 W3-BE-D ✅ code (W3HistoryAnswerValuesTest 5 + W3IntakeProfileFieldsTest 4 + regression 68 green; dev migrated 400001, mirror backfill 133 answers → 226 rows, idempotent). FE follow-up → W4-FE-5 task 13 (intake wizard profile fields). BE follow-up (FIN pass): run the mirror after security:pii-encrypt + nightly schedule; GynObstetricHooks / PregnancyService direct writers don't sync until the command runs.

- 2026-10-23 W1-BE-B ✅ code (W1bCatalogManagementTest 18 + 14 guard files green; ClinicRoleManagementTest 3 = known baseline). Dev: bridge 200001 + seed 200002 (complaint 54 general, exam 61). Path stays /api/clinic/clinical-lookups. Seed specialty NULL = core (GYN/dental also see general values). Nurse add by role name (receptionist grant from a first anchor revoked on dev). BE follow-up (FIN pass): restore doesn't check a sibling label clash.
- 2026-10-23 Deployed /app main-PUYCINYJ.js from a clean worktree of FE HEAD (10d02f96 + 5fc82df9 + I18N 20261023vsc1). W4-FE-5 + W2-FE-2 dispatched.
- 2026-10-23 W1-BE-A2 [FIN] ✅ code (AdmissionFolioOrderTest 8 + 12 Clinic/Hospital regression files green). One resolver EncounterServiceOrder::admissionFolioFor; listener skips admission encounters; Folio::open adopts an empty encounter order; clinic:repair-admission-orders (registered in HospitalServiceProvider). Dev: 7 empty strays (68…81) cancelled, folio totals unchanged. Behaviour: post-discharge orders reopen the closed folio (one bill per stay). Fable FIN review dispatched.
- 2026-10-23 W2-FE-6 ✅ FE 6a79cf67 + BE (Nutrition soldProducts; NutritionProductsSoldTest 5 + NutritionVisitRecordTest = 27 green). Classic «الكشف» 0 px diff (43, 50 × 2 heights); shell «الكشف» 2–6k px with the nut-grid SCSS (shadow edges, page scroll). nut_board removed; nut_actions required. SCSS + nutrition inpatient rx → sent to W4-FE-5; Decision 7 unlock → W3-FE-4. Dental plan/FMX cards NOT done here → add to W3-FE-4. Incident: name-based token revoke killed another agent's token → agents now use unique token names.
- 2026-10-23 W2-BE-C ✅ (W2becVisitLayoutSettingsTest 13 + S1VisitLayout + Backbone = 36 green). Element keys = dotted spec keys; exam field key = region code; center = hospital preset; dev company 1 facility_type=hospital; dev migrated 500001 (hpi, complaint_duration).
- 2026-10-23 BE committed aacaac484 (all BE WPs so far + 6 bilingual CHANGELOG bullets). Orchestrator fixed G1aGynFoundationTest (the new Rh-negative alert legitimately adds a core alerts section between GYN heads → order checked on GYN keys only; 15 green). Dev: 0 pending migrations. W3-FE-4 dispatched (new components first; shell files after FE-5).
- 2026-10-23 Fable review W1 ✅ design/FABLE-review-W1.md: no P0; P1×5 + P2 → W5-FE-7 brief (orchestrator decisions written there).- 2026-10-23 Fable FIN W1-BE-A2 = APPROVE WITH FIXES (design/FABLE-FIN-W1-BE-A2.md): P1-1 re-split always, P1-2 stray definition + --move-lines, P1-3 resolver status, P1-4 Dental ChargeService; P2 billingOrderId short-circuit → fix pass sent to the same agent. CHANGELOG bullet amended (expired contract 422 on insured stays).

- 2026-10-23 W2-FE-2 ✅ FE 0931e8cb (+ BE FavoriteController clinic_drug / DrugPresetController already in aacaac484; W2Fe2FormularyFavoriteTest 3 + Favorite/DrugPreset 14 green). Shared diagnosis panel = classic screen gets the picker too. Shell bindings (lab/rad compact, dx inputMode) → W3-FE-4. Gaps: history picker invisible on dev (no general lookup questions); hidden values show raw codes to non-managers on GYN/history chips (BE sends hidden rows only to managers) → FIN pass.
- 2026-10-23 W4-FE-5 ✅ FE 1f7ffdbe (checks: resolve 34, inpatient 41, dental 16, nutrition 26, w4-catalog 50 green; build green). Note: first-visit intake wizard auto-opens on dev (intake enabled, many pending). Gaps: history line has no positive-answer count; print window may be blocked with print.engine=pdf (footer buttons = fallback); visit-shell.component.ts 1263 lines → refactor in FIN. Shell files handed to W3-FE-4 (+ GYN collapsed defaults).- 2026-10-23 Deploy attempt of FE HEAD (I18N vsc2) failed to build in a clean worktree: visit-layout.model.ts went into 1f7ffdbe with W3-FE-4's in-progress type changes (ClientProfile.elements) while visit-layout.service.ts is still uncommitted → HEAD builds only together with W3-FE-4. /app untouched (main-PUYCINYJ.js). Deploy after W3-FE-4.

- 2026-10-23 W1-BE-A2 fix pass ✅ BE f008e9e47: P1-1..4 + P2-1/2/3/7 (AdmissionFolioOrderTest 12 + Clinic/Hospital/Dental regression green); dev dry-run 0. Documented: post-discharge reopen not on an already-submitted claim; splitForOrder doesn't re-derive unit_price (pre-existing).
- 2026-10-23 W5-BE-E ✅ BE 9fae23849 + FE label-resolve commit (W5beeTidyTest 8 + 8 regression files green). Found a missed mirror writer (GynOperationService::writeDirect). Task 4 needed no change (settings page reloads after save). Follow-up: specific «الاسم موجود» message for a restore clash in the picker undo (FIN).
- 2026-10-23 W3-FE-4 ✅ FE 279b10c3 (w3-settings 47 + all checks green; build green). Decision 7 lifted: layout saves for all 4 types. Gaps: rad.prev has no strip to switch; rx.interact = per-drug alert notes (no interaction engine); history/spec question fields not in the ⚙ (link to /clinic/settings). Deployed /app main-UGLV4HWO.js from a clean worktree of FE HEAD (I18N vsc3). Orchestrator smoke: 34/54/37/43/27 open, no console errors except the known lis/investigations 404 (W5-FE-7). Full Fable review dispatched.
- 2026-10-23 W5-FE-7 dispatched (Fable W1 fixes) in parallel with the Fable FULL review (read-only). FULL review findings → a W6 fix pass.
- 2026-10-23 Fable FULL review ✅ design/FABLE-review-FULL.md: settings layer = the analysis; P0-1 is_insured never sent by the BE (classic + shell treated every visit as cash) → fixed by the orchestrator BE 674c1e134 (+ test; FinPrimaryDiagnosis 7 + EncounterTest 14 green; CHANGELOG amended). P1-1/2/4/5/6 + 13 P2 → added to W5-FE-7 (decision P1-4: question-backed specialty cards get a ⚙ with their question codes; note-only gears link to the type sheet). P1-3 → W6-BE-F.
- 2026-10-23 W6-BE-F ✅ BE 007409760 (W6bfGynComplaintCatalogTest 5 + 5 regression files green; dev migrated 600001: category 2611 + 20 Arabic complaints first on gyn_ob). Orchestrator added: ComplaintController::store also reuses the row matching name_ar (picker sends value_ar → no code-less duplicates) + test (ComplaintCatalogTest 7 green) + CHANGELOG bullet. FE comparator (clinical-picker.model/dialog) commits with W5-FE-7 (same files). Known pre-existing: GYN seedLookup ignores soft-deleted codes (unique index on a pack rerun) → FIN note.
- 2026-10-23 W5-FE-7 ✅ FE 887145ee + BE c5ed456c9 (W5Fe7LabModeAndPregnancyTest 4 + 71 regression green; 6 FE checks green). Decisions: ClinicCatalogMode::labMode() = standalone when the LIS module is disabled (fixes the lis/investigations 404s; settings may still display "integrated"); inpatient vitals recorded as ONE round via «تسجيل الجولة» (POST hospital/admissions/{id}/vitals) — weight/height still autosave; nutrition waist/hip read-only from the latest measurement; antenatal pack gated by pregnancy_open; GYN-only «المدة» hidden in favour of the shared «مدة الشكوى». Orchestrator: GYN pack rerun skips deleted values (BE d3070f8df). Deployed /app main-DEDSDMZY.js (I18N vsc4). Fable FINAL verification dispatched.