3.6 KiB
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 commitd3ec723and 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, neverPOST 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 whilelistrequires 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 resulting409, it does not pre-check. - The variant snapshot is serialised at booking time (
IVariantSnapshotSerializer) onto the booking row — see bookings.md. Editing or deactivating a variant never changes a past booking. set_activeis 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
nameFaandnameEn; the client picks by locale.OptionGroupDtocarries itsvaluesinline, so the variant builder needs one round trip, not one per group. isRequired+sortOrderon 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.