fd9885e9ec
Experimenting used to mean publishing — churning the immutable version
history and risking real tickets pricing against a half-baked card while
the admin iterated. The lab is now a true sandbox:
- tariff_drafts table (migration 0021): MUTABLE by design — the one
exception to "editing publishes a version"; a draft prices nothing and
signs nothing. Drafts are validated + tz-stamped on save exactly like a
publish, so a saved draft always simulates and never fails at publish.
- CRUD under /api/tariff/drafts (list tariff:read, mutations
tariff:update); publishing a draft goes through the normal immutable
POST /api/tariff/versions path.
- Lab UI rebuilt: sidebar lists lab drafts AND the full published history
(click any to price against it); main pane cut to pure entry/exit
(ticket loader, payment, category inputs dropped); the composer form is
extracted to TariffEditorForm.tsx and reused in a modal (new drafts
prefill from the active card); per-draft Publish with confirm.
- tariff_versions.name (migration 0022): optional label stamped at
publish — carried from the lab draft, or typed in the composer's new
optional field — so history reads "Winter 2027", not UUID prefixes.
- Includes the composer UI + sq/en labels for the package mode (engine
landed in d9e6c13) and the "Flat price / hour" relabel.
5 new server integration tests (RBAC, roundtrip, validation, tz-stamp +
simulate + publish w/ name); server suite 288 green.
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
15 lines
724 B
SQL
15 lines
724 B
SQL
-- Tariff-lab drafts (2026-07-05). A mutable scratchpad for the lab: the admin composes
|
|
-- experimental rate cards here, simulates them against hypothetical stays, and only
|
|
-- PUBLISHES (normal immutable tariff_versions path) when satisfied. Deliberately mutable —
|
|
-- a draft prices nothing and signs nothing; experimenting through real publishes would
|
|
-- churn permanent versions and risk a wrong card going live. See wiki/concepts/tariff.md.
|
|
CREATE TABLE `tariff_drafts` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`name` text NOT NULL,
|
|
`currency` text NOT NULL,
|
|
`structure` text NOT NULL,
|
|
`created_by` text,
|
|
`created_at` text DEFAULT (current_timestamp) NOT NULL,
|
|
`updated_at` text DEFAULT (current_timestamp) NOT NULL
|
|
);
|