# GYN form customize — LEDGER

- Date: 2026-11-10 · Branch `hazemdev3` (BE `/home/moonui3/moon-erp-be`, FE `/home/moonui3/public_html/moon-erp`)
- Source plan (owner-approved «ابدأ» 2026-11-10): https://moonui3.elbaset.com/his-analysis/gyn-form-customize-plan.html
- Owner acceptance: on moonui3 `/app/clinic/encounter/<id>/shell?page=visit` (GYN), a manager turns on «تخصيص», hides ANY element (tab, card, section, field, single option, table column/row, button, header line, summary), makes fields required (final save refuses empty), switches multi-option fields chips⇄dropdown (search, add-if-missing, ★), resizes fields; inputs are sized to their data; every field has a small ⓘ (ar/en by UI language; formula for computed); layouts save as named templates, one main, export/import JSON between installs.

## Decisions (do not re-litigate)
- D1 Scope company-wide (existing `clinic.visit_layouts[gyn_ob]`), no per-branch level.
- D2 Every visible element in every GYN form is hideable. Hidden field = also hidden in print/summary; stored value kept.
- D3 Required enforced only on final save/sign; draft autosave unaffected; hidden-by-condition fields never required.
- D4 Doctor may override only `input` and `size` (when not locked); everything else is the manager's (`clinic.layout.manage`).
- D5 Descriptions AI-written ar/en from schema + code, flagged `desc_review: true`.
- D6 Templates keyed by field/element CODES (never ids) for export/import; unknown codes ignored and reported.

## Shared contract (all WPs)
Client profile `clinic.visit_layouts[gyn_ob]` (existing):
- `fields[<gyn question code>]` = `{visible?, required?, input?: 'chips'|'select', size?: 's'|'m'|'l'|'f', hidden_options?: string[] (option codes), locked?}`
- `elements[<key>]` = `{on: bool, locked?}` — any non-field element. Key grammar `gyn.<kind>.<scope>.<id>` with kind ∈ `sec|tab|card|col|row|btn|hdr|sum|el`, chars `[a-z0-9_.:-]`, ≤120. Missing = on.
Doctor profile: `fields[code] = {input?, size?}`.
Schema meta (WP5): `meta.desc_ar`, `meta.desc_en`, `meta.formula_ar`, `meta.formula_en`, `meta.desc_review`.

