create mvp path
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# catalog — service categories, option groups, nurse pricing variants
|
||||
|
||||
> Client seam `client/src/services/catalog/` · `USE_CATALOG_MOCK = false` (**real**) · 14 server ops
|
||||
> Last verified: 2026-07-30 against commit `d3ec723` and swagger.v1.json (2026-07-29).
|
||||
|
||||
An EAV catalogue: admin defines categories and their option groups; each nurse composes **variants** —
|
||||
a category + a chosen set of option values + a price. A variant is what a customer actually books.
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Path | Auth | Verdict |
|
||||
| --- | --- | --- | --- |
|
||||
| GET | `/api/v1/catalog/categories` | **anonymous** | wired · paginated |
|
||||
| GET | `/api/v1/catalog/option_groups` | **anonymous** | wired |
|
||||
| GET | `/api/v1/nurse_variants/list` | `[Authorize]` | wired · paginated |
|
||||
| GET | `/api/v1/nurse_variants/get/{id}` | **anonymous** | wired |
|
||||
| POST | `/api/v1/nurse_variants/create` | `[Authorize]` | wired |
|
||||
| POST | `/api/v1/nurse_variants/update/{id}` | `[Authorize]` | wired |
|
||||
| POST | `/api/v1/nurse_variants/set_active/{id}` | `[Authorize]` | wired |
|
||||
| POST | `/api/v1/admin_catalog/create_category` | admin | **unwired** — no console screen |
|
||||
| POST | `/api/v1/admin_catalog/update_category/{id}` | admin | **unwired** |
|
||||
| POST | `/api/v1/admin_catalog/set_category_active/{id}` | admin | **unwired** |
|
||||
| POST | `/api/v1/admin_catalog/create_option_group` | admin | **unwired** |
|
||||
| POST | `/api/v1/admin_catalog/update_option_group/{id}` | admin | **unwired** |
|
||||
| POST | `/api/v1/admin_catalog/create_option_value` | admin | **unwired** |
|
||||
| POST | `/api/v1/admin_catalog/update_option_value/{id}` | admin | **unwired** |
|
||||
|
||||
No phantoms. The seven `admin_catalog` routes are `DynamicPermission` + `sensitive`; the catalogue is
|
||||
seeded and managed out of band today, so the console has no editor. That is a UI gap, not a contract gap.
|
||||
|
||||
> Mutations are **action-style, not REST**: `POST admin_catalog/create_category`, never
|
||||
> `POST admin/catalog/categories`. The old contract doc calls this out explicitly and it still holds.
|
||||
|
||||
## Shape rules the JSON does not express
|
||||
|
||||
- **`GET nurse_variants/get/{id}` is anonymous** while `list` requires auth. That asymmetry is deliberate —
|
||||
a public nurse profile links to a specific variant.
|
||||
- **A duplicate variant is rejected by `option_set_hash`.** The server hashes the chosen option-value set
|
||||
per (nurse, category) and enforces uniqueness, so a nurse cannot list the same configuration twice at two
|
||||
prices. The client surfaces the resulting `409`, it does not pre-check.
|
||||
- **The variant snapshot is serialised at booking time** (`IVariantSnapshotSerializer`) onto the booking
|
||||
row — see [bookings.md](bookings.md). Editing or deactivating a variant never changes a past booking.
|
||||
- **`set_active` is the only way to retire a variant.** There is no delete; a variant referenced by
|
||||
bookings must remain resolvable.
|
||||
- **Prices are IRR digit strings** outbound. The nurse enters Toman in the UI and the client converts at
|
||||
the input boundary — the wire is always IRR.
|
||||
- Reference names come as **both** `nameFa` and `nameEn`; the client picks by locale. `OptionGroupDto`
|
||||
carries its `values` inline, so the variant builder needs one round trip, not one per group.
|
||||
- `isRequired` + `sortOrder` on an option group drive the builder's validation and layout — the client
|
||||
does not hardcode either.
|
||||
|
||||
## Enums
|
||||
|
||||
| Vocabulary | Values |
|
||||
| --- | --- |
|
||||
| `PriceUnit` | `per_hour` `per_session` `per_half_day` `per_day` `per_24h` |
|
||||
|
||||
`PriceUnit` is a label vocabulary, never a multiplier — the client must not derive a total from it. Display
|
||||
strings are i18n keys, never the code.
|
||||
|
||||
## Open REQs
|
||||
|
||||
None. The variant builder (b7) and the Home category grid (A5) both read the contract as served.
|
||||
Reference in New Issue
Block a user