# Admin · Settings — Parity Matrix

Canonical: `portals/admin/Settings.tsx` (+ `lib/status.ts`, `lib/theme.ts`, `store/store.ts`, `types.ts`).
Ours: `backend/controllers/SettingsController.php`, `backend/views/settings/*`, `backend/models/Settings.php`.

| Demo behavior | Demo ref | Our ref | Status | Note |
|---|---|---|---|---|
| 3-tab Settings shell (workflow / docs / colors) | Settings.tsx:332-360 | backend/views/settings/_form.php:85-149 | missing | Ours is a single form with Policies/Financial/System cards — no tabs, different sections |
| Page header "Settings" | Settings.tsx:336 | _form.php:69-72 | partial | Ours titled "Website Settings" with a different scope |
| **Booking-workflow editor** (transition chips per FROM status) | Settings.tsx:82-145 | — | missing | No transition table or editor anywhere in backend/common/frontend/api |
| Editable `bookingTransitions` allow-list enforced app-wide | types.ts:540, store.ts:518, lib/status.ts:60 | — | missing | Our booking status changes are not gated by an editable state machine |
| Per-status **Reschedule** capability toggle | Settings.tsx:144-167, lib/status.ts:96 | — | missing | No `rescheduleStatuses` concept |
| **No-show grace (min)** input + enforcement | Settings.tsx:160-167, lib/status.ts:106 | — | missing | No grace setting; no-show not time-gated |
| Reset booking workflow to defaults | Settings.tsx:73-80 | — | missing | — |
| `updateConfig` triggers billing reconcile | store.ts:458-461 | — | missing | No equivalent config-change hook |
| **Policies & documents** listing (name/version/updated/status) | Settings.tsx:182-225 | _form.php:96-110 | partial | Ours uploads files but stores no version/date/published-draft status; no listing table |
| Published vs draft document status badge | Settings.tsx:215-219 | — | missing | No per-document status field |
| Document "View"/download | Settings.tsx:213-220 | _form.php:41-51 ($docLink) | partial | Ours links the current uploaded file; demo is a simulated download |
| Policy upload + notify customers/agents/shops | — (not in demo) | SettingsController.php:104-159 | done (ours-only) | Capability beyond the demo |
| **Color-system** token editor (live theming) | Settings.tsx:262-330, lib/theme.ts:50-90 | — | missing | No theme-token store / color picker; colors fixed in Tailwind config |
| Override / save-default / reset 3-layer color model | Settings.tsx:282-283, store.ts:463-477 | — | missing | — |
| Reset-all colors (disabled when clean) | Settings.tsx:268-291 | — | missing | — |
| Live CSS-var recolor across portals | lib/theme.ts (badgeTint) | — | missing | — |
| Admin-only / global (single config row) scoping | portals/admin; GlobalConfig | SettingsController.php:26-41, 90 (findModel(1)) | done | Both treat settings as platform-wide; ours adds manager permission check |
| RTL-ready layout (logical props) | Settings.tsx:144 | _form.php (Tailwind logical classes) | done | Both use logical properties |
| Financial rates (taxes/commission/deposit) | — (GlobalConfig elsewhere) | _form.php:113-124 | done (ours-only) | Not part of demo Settings screen; belongs to financial-config parity area |
| System flags (distance/unpaid-period/show-agents) | — (not in demo) | _form.php:127-149 | done (ours-only) | Not in demo Settings |
| Row Update action works | n/a | SettingsController.php:268-273 vs index.php:91 | missing | `actionUpdate` throws 404 unconditionally; index pencil link is dead |

## New in demo (absent on our side)
- Admin-editable **booking-workflow state machine** (transitions + reschedule capability + no-show grace), enforced everywhere.
- **Color-system** live-theming editor (token catalogue, override/save-default/reset, runtime CSS vars).
- **Versioned policy documents** with published/draft status (demo lists; we only upload files).
- 3-tab Settings layout and the "Reset to defaults" / "Reset all" affordances.

## Ours, not in demo
- Policy **file upload** + downstream customer/agent/shop **notifications**.
- **Financial** settings (taxes, taxes_type, platform_commission, max_deposit_percent).
- **System** settings (distance_range, not_paid_bookings_period, show_agents).
- Contact/social website fields + settings listing grid (`index.php`).

Area score: 18%

## Verified verdict (adversarial)

Re-read BOTH sides for every "done"/high claim. Findings:

| Demo behavior | Analyst | Verified | Evidence |
|---|---|---|---|
| Admin-only / global single-config scoping | done | **partial** | Edit surface is single-row (`SettingsController.php:90` `findModel(1)`), but `actionIndex` renders `update.php` only for that row while `actionIndex`→`index.php` grid lists ALL `Settings` rows and offers **Create Settings** (`index.php:49-53`, `actionCreate` 192-260) — ours can hold N config rows; demo is strictly one `GlobalConfig`. Permission gate fires only for `manager` role; every other role falls through to `return true` (`SettingsController.php:36-39`) — broader than "admin-only". |
| RTL-ready layout (logical properties) | done | **done (confirmed)** | `_form.php` uses only logical classes (`border-s` ×5, `ps-5`, `me-3`, `file:me-3`); zero physical `ml-/mr-/pl-/pr-/text-left/text-right/left-/right-`. Matches demo `Settings.tsx:131,144` (`ms-auto`, `border-s`, `ps-3`). |
| Row Update action works | missing (defect) | **missing (confirmed defect)** | `index.php:91` pencil → `['update','id'=>...]`; `actionUpdate` (`SettingsController.php:268-273`) throws `NotFoundHttpException()` unconditionally. Dead link. |
| Policies & documents listing (version/updated/status) | partial | **partial (confirmed)** | Demo `Settings.tsx:38-44,182-225` = read-only versioned table (name/version/updated/published-draft). Ours (`_form.php:96-110`, `SettingsController.php:104-159`) uploads files → writes `*_path` + notifies; stores NO version/date/status metadata and renders NO listing table. |
| Booking-workflow editor / reschedule toggle / no-show grace / reset / color system / 3-layer color model | missing | **missing (confirmed)** | No `bookingTransitions` / `rescheduleStatuses` / `noShowGraceMin` / theme-token store anywhere in backend/common/frontend/api. Demo enforces these in `store.ts:458-523` + `lib/status.ts` + `lib/theme.ts`. Our status changes are not gated by an editable state machine. |

### Overclaims downgraded
- **Admin-only / global single-config scoping**: done → **partial**. Ours is not a guaranteed single config (grid + Create allow multiple rows) and the permission check is manager-only, not admin-only.

### Confirmed (no change)
- RTL-ready layout — done (verified clean logical props).
- Row Update — missing/defect (verified dead link + unconditional 404).
- Policies & documents listing — partial (verified no metadata/listing).
- All booking-workflow / color-system / versioned-docs rows — missing (verified absent).

### Adjusted area score
Booking-workflow state machine, color-system live theming, and versioned policy docs (the three substantive demo pillars) are entirely absent; the one "done" interactive claim (scoping) is overclaimed; the index Update action is a live defect. The only genuine matches are RTL and the single-row edit shell. **Adjusted score: 16%** (down from analyst's 18% — the scoping overclaim costs the small credit it was given).
