# م2 — الإعدادات والصلاحيات المؤسِّسة — CANONICAL SPEC (extracted from KB, read-only)

Sources read in full:
- `/home/moonui/public_html/knowledge-base/topics/clinic-service-settings.md` (canonical settings schema, §§Part 1B)
- `/home/moonui/public_html/knowledge-base/topics/clinic-principles.md` (owner's binding principles)
- `/home/moonui/public_html/knowledge-base/topics/clinic-execution-phases.md` (م2 row + phase section — THE binding 12-phase plan)
- `/home/moonui/public_html/knowledge-base/topics/clinic-tightening-plan.md` (skimmed — older phase-numbering plan, permission-gap findings)
- `/home/moonui/public_html/knowledge-base/topics/clinic-test-scenarios.md` (skimmed — uses an OLDER phase numbering, see ⚠️ Numbering caveat at bottom)

---

## ⚠️ CRITICAL CAVEAT — phase-numbering collision across KB files

`clinic-execution-phases.md` is explicitly the **binding** 12-phase sequential plan (م0→م11), with م2 = "الإعدادات والصلاحيات المؤسِّسة" (Settings & Founding Permissions).

However, `clinic-service-settings.md` §2 and `clinic-tightening-plan.md` tag individual settings/features with phase numbers from an **older/different numbering scheme** (their own local plan, e.g. م5=Cashier, م9=reports/roles) that does **not** match the current binding numbering (where م8=Cashier, م2=Settings). `clinic-test-scenarios.md` also uses this older scheme (its م2 = Queue, its م3 = Consultation — NOT settings).

**Treat `clinic-execution-phases.md`'s م2 section (lines 64-68) as the authority for what's IN SCOPE for م2 today.** Any "(م5)"/"(م9)"/"(L4)"/"(L5)" phase tags quoted below from `clinic-service-settings.md` are **that document's own internal roadmap tags, not the binding phase numbers** — they indicate "this setting's full activation/consumption happens later," not "this setting is out of scope for م2." Flag this to Fable if scope boundaries are unclear during SDD.

---

## 1) SETTINGS MATRIX — 6 groups (per `clinic-service-settings.md` §2 "المستهدف — مخطط الإعدادات الشامل")

**Mechanism (already built, no FE code needed for new keys):** `Modules/Core/app/Services/SettingsService.php::get(key, companyId, branch?, user?)` — fallback chain (user+branch → user → branch → company → definition default → null), 5-min company cache, cast by `value_type`, `set()` validates against `allowed_values`. FE `settings/clinic-settings.component.ts` is 100% dynamic — reads `SettingService.list('clinic')`, groups by `display_group`, renders field type from key pattern (boolean→toggle, `*_account_id`→account picker, enum→select, integer/decimal→number, else text), saves only the diff. **New client = new row in `SettingDefinitionSeeder` → appears in screen automatically, no FE code.** (clinic-service-settings.md L136, L151, L166)

**Owner's governing principle for the whole matrix:** «الإعدادات definitions-driven بمجموعات ... عميل جديد = يظبط إعداداته فيشتغل النظام على وضعه بلا كود» (clinic-principles.md L56).

### Existing today (4 definitions, already live) — `SettingDefinitionSeeder.php:1775`, group tag "Clinic (HIS)"

| Key | Default | Type | Group | Read in | KB cite |
|---|---|---|---|---|---|
| `clinic.ar_account_id` | null | integer (account) | clinic_accounting | `PostReceiptJournalEntry:24`, `RefundServiceOrderLine:107`, `ApplyAdjudicationToLedger:68` | clinic-service-settings.md L142 |
| `clinic.revenue_account_id` | null | integer (account) | clinic_accounting | `PostReceiptJournalEntry:25`, `RefundServiceOrderLine:108` | L143 |
| `clinic.allow_overbooking` | true | boolean | clinic_general | `BookAppointment:73`, `MarkArrived:58` | L144 |
| `clinic.ordering_mode` | `intent` | enum(`intent`\|`immediate`) | clinic_general | `Support/OrderingMode.php:21/30` — forces 409 on direct execution when `intent` (`LabOrderController:29`, `RadOrderController:70`) | L145 |

### Read but UNDEFINED today (silent fallback, invisible in UI — a gap the settings screen must close)

| Key | Fallback value | Read in | KB cite |
|---|---|---|---|
| `his.mode` (`single_clinic`\|`center`) | `?? SINGLE_CLINIC` | `DoctorScheduleSlotRequest.php:58` — forces room requirement in `center` mode. Enum = `Enums/ClinicMode.php` (a PHP const-class, not a real enum). **No `SettingDefinition` row exists → always resolves single_clinic, no UI toggle.** | L148 |
| `clinic.dashboard_top_services_count` | `?? 5` | `ClinicDashboardService.php:142` | L149 |

### Target scheme — 6 groups (owner-approved shape; ≈15 new settings total across all groups per KB's own count, L166)

**💰 مالية (Financial — GL + fail-fast):**
| Item | Status | Notes / Principle |
|---|---|---|
| `clinic.ar_account_id` | ✓ exists | — |
| `clinic.revenue_account_id` | ✓ exists | — |
| Refund/credit-note account | 🆕 planned, key name TBD | tagged "م5" in that doc's own numbering = cashier/refund phase |
| Cashier over/short variance account | 🆕 planned, key name TBD | tagged "م5/م9" |
| **Fail-fast policy** | 🆕 validation rule, not a data key | «لا قيد بحساب null» — owner: financial settings must reject empty required GL accounts at save-time, not fail silently downstream. This is the literal م2 owner test scenario (see §3). |

**🏗️ أوضاع البيع (Sales modes) — home of the "إعداد أساسي" principle:**
| Item | Status | Notes / Principle |
|---|---|---|
| `clinic.ordering_mode` (`intent`\|`immediate`) | ✓ exists | — |
| `clinic.lab_mode` (`integrated`\|`standalone`) | 🆕 planned — **«الإعداد الأساسي» بأمر المالك** | «المعمل متفعل ولا لأ» — THE foundational switch: integrated → reception executes via LIS flow; standalone → clinic becomes catalog owner, doctor orders from clinic_services type=lab, results enter via the external-result (L3) mechanism (owner: "قيمة رقمية / صورة / PDF... خطوة اختيارية"). Full consumption lands later (م4/م7 per binding plan) but the SETTING ITSELF (and its persistence + read-back) is م2 scope. (clinic-service-settings.md L37, L160; clinic-principles.md L46) |
| `clinic.rad_mode` (`integrated`\|`standalone`) | 🆕 planned — same "إعداد أساسي" status as lab_mode | Identical mechanics for radiology (L39, L160) |
| `clinic.pharmacy_source` (`products`\|`standalone_formulary`) | 🆕 planned | Owner: purchasing/dispensing is ALWAYS a separate operation from the doctor's screen, in both sub-modes (clinic-principles.md L29-32) |
| `his.mode` (`single_clinic`\|`center`) | 🆕 needs promotion from silent fallback to a real `SettingDefinition` row | Currently invisible/unconfigurable; listed both under "needs promotion in م1" (L148 area) and inside this م2 target scheme (L160) — ambiguous which phase actually ships the promotion; flag to Fable. |

**📅 تشغيل (Operations):**
| Item | Status | Notes / Principle |
|---|---|---|
| `clinic.allow_overbooking` | ✓ exists | — |
| `clinic.scheduling_mode` (`slots`\|`open`) | 🆕 planned | Owner: «عيادات كتير مش بتشتغل بجداول الكشف — بتحجز أي عدد في نفس المعاد» → `slots` = capacity-based (+ `allow_overbooking` toggle already exists) vs `open` = free booking, no slot check, queue orders by arrival. (clinic-principles.md L75-76 — explicit dedicated section "الجدولة اختيارية") |
| `clinic.default_payment_method` (e.g. `cash` default) | 🆕 planned | For the "collect now at visit-add screen" flow — owner: the amount pre-fills to the FULL invoice in cash by default ("الطبيعي الدفع كامل") (clinic-service-settings.md L204-205) |
| `clinic.allow_credit_balance` | 🆕 planned, default **enabled** | Per-client policy toggle: allow patient debt/credit when partial payment is made (L214, explicit: "افتراضي مفعّل") |
| Follow-up window (days) + follow-up price policy (free/discounted) | 🆕 planned, no key name yet | Tagged "م8" in that doc's local numbering (service-settings L162) |
| Daily queue reset | 🆕 planned, no key name yet | Tagged "م2" in that doc's local numbering — **NOTE: this is the OLD numbering's م2 (=Queue phase), likely NOT this binding م2 (=Settings); needs Fable disambiguation** (L162) |
| `clinic.dashboard_top_services_count` | 🆕 needs promotion from silent fallback | Currently `?? 5`, no `SettingDefinition` row (L149, L162) |
| `clinic.visit_stations` | 🆕 planned, exact type/values TBD | Governs whether the 3 visit stations (vitals/history/consultation itself) run separate or combined per client (clinic-principles.md L64-70) |

**🖨️ طباعة (Print) — no code exists today:**
Logo, margins, fonts, "show diagnosis" toggle, per-doctor signature. (clinic-service-settings.md L163)

**💊 روشتة (Prescription) — no code exists today:**
Drug source (`products`\|`standalone` — likely reuses/parallels `clinic.pharmacy_source`), per-drug defaults for dose/frequency/duration/instructions, per-doctor favorites. (L164)

**🩺 حقول إكلينيكية ديناميكية (Dynamic clinical fields):**
A field-definition **engine** (not a simple setting key): bilingual name + type (numeric/text/select) + unit + normal range/**danger thresholds with alerting** + show/hide + sort order, exportable as **presets** seeded to clients. Precedent already built: the `history_questions` engine (WP-14). Nothing exists today for vitals (still hardcoded columns on `clinical_examinations`). (clinic-principles.md L37-39, L161; clinic-service-settings.md L161) — Per `clinic-test-scenarios.md` L318 (old numbering!) the ENGINE build itself lands in a consultation-related phase and only the presets-management SCREEN lands in a settings/roles phase — exact binding-phase mapping is unclear; likely the م2 settings screen just needs a placeholder/stub group here, with the real engine built later (per `clinic-service-settings.md`'s own gap-list this is tagged as a separate WP, not a simple key).

---

## 2) FIVE ROLE PRESETS (owner-named list, `clinic-execution-phases.md` L27/66)

**استقبال (Reception) · تمريض (Nursing) · دكتور مساعد (Assistant doctor) · كاشير (Cashier) · مدير (Manager)**

The KB does **not** give a literal permission-key table for all 5 — only nursing and assistant-doctor have an explicit permission key named. Capabilities below are reconstructed from workflow descriptions scattered across the KB (cited per line) — treat as the best-available synthesis, **not** a KB-verbatim table; the exact permission-key set per role is itself open work for م2 (see §4).

| Preset | What KB explicitly grants | KB cite |
|---|---|---|
| **تمريض (Nursing)** | Station-scoped: **`clinic.vitals.record` ONLY** — a worklist screen of arrived patients where they record vitals; nothing else. | clinic-principles.md L70 ("«محطة القياسات» للتمريض بطابور الواصلين وصلاحية `clinic.vitals.record` فقط"), L85 (test scenario) |
| **دكتور مساعد (Assistant doctor)** | Station-scoped: **`clinic.history.record`** — a worklist screen for entering the complaint/history sheet ahead of the main doctor. | clinic-principles.md L70 ("«محطة الشيت» بصلاحية `clinic.history.record`") |
| **استقبال (Reception)** | Check-in ("وصل" button, gated by permission per L44 of tightening-plan), book appointments, assign doctor when auto-assign yields none, **execute** the doctor's lab/rad/medication orders (intent→execution split — "الاستقبال هو اللي بينفّذ في الحالتين" per clinic-principles.md L27), collect payment at the point of visit-add ("حصّل الآن") OR route to cashier queue ("إرسال للكاشير"). | clinic-principles.md L22-27; clinic-service-settings.md L198-222 (payment design); clinic-tightening-plan.md L44, L56-59 |
| **كاشير (Cashier)** | Mandatory open session to collect; sees the **cashier queue** (items reception routed, showing patient/amount-due/sent-time/sender); completes collection (`CollectReceptionReceipt`), issues real receipts, processes refunds safely (no double-refund), closes session with self-entered counted cash, sees Z-report. | clinic-service-settings.md L216-222; clinic-tightening-plan.md L62-68 |
| **مدير (Manager)** | Implied superset: settings screen access, financial/day-end reports, doctors CRUD, revenue-split/commission configuration, contract/insurance approvals, exports. (Not itemized explicitly as a permission list anywhere in KB — inferred from "إدارة كاملة" description of the end-of-day/reports phase.) | clinic-tightening-plan.md L90 ("صاحب العيادة/المدير آخر اليوم... إدارة كاملة") |

**Cross-cutting م2 requirement (applies to ALL roles, not preset-specific):** «سياسة `*appCan` على أزرار الكتابة كلها» — every write button across the whole clinic module must be gated by an `appCan`-style directive tied to a real permission, closing the gap flagged in م0's audit (10 unguarded routes + zero `*appCan` on write buttons module-wide, per clinic-tightening-plan.md L161). (clinic-execution-phases.md L66)

---

## 3) م2 «تست المالك» — exact acceptance scenario (clinic-execution-phases.md L67, verbatim translation)

Three checks the owner will personally run to approve م2:

1. **«اقلب `lab_mode` لمستقل وشوف أثره (م7 هيفعّله بالكامل)»** — Flip `clinic.lab_mode` to `standalone` in the settings screen and observe its effect. (Full downstream activation is deferred to a later phase — م2 only needs the toggle to exist, persist, and be readable/visibly acknowledged somewhere.)
2. **«جرّب تحفظ إعداد GL فاضي → يرفض»** — Attempt to save a financial (GL account) setting empty/blank → must be explicitly rejected (fail-fast validation before save, not a silent null downstream).
3. **«ادخل بيوزر «تمريض» وشوف حدوده»** — Log in as a "تمريض" (nursing) preset user and observe their boundaries — i.e., confirm they are actually restricted to their permitted scope (vitals-only), proving the role-preset + `*appCan` enforcement work end-to-end.

**Goal statement (م2's «الهدف» line, L65):** «الدنيا ترتب بعضها» — a control panel letting every client configure their operating mode without code.

**Dependency:** م1 (clinic-execution-phases.md L68) — "إعدادات الخدمة بتشاور على أنواعها" (service settings correlate with service types, i.e. م1 must be done first since lab_mode/rad_mode's meaning depends on service_type=lab/radiology existing). Primary reference: `[[clinic-service-settings]]` §مخطط الإعدادات.

---

## 4) Owner decisions: RESOLVED vs still OPEN for م2

### ✅ RESOLVED (owner has already decided; safe to implement directly)
- The 6 settings-group taxonomy itself (💰/🏗️/📅/🖨️/💊/🩺) — fixed shape, not up for debate.
- `lab_mode` / `rad_mode` are explicitly labeled by the owner as **"الإعداد الأساسي"** (the foundational setting) — binary integrated|standalone, drives catalog-picker source, order-creation path, and results-entry mechanism downstream.
- `scheduling_mode = slots|open` — explicit dedicated owner section, fully specified semantics.
- `ordering_mode = intent|immediate` — already implemented and live; no design work needed here.
- Default payment flow: `default_payment_method` defaults to cash, full invoice amount pre-fills by default ("الطبيعي الدفع كامل").
- `allow_credit_balance` — defaults to enabled, explicit owner call.
- The 5 role-preset **names** (استقبال/تمريض/دكتور مساعد/كاشير/مدير) — fixed list, not to be renegotiated.
- Nursing = `clinic.vitals.record` only; Assistant doctor = `clinic.history.record` — these two permission keys are explicit and final.
- The settings mechanism itself (SettingDefinition-seeder-driven, auto-appears in FE, no new FE code per key) is existing, proven infra — just add rows.
- Fail-fast philosophy for financial settings (no silent-null GL posting) — established principle from م0, re-validated as a settings-save-time UX requirement in م2.

### ⏳ STILL OPEN (needs a decision during م2 SDD — escalate to Fable per the mandated workflow)
- **Exact key names + types + defaults** for: refund/credit-note account, cashier over/short variance account, follow-up window (days), follow-up price policy, daily queue reset, `clinic.visit_stations` (exact value shape — boolean per station? enum?) — KB only describes these narratively, no finalized schema row like the existing 4.
- **`his.mode` promotion timing** — ambiguously placed in both "م1" and inside the م2 target scheme in the same source doc; needs disambiguation on whether م2 ships this promotion or it was already done in م1.
- **Print settings group** — zero code exists; only a bullet list of fields (logo/margins/fonts/show-diagnosis/per-doctor-signature), no key names/types decided.
- **Prescription settings group** — zero code exists; only bullet descriptions, no key names/types decided. Also unclear whether `clinic.pharmacy_source` (sales-modes group) and the "drug source" prescription-group item are the SAME setting duplicated across two group listings, or two distinct settings — needs reconciliation.
- **Reception / Cashier / Manager exact permission-key lists** — unlike nursing/assistant-doctor, the KB gives no literal `clinic.xxx.yyy` permission keys for these three; only narrative workflow descriptions. Authoring the concrete permission list per role is open work for م2 itself.
- **Dynamic clinical-fields engine scope for م2** — is it (a) fully out of scope for م2 (built later, م2 just reserves a settings-group placeholder), or (b) partially scoped now? Conflicting phase tags across `clinic-service-settings.md` and `clinic-test-scenarios.md` (which itself uses stale phase numbering) make this ambiguous — flag to Fable before committing scope.
- **Daily queue reset** setting is tagged "م2" in `clinic-service-settings.md`'s own (older, non-binding) numbering scheme, which historically = Queue phase, not Settings phase — likely a false positive for THIS م2's scope; needs explicit exclusion confirmation from Fable.