## WPs
| WP | Scope | Repo | Depends | Review | Migration? | Status | Commits |
|----|-------|------|---------|--------|-----------|--------|---------|
| WP1 | Rule contract on BE: gyn codes accept input chips/select, size, hidden_options; doctor size; `gyn.*` element keys accepted for gyn_ob; tests | BE | — | Codex | no | ✅ done — Codex skipped (self-review of diff); new test 4/4 + layout tests 23/23 pass | dd910564f |
| WP2 | FE core: customize mode in GynModuleForm (field eye/*/widget/size/options, section eye), rules honoured in render, size-to-data, generic hide directive for any element, applied across GYN cards/tabs/headers/buttons | FE | WP1 | Codex + Fable(UI) | — | ✅ done (see notes) | |
| WP3 | Required enforced on final save/sign for GYN forms | FE(+BE if sign validates) | WP2 | Codex | no | ✅ FE d47d5115 | |
| WP4 | Unified dropdown: search + add-if-missing + ★ for inline-option fields too | BE+FE | WP2 | Codex | maybe | ✅ BE 8776a4fc3 FE d47d5115 | |
| WP5 | ⓘ info icon + AI bilingual descriptions/formulas for all GYN fields in schema JSON | BE data + FE | WP2 | Codex + spot medical check | no | ✅ data 4ea39274f FE d47d5115 | |
| WP6 | Templates: table, CRUD, set main, export/import JSON, FE UI | BE+FE | WP1 | Codex + advisor | yes | ✅ BE 871b25582 FE 088ae7db | |
| WP7 | Custom renderers (OB-history, pregnancy/delivery/antenatal grids, POP-Q, PROM, UDS, spouse, op header): hide every element/column, required, ⓘ | FE | WP2 | Codex | — | ✅ FE 088ae7db | |

## DAG
WP1 → WP2 → (WP3, WP4, WP5, WP7 serial on FE) ; WP6 after WP1, BE part may run beside FE WPs. One writer per repo at a time.

## Baseline
Owner override 2026-09-07: suites not run during implementation. FE `ng build` green at start (main-2JFAIFVG deploy 2026-11-10).

## Deferrals
(none)

WP1 notes: doctor locked-field differs → 422 (existing input semantics kept); doctor cannot set gyn.* elements (D4).

WP5 BE data done 4ea39274f: Modules/Gyn/database/data/gyn_field_help.json (1154 desc ar/en, 42 formulas, AI-written, review=true), served as `help` {desc_ar, desc_en, formula_ar?, formula_en?, review} on every GET gyn/schema field definition. Test GynFieldHelpTest 3/3. FE ⓘ icon pending (after WP2).

WP6 BE done 871b25582: table clinic_layout_templates (migrated on dev), /api/clinic/layout-templates (GET list main-first | POST {clinical_type,name,description?,from_current?,payload?} → {data,skipped} | PUT | DELETE soft | POST {id}/apply → client profile, sole main | GET {id}/export {format:'moon.layout-template',version:1,…} | POST import file|json → {data,skipped}). is_main = last applied. Tests: layout suite 27/27 incl. GynLayoutTemplatesTest 4/4. FE dialog pending (after WP2).

WP2 done b86c8adf: GynCustomizeService (shell-provided), *gynHide directive + GynEyeComponent (features/gyn/customize/), per-field strip (👁 * widget size ☰options), section 👁, 8-col grid (s=1 m=2 l=4 f=full), keys gyn.sec.<module>.<slug> (EN title slug), gyn.tab.first.*, gyn.tab.gyn_cat_page.*, gyn.card.mod.<module>, gyn.sum.mod.<module>, gyn.hdr/btn/card.<module>.*. Entry «🧩 تخصيص الفورم» in gear. ng build green, deployed /app. Not browser-tested. Known gaps → WP7: custom renderers internals, BE gyn_summary/print hide (D2), complaint slot forces duration hidden, *gynHide on ng-container dims first element only.

WP2 review (code-reviewer, read-only): no critical; 10 findings (key length/collisions/title-based section slug, all-tabs-off fallback, stale formMode, last option hide, inline styles, required in hidden section, doctor save elements). Forwarded to the WP3-5 agent to fix in the same pass; #8 (shared host keys) accepted by design.

WP3/WP4/WP5-FE done — BE 8776a4fc3 (POST clinic/history-questions/{id}/options {label} → option; favourites type history_answer_option; schema options carry id; GynInlineOptionAddTest 4/4), FE d47d5115 (missingRequired on sign via GynCustomizeService; app-gyn-option-picker everywhere with search/★/＋; ⓘ tooltip with formula). WP2 review fixes folded in: section key now = first field code (title fallback), key caps, dedupe, empty-state for all-tabs-off, formMode reset, last-option guard, CSS classes. Deployed /app. Gaps: required checked only on mounted forms (unopened tab not enforced); PROM/hint fields no ⓘ; obhx/table-cell selects no ★/＋ (WP7).

WP6 FE + WP7 done FE 088ae7db: «📚 القوالب» dialog (save current, apply=main w/ confirm, rename, delete, export, import + skipped list); keys on obhx (col/btn/hdr/el), table columns gyn.col.<field>.<col>, antenatal, POP-Q points, PROM parts, pregnancy, cycle, delivery, operations, UDS, spouse, discharge, followup, urogyn; ⓘ/*/rules in their own dialogs; pure gyn-required.ts checks unopened category modules. Deployed. Gaps → WP8: hidden fields in print + BE gyn_summary (D2); core modules (profile, menstrual, complaint, exam, imaging) unchecked when off-screen.
| WP8 | D2 on BE: hidden fields/sections out of GYN print + gyn_summary; required for off-screen core modules | BE+FE | WP7 | review | no | ✅ uncommitted (see notes) | |

WP8 done (uncommitted, not deployed): BE contract Clinic `Contracts/OutputVisibility` + `OutputVisibilityAccess` (hiddenFor/hides), Gyn `Support/GynVisibility` (bound in GynServiceProvider; FE key scheme ported: sections, gyn.tab.first.profile|spouse|menstrual|obhx, gyn.card.mod.*, gyn.tab.gyn_cat_page.*, repeat children, PROM items). Applied in ClinicalSummaryService (moduleValues + whole-module skip → preview, saved summary doc, UDS/operation docs built from sections) and DocumentPrefill::uds. ClinicalPrintData visit_summary prints no GYN answers (no change). Test GynVisibilityTest 4/4. FE gyn-core-required.ts: off-screen required for profile/menstrual/complaint/exam/imaging with jump (first-visit part / imaging test tab / shell jump); a core module whose host card is off the layout is skipped. CHANGELOG 3 bullets. Gaps: ObhxTemplate + record templates reading their own tables ignore per-column hides; some templates print «?» for a hidden value; hidden_options not applied to print.

WP8 done BE 048e96459 / FE f66c3eb4: GynVisibility (Modules/Gyn/app/Support) behind OutputVisibility contract in Clinic; summary preview, saved summary docs, UDS/operation docs and UDS prefill drop hidden fields/sections/modules; FE gyn-core-required.ts covers profile/menstrual/complaint/exam/imaging off-screen. CHANGELOG 3 bullets. Gaps: table-based doc templates (obhx rows, pregnancy, procedures) ignore per-field/column hides; some templates print «?» for a hidden value; single-option hide not in print; old saved docs frozen; UDS prefill untested.
Phase C: module suites Gyn + Clinic running.

Phase C (2026-11-10): Gyn module 138/138 pass. Clinic module 1860 pass / 11 fail — all 11 outside this feature by inspection (roles presets now include screen.* perms, appointment queue count, HRM dept projection, service category 422, settings seeder count 15≠14, route-map coverage for purchase-history + nutrition lab-test-history, package freeze/doctor-share/split counts); none touch visit-layout, history options, favourites or summaries. Pushed hazemdev3 (not merged to main).
