# G5 — GYN obstetrics: the pregnancy (a C1 episode — EDD / GA computed, fills the shared «pregnant» fact), antenatal visits = the pregnancy's encounters + D1 observations (no visits table), high-risk register, VTE score (RCOG GTG 37a) + an alert at the threshold, labour / vaginal delivery / CS on ONE C1 delivery procedure, postpartum reviews + the registry follow-ups, the expected-births report, and their summaries (antenatal · delivery)

Read `_COMMON.md` first. G5 is **two serial WPs**: G5a (BE: install the 8 p3e modules from the committed schema JSON, the pregnancy as a C1 `pregnancy` episode with record-scope fields, the delivery as a C1 procedure with record-scope `labour` / `vd` / `cs` fields, antenatal flowsheet from observations, the 7 obstetric computed keys, VTE alert + high-risk → conditions, antenatal / postpartum follow-up rules, EDD/GA + ongoing pregnancy in the header slot, the 8 summary templates, the expected-births report) → G5b (FE: pregnancy card, antenatal flowsheet, delivery card, postpartum rows, expected-births screen). Like G2–G4, the modules are **definitions in the G1 engine — no table, no component per module**; only the pregnancy card, the flowsheet and the delivery card (C1 entities) get bespoke UI.

**Depends on:** C1a ✅ (`clinical_episodes` kind `pregnancy`, `encounters.episode_id`, record-scope answers `record_type=clinical_episode|clinical_procedure`, `PUT clinic/records/{type}/{id}/fields`, `EpisodeService` open / close / attachEncounter, `ProcedureService` record / update / sign / cancel, `FollowUpService::generate` + `ClinicalTypeRegistry::followupRules`), C1b ✅ (`antenatal` + `delivery` summary types already declared for `gyn_ob`), D1 ✅ (`clinical_observations`, `ObservationService::latestFor`, definitions `gyn_fundal_height`, `gyn_fetal_hr` + core `bp_systolic/bp_diastolic/weight`), D2 ✅ (`PatientAlertService`, `PatientConditionService`, the header specialty slot `PatientHeaderExtensions` — the sign snapshot already stamps it, `SnapshotEncounterHistory::specialty`; the shared `pregnant` visit fact, D2a migration 170005), E1 ✅ (`ComputedRegistry::extend`, show_if grammar incl. `condition`), G1a–G4a ✅ (`Modules/Gyn`, `gyn_schema.json` — the 8 ob modules are already exported, `GynFieldPackSeeder`, `GynModuleValues`, `GynFieldWriteGuard`, `GynFeatures` `obstetrics`, `GynProcedureCatalog`, JS-fixture approach `export-g4a-fixtures.mjs`). G5b needs G5a ✅, G1b ✅, S1 ✅, G4b ✅ (procedure card patterns).

## Spec (read before coding)
- `/home/moonui3/public_html/knowledge-base/plans/gyn-obstetrics-module-src/p3e-schema-ob.js` — **the whole file** (8 modules: pregnancy · highrisk · vte · antenatal · labour · vd · cs · postpartum — sections, fields, options, show_if, `sum`). `Modules/Gyn/database/data/gyn_schema.json` is its committed machine form (`gyn_pregnancy_*` … `gyn_postpartum_*`, `gyn.v.chorion/placenta/liquor/contra` lookups) — do not hand-edit it. Note: `cs.media` is not in the JSON (media = AF3 attachments of the delivery procedure).
- `p4a-engine-calc.js` `CALC.edd / _eddDate / ga / gaAt / gdm / vte / bishop / pph`, `fmtD`, `daysBetween` (lines 4–31); SUM_TYPES `antenatal` = profile, alerts, obhx, pregnancy, highrisk, vte, antenatal, team · `delivery` = profile, obhx, pregnancy, labour, vd, cs, postpartum, discharge.
- `p4c-scenarios.js` scenario 2 «حمل عالي الخطورة (GDM + DVT سابق) → قيصرية» (pregnancy · highrisk · vte · antenatal = the fixture); **no labour / vd / cs / postpartum scenario** — hand-made cases.
- `../design-gyn-integration.md` §2 rows `pregnancies` (→ see decision 1: an episode, not a Gyn table), `antenatal_visits` (removed — encounter + observations), `follow_up_tasks`, Summary generator, صلاحيات `gyn.pregnancy.*`; §3 (`antenatal` = flowsheet card); §4 computed list (`edd, ga, gaAt, gdm, vte, bishop, pph`); §7 decisions 6 (pregnancy fills the shared «pregnant» field derived), 18 (antenatal visit = encounter + observations), G4 (pregnancy schedules «حمل بالخطورة»).
- `../design-data-layers.md` §3 (one answers store; record scope; observations), `../visit-shell-prototype.html` `GYN_SUM` (`antenatal`, `delivery`) and the `ob` tab.
- `../master-plan.md` G5 row (acceptance: **EDD/GA in the header · a follow-up visit shows in the antenatal flowsheet · VTE ≥ 4 raises an alert**).
- `../legacy-obgy-options-analysis.md` — read-only reference (the old antenatal sheet, pick-don't-type option lists). Never connect to the legacy system, never persist its credentials.
- `G1-gyn-foundation.md` decisions 2–8, `G2` 7–8, `G3` 3–4 / 9, `G4` 1–2 / 7 (record-scope modules, one home per value, templates query their entity, follow-ups = `follow_up_tasks`) — binding here too.

## Decisions (do not re-litigate)
1. **A pregnancy IS a C1 episode** — `clinical_episodes` `kind='pregnancy'`, `clinical_type='gyn_ob'`, `ref_type='gyn.pregnancy'`, `categories` = the visit's OB category codes (default `['normal']`, `high_risk` added when risk = High) so every attached visit keeps the ob modules open, `title` «Pregnancy — EDD 12 Mar 2027». **The `pregnancy` module fields are record-scope answers** (`record_type='clinical_episode'`), seeded `scope='record'`, written through the shared `PUT clinic/records/clinical_episode/{id}/fields`. **Deviation from design-gyn §2 / G1 decision 2** (a `pregnancies` Gyn table): C1a gives the entity (status, dates, team, timeline, encounter link) and record scope its fields — **no new table** (G3a precedent). One open pregnancy per patient (422).
2. **EDD / GA are computed, never stored** (record scope has no derived pass; GA changes daily): `GynObstetrics::eddDate` ports `CALC._eddDate` (Early-US → `us_edd`; IVF → `et_date + 266 − (D5 ? 5 : 3)`; else `lmp + 280`), `ga` «W+D w» / «not yet» / «post-dates / delivered?», `gaAt(date)`. Registered as `gyn_edd / gyn_ga / gyn_ga_at` (the Clinic `edd` / `ga` built-ins keep their Naegele / «Ww+Dd» contract). The read model, header, flowsheet and templates compute them.
3. **The shared «pregnant» fact** (D2a core `pregnant`, scope encounter, prefill) is filled `source='derived'` = true on the booking visit, on every visit attached to the open pregnancy and on any clinic's `EncounterStarted` of a patient with an open pregnancy (only when the visit has no answer yet — a typed answer wins); false on the visit that closes it. The header slot carries `pregnancy {episode_id, edd, ga, risk, fetuses, vte}`; `gpal` counts the ongoing pregnancy (`GynComputed::gpal(..., ongoing: 1)`).
4. **Antenatal visits = the pregnancy's encounters** (design-gyn decision 18) — no repeat, no table. `gyn_antenatal_visit` (repeat parent) is not seeded; its children are seeded **flat** (encounter scope, row 0 of the visit) except the values with another home: `date` = the encounter date, `ga` = computed (`gaAt` of the visit date), `bp` / `weight` / `fhr` / `fh` / `efw` / `efw_c` / `afi` / `cl` = **D1 observations** (`bp_systolic`+`bp_diastolic`, `weight`, `gyn_fetal_hr`, `gyn_fundal_height`, + the new Gyn-seeded definitions `gyn_efw`, `gyn_efw_centile`, `gyn_afi`, `gyn_cervical_length`, create-only, never resurrected). The flowsheet read model = every non-cancelled encounter of the episode (oldest first) × its latest observations × its flat antenatal answers; a paper back-entry = an observation set with `encounter_id NULL` dated `observed_at` (D1 allows it) and appears as an unattached row. Attaching a visit completes the open antenatal follow-up task due within ±14 days.
5. **High-risk and VTE stay encounter-scope** (the JSON), `carry_forward='prefill'` (the register / plan is re-confirmed per visit). Their summaries and the read model fall back to **the latest visit of the pregnancy that answered the module**. **VTE**: `gyn_vte` = `CALC.vte` ported (RCOG GTG 37a points, the BMI ≥30/≥40 overlap −1, antenatal / postnatal recommendation, tone bad ≥ 3 / warn 2); stored derived on save (`HistoryService::recomputeDerived`); **its save hook raises / resolves the D2 alert** `kind=custom, code=gyn_vte_high, severity=danger, source=gyn_vte, ref encounter` when the score ≥ **4 antenatal** (master-plan acceptance) / ≥ **2 postnatal** (RCOG postnatal LMWH threshold); a visit that assesses below the threshold resolves it; a visit without VTE answers leaves it. **High-risk → conditions:** the same save hook adds (never resolves — a pregnancy register untick does not cure a chronic condition) the D2 conditions of the `highrisk.maternal` chips that map to a catalog condition (`previous_dvt_pe → dvt_pe`, `thrombophilia`, `aps`, `chronic_hypertension → hypertension`, `diabetes_pre_existing → diabetes`, `epilepsy`, … only codes present in the company `condition` catalog). The hook is the only save-side hook HistoryService offers (no event) — documented.
6. **A delivery IS one C1 clinical procedure** (`clinical_type='gyn_ob'`, `episode_id` = the pregnancy) whose **`labour`, `vd`, `cs` fields are record-scope answers** (`record_type='clinical_procedure'`, seeded `scope='record'`; the `labour.progress` table rows in `value_json`). One home: `gyn_vd_dt` / `gyn_cs_dt` → `performed_at`, `gyn_cs_surgeon` → `surgeon_name` (not seeded; the read model / templates print `performed_at` as `Y-m-d H:i`). `procedure_codes` = the catalog row of the mode (`gyn_cesarean_section` from PROC_LIB; `gyn_vaginal_delivery` / `gyn_instrumental_delivery` added to `GynProcedureCatalog` in code). Mode rules stay C1's. `pph` / `bishop` are computed at read (`gyn_pph`, `gyn_bishop` ported). Deliveries are **excluded from the G4a operation list / operative summary** (a procedure with a delivery code on a pregnancy episode). Sign = snapshot (`anesthesia` ← `cs.anesth` when it fits, `findings` ← CS findings, `complications` ← vd `mat_comp` / cs `injury`, `specimens` ← cs specimens) → `ProcedureService::sign`; then the C1 generic `post_procedure` 7d/1m/3m/6m tasks of that procedure are **cancelled** and the `post_delivery` rule is generated (decision 7); the pregnancy closes `delivered` (decision 8).
7. **Follow-ups** = `follow_up_tasks` through `FollowUpService::generate` with **Gyn-only trigger strings** (`followupRulesFor` filters by string; a `procedure.signed` rule would fire on every TLH): `antenatal_low` (`gyn.pregnancy.booked_low` — 16/25/28/31/34/36/38/40/41 w, NICE), `antenatal_high` (`gyn.pregnancy.booked_high` — 12/16/20/24/28/30/32/34/36/37/38/39 w) anchored at **EDD − 280 d** (the offsets read as gestational weeks; tasks already past at booking are cancelled), `post_delivery` (`gyn.delivery.signed` — 7 d wound / perineum check, 6 w postnatal check) anchored at `performed_at`. `POST pregnancies/{e}/schedule` regenerates after the dating / risk change (open tasks of the other risk rule or a moved date are cancelled). Schedules are code defaults — **doctor to confirm** (design-gyn §7 G4 ⏳).
8. **Pregnancy lifecycle** (`Modules/Gyn/app/Services/PregnancyService.php`, through C1's `EpisodeService`): open/book (`encounter_id?`, dating fields, `conception`, `fetuses`, `risk`, `categories?`) · attach a visit · schedule · close (`outcome` = an obhx outcome code or `transferred` / `lost_to_follow_up`; `create_obhx_row` default true ⇒ an `obstetric_history_rows` row: year, GA weeks at close, outcome, birth weight / sex from the delivery's first baby, mode detail vacuum/forceps, PPH ≥ 500 mL) · cancel (entered in error; record frozen by C1a). **Feature** `gyn.feature.obstetrics` off ⇒ every pregnancy / delivery / report endpoint 422 `gyn_feature_off` and the module fields 422 (existing guard).
9. **Postpartum** stays the JSON (encounter-scope repeat `gyn_postpartum_day`): a ward stay writes one row per day on the admission visit, a clinic review one row on its visit. The template renders the visit's own rows (a closed pregnancy takes no more attached visits — C1 `attachEncounter` needs an open episode).
10. **show_if context** (`GynShowIfContext::values`): the visit's pregnancy (its episode, else the patient's open pregnancy, else one closed ≤ 84 days ago) contributes its record answers (`gyn_pregnancy_*`), the live `gyn_pregnancy_edd/ga/blood_rh`, and its delivery's record answers (`gyn_labour_* / gyn_vd_* / gyn_cs_*` + `gyn_vd_dt` / `gyn_cs_dt` from `performed_at`); `answeredModules` adds `pregnancy` / `labour` / `vd` / `cs` when those records have answers. The BE already unions D2 `condition` codes (VTE module rule `{k: condition, has: dvt_pe}`) — **the FE context lacks both** (G1b gap) — G5b must add them.
11. **Summaries** = `Modules/Gyn/app/Summary/{Pregnancy,Highrisk,Vte,Antenatal,Labour,Vd,Cs,Postpartum}Template.php`, ported **line by line** from the p3e `sum` (English, identical to the JS for the same values). `CALC.gdm` / `CALC.vte` / `CALC.pph` `{t, cls}` render as `.t` (G2a documented deviation). Pregnancy / labour / vd / cs query their entity; highrisk / vte fall back per decision 5; antenatal = the flowsheet rows up to this visit. The `antenatal` / `delivery` types already exist (C1b). `GET pregnancies/{e}/summary` returns the lines without an encounter.
12. **Expected births** `GET reports/expected-births?from=YYYY-MM&to=YYYY-MM&doctor_id=` — open pregnancies of the company (patient data scope through `Patient::query()`), EDD computed in PHP (decision 2), grouped by EDD month: `{months: [{month, count, high_risk, multiple, rows: [{episode_id, patient_id, name, mrn, phone, edd, ga, risk, fetuses, delivery_plan, primary_doctor_id}]}], total}`; default window = this month + 5.
13. **Permissions:** `gyn.pregnancy.view` (list / show / flowsheet / summary / report), `gyn.pregnancy.manage` (open / attach / schedule / close / cancel **and** writing pregnancy fields — `GynFieldWriteGuard`, 403). Delivery = `clinic.procedures.view/edit/sign` (labour / vd / cs fields need `clinic.procedures.edit`, G4a rule). Grants (additive, `GrantGynPermissionsSeeder` + bridge migration): owner all; anchor `clinic.encounters.view` → pregnancy.view; `clinic.encounters.update` → view + manage; `gyn_consultant` / `gyn_doctor` / `gyn_team_member` view + manage; `gyn_nurse` view (+ the nurse records the antenatal observations through D1); `gyn_sonographer` view.

## Shared-file rules
- Orchestrator-owned — REPORT: `Modules/Clinic/routes/api.php`, `RolePermissionSeeder.php` (`GYN_PERMISSIONS` + labels for `gyn.pregnancy.*`), `StandardRolesSeeder.php`, `ClinicPermissionDependencies` (manage → view + `clinic.history.record`), setting seeders, permission-labels, `config/moonstack.php`. You own `Modules/Gyn/routes/api.php`.
- No Clinic file is edited in G5a (the hooks are `ComputedRegistry::extend`, `ShowIfContextBuilder` / `PatientHeaderExtensions`, `ClinicalTypeRegistry::register`, an `EncounterStarted` listener registered by `GynServiceProvider`).
- FE i18n (G5b): targeted keys under `GYN.*` only, ar + en; **no `I18N_VERSION` bump**.

---

## G5a — BE (migrations `2026_11_03_410000`–`410099`, in `Modules/Gyn/database/migrations`)

### Files
- `Modules/Gyn/app/Support/GynSchema.php` (+`G5_MODULES`, `PREGNANCY_MODULES`, `DELIVERY_MODULES`, `DELIVERY_ENTITY_FIELDS`, `ANTENATAL_SKIP`, `FLAT_MODULES`), `GynComputed.php` (+7 keys), `GynShowIfContext.php` (pregnancy / delivery values + answered), `GynFieldWriteGuard.php` (pregnancy permission + delivery entity fields), `GynExtensions.php` (8 templates, follow-up rules, header), `GynProcedureCatalog.php` (2 delivery rows), `Services/GynPackInstaller.php` (default set + observation definitions), `Services/GynOperationService.php` (exclude deliveries), `database/seeders/GynFieldPackSeeder.php` (record scope / flat / skip / prefill), `database/seeders/GrantGynPermissionsSeeder.php`, `Http/Controllers/GynSchemaController.php` (module scope / storage / entity fields), `Providers/GynServiceProvider.php` (EncounterStarted listener), `routes/api.php`, `lang/{ar,en}/gyn.php`.
- New: `Support/GynObstetrics.php` (EDD / GA / gaAt / gdm / vte / bishop / pph ports + RCOG points), `Support/GynObstetricHooks.php` (VTE alert + high-risk conditions save hook), `Services/PregnancyService.php`, `Services/GynDeliveryService.php`, `Services/ExpectedBirthsReport.php`, `Http/Controllers/PregnancyController.php`, `Http/Controllers/GynDeliveryController.php`, `Summary/{Pregnancy,Highrisk,Vte,Antenatal,Labour,Vd,Cs,Postpartum}Template.php`, `database/data/tools/export-g5a-fixtures.mjs` → `tests/Fixtures/g5a_expected.json`.
- Migrations: `410000_install_gyn_obstetrics_modules` (data, pattern 400000: fields + observation definitions + delivery catalog rows on every gyn_ob company), `410001_gyn_obstetrics_permission_bridge` (pattern 390002).

### Interfaces (`api/gyn`, company-scoped, patient data scope through `Patient::query()`)
| Method | Path | Permission | Body / result |
|---|---|---|---|
| GET | `patients/{patient}/pregnancies?status=` | `gyn.pregnancy.view` | read models (newest first) |
| POST | `patients/{patient}/pregnancies` | `gyn.pregnancy.manage` | `{encounter_id?, lmp?, dating?, us_edd?, et_date?, et_day?, conception?, fetuses?, risk?, categories?[]}` → 201 |
| GET | `pregnancies/{episode}` | `gyn.pregnancy.view` | read model |
| PUT | `pregnancies/{episode}/encounter` | `gyn.pregnancy.manage` | `{encounter_id}` attach a visit |
| POST | `pregnancies/{episode}/schedule` | `gyn.pregnancy.manage` | regenerate the antenatal tasks → read model |
| POST | `pregnancies/{episode}/close` | `gyn.pregnancy.manage` | `{outcome, encounter_id?, reason?, create_obhx_row?}` |
| POST | `pregnancies/{episode}/cancel` | `gyn.pregnancy.manage` | `{reason}` |
| GET | `pregnancies/{episode}/visits` | `gyn.pregnancy.view` | the antenatal flowsheet rows |
| GET | `pregnancies/{episode}/summary` | `gyn.pregnancy.view` | `{pregnancy, highrisk, vte, antenatal, labour, vd, cs, postpartum, text}` |
| GET | `pregnancies/{episode}/deliveries` | `clinic.procedures.view` | delivery read models |
| POST | `pregnancies/{episode}/deliveries` | `clinic.procedures.edit` | `{mode: vaginal\|instrumental\|cesarean, encounter_id?, place?, place_name?, hospital_surgery_id?, performed_at?, scheduled_at?, surgeon_id?, surgeon_name?, indication?, fields?{code: value}}` → 201 |
| GET / PUT | `deliveries/{procedure}` | view / edit | read model / header (partial, `mode` switches the catalog row) |
| POST | `deliveries/{procedure}/sign` | `clinic.procedures.sign` | snapshot + sign + post_delivery tasks + pregnancy closed → read model |
| POST | `deliveries/{procedure}/cancel` | `clinic.procedures.edit` | |
| GET | `reports/expected-births?from=&to=&doctor_id=` | `gyn.pregnancy.view` | decision 12 |
Pregnancy read model: `{id, patient_id, status, opened_at, closed_at, outcome, title, categories, encounter_ids, record_type, fields (code ⇒ value), edd, edd_by, ga, ga_days, risk, fetuses, blood_rh, follow_ups[{id, title, due_on, status, rule_key}], visits_count, deliveries[{id, mode, status, performed_at}], vte {score, text, tone, phase, encounter_id}|null, highrisk {maternal[], obstetric[], fetal[], placental[], encounter_id}|null, summary}`. Delivery read model: `{id, episode_id, patient_id, encounter_id, status, mode, place, place_name, performed_at, scheduled_at, surgeon_name, is_signed, editable, record_type, fields, derived {bishop, pph}, babies[], follow_ups, summary {labour, vd, cs}}`. Fields: the shared `GET/PUT api/clinic/records/{clinical_episode|clinical_procedure}/{id}/fields`; observations: the D1 endpoints.

### Tests — `Modules/Gyn/tests/Feature/G5aGynObstetricsTest.php` + `Modules/Gyn/tests/Unit/G5aGynObstetricsComputedTest.php` (prefix `g5a_`)
installer seeds the 8 modules (pregnancy / labour / vd / cs `scope=record`, antenatal flat without the observation / entity codes, postpartum repeat, highrisk + vte prefill) + the 4 observation definitions + 2 delivery catalog rows idempotently; computed vectors = the JS (edd ×3 dating methods, ga / not yet / post-dates, gaAt, gdm, vte antenatal / postnatal / overlap / empty, bishop partial / favourable, pph none / minor / major); book a pregnancy → episode kind pregnancy + record answers + `pregnant` derived on the visit + antenatal tasks anchored at EDD − 280 (low vs high schedule, past ones cancelled) + one open pregnancy only; pregnancy field write through the record endpoint, through the encounter path 422, without `gyn.pregnancy.manage` 403; show_if: antenatal / labour open on a visit of the pregnancy; header specialty `pregnancy.edd/ga` + ongoing G, and the signed snapshot carries it; flowsheet row from a visit's observations + answers (+ an unattached back-entry), attach completes the nearest task; VTE score ≥ 4 raises the alert, a lower assessment resolves it, postnatal ≥ 2; high-risk DVT chip → `dvt_pe` condition; delivery CS record + sign → snapshot, post_procedure tasks cancelled, post_delivery 7 d / 6 w, pregnancy closed delivered + obhx row (live_birth_cs) and G/P/A/L updates; deliveries absent from the operations list; summaries = the JS for scenario 2 + hand-made labour / vd / cs / postpartum cases; the `antenatal` / `delivery` summary types carry the lines; expected-births by month (+ doctor filter, closed excluded); feature off ⇒ 422 + modules hidden. Run also every `Modules/Gyn/tests`, `Af2IsolationTest`, `PlatformD0FieldIsolationTest`, `ClinicProfilePackTest`, `C1aEntitiesTest`, `C1bSummaryRecordTest`, `D1ObservationsTest`, `D2aFactsTest` — keep green.

### Out of scope (G5a)
Any FE; a partogram chart; CTG storage; neonatal patient records (baby as a patient / NICU module); per-procedure follow-up rules inside C1 (`FollowUpService` has no procedure filter — report); editing the Clinic D1 seeder (the 4 new observation codes are Gyn-seeded); obhx «ongoing» auto-row (the header counts the open pregnancy instead); a births statistics dashboard (Robson / CS rate) beyond the expected-births list.

---

## G5b — FE (`src/app/features/gyn/`; no migrations)

Design consult (cheap agent, not Fable — owner rule) on: the pregnancy card (header «EDD 12 Mar 2027 · 28+3 w · High risk · twins DCDA», book / close / outcome), the antenatal flowsheet (one row per visit: date · GA · BP · weight · urine · FHR · FH · presentation · EFW (centile) · AFI · plan; add-row from the current visit's vitals; overdue next-visit chip), the delivery card (mode switch vaginal / instrumental / CS, labour → outcome → the vd or cs sections by show_if, babies rows, sign), the VTE score chip + recommendation, the expected-births screen (month tabs + list).

**G5a hand-off notes:** `GET gyn/schema` reports `pregnancy` `scope=record, storage=episode, record_type=clinical_episode, episode_kind=pregnancy`; `labour/vd/cs` `storage=procedure, record_type=clinical_procedure, entity_fields`; `antenatal` children are flat with `observations` = {k → observation code}. The FE show_if context must add (1) the D2 `condition` codes of the patient, (2) the episode categories, (3) the pregnancy + delivery record values (decision 10) — or read the BE context. `computed.ts` mirrors `edd/ga/gaAt/gdm/vte/bishop/pph` (vectors in `g5a_expected.json`). The antenatal children keep the p3 `rep: 'visit'` in the schema JSON but are seeded flat — render them as one row of the visit (repeat_index 0). `gyn_pregnancy_blood_rh` in the BE context is `+` / `−` (U+2212, the `anti_d` rule's sign). The core `pregnant` fact is written derived only where the company has that D2a definition. Encounters after the delivery cannot be attached to the (closed) pregnancy — the BE still resolves it for 84 days by recency (decision 10).

### Do
1. `gyn-pregnancy-card.component.ts` — the `pregnancy` module card: the patient's pregnancies, «＋ حمل» (book from the visit), the record fields with `gyn-module-form` in record mode (`PUT clinic/records/clinical_episode/{id}/fields`), live EDD / GA, schedule tasks, close with outcome, read-only when closed / cancelled.
2. `gyn-antenatal-flowsheet.component.ts` — `GET pregnancies/{e}/visits`; the current visit's row writes observations through D1 (vitals panel codes + `gyn_fetal_hr`, `gyn_fundal_height`, `gyn_efw`, `gyn_efw_centile`, `gyn_afi`, `gyn_cervical_length`) and the flat antenatal answers through the encounter path.
3. `gyn-delivery-card.component.ts` — deliveries of the pregnancy, «＋ ولادة» (mode), labour / vd / cs fields in record mode (`clinical_procedure`), babies rows, sign (shows the post-delivery tasks).
4. VTE chip + high-risk banner from the read model; the expected-births screen (`GET reports/expected-births`).
5. `computed.ts` (G1b file — extend): the 7 keys identical to PHP for the G5a vectors (`npx tsx` one-off; report).
6. i18n `GYN.PREGNANCY.*`, `GYN.ANTENATAL.*`, `GYN.DELIVERY.*`, `GYN.BIRTHS.*` (ar + en), no version bump. `npx ng build --base-href /app/` green. No deploy.

---

## Report back (each WP)
Files created/edited; installer counts; test output with pass counts; migrations + dev commands; Gyn route lines (Clinic route lines to paste — should be none); permissions/settings needed; CHANGELOG EN/AR; decisions taken; files needed but not touched; any p3e field the JSON lacks or the summary port could not match exactly.
