Two-tier service model the marketplace is priced and searched on. Admin
catalog skeleton (categories + EAV option groups/values, addable as data
not migrations; NULL category = cross-category) and the nurse pricing layer
(nurse_service_variants — the atomic bookable unit: category + one value per
required dimension at the nurse's own IRR price and price unit).
- New `catalog` schema via one additive migration; Price BIGINT (no floats),
on the wire as a string of digits; total = price + unit + session_count.
- Duplicate-listing guard: deterministic option_set_hash + filtered
UNIQUE(nurse_id, service_category_id, option_set_hash) WHERE deleted_at IS
NULL + friendly 409 pre-check. One value per dimension; required groups
(incl. cross-category) enforced; deactivate, never delete.
- Public catalog browse cached behind a CatalogCache generation token,
invalidated on any admin write. IVariantSnapshotSerializer shipped for b8.
- Contract (catalog.md) + handoff + report published; swagger refreshed.
122 tests green; zero new build warnings.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>