cc507f490f
Owners often state rates as a total-by-duration matrix (0-1h=200, 0-3h=500,
0-6h=800, 0-9h=900, 0-12h=1000) that the marginal hourly ladder can't express
(the ladder sums per-increment rates; this is cumulative totals at thresholds).
Add STEPPED as a third pricing mode alongside the ladder and flat.
- @parking/shared: TariffStep {uptoMin, totalMinor} + a `steps[]` field on V1
structures and V2 cards (mutually exclusive with blocks/flatMinor). steppedFee():
smallest tier with uptoMin >= duration wins (INCLUSIVE boundary), the top tier
repeats as a per-day cap; wired into computeFeeV1 + computeFeeV2 (V2 default card
only — a whole-stay total can't be sliced per-increment by a windowed card).
Validation: ascending uptoMin, non-negative totals, no daily-cap-with-steps,
steps-only-on-default. priceSession/quote/booth/Lab price it via the shared core.
- Composer UI: a "By duration (up-to)" mode with an up-to/total table (base card
only). i18n modeStepped/steppedHint/stepUpTo/stepTotal/addStep (sq+en).
- 8 new unit tests incl. the exact owner matrix, multi-day repeat, overstay, and
validation (53 pass). Verified end-to-end via the UI: authored + published the
matrix, Tariff Lab prices it exactly (3h->500, 6h->800, 12h->1000, 2d->2000).
Wiki: tariff (three pricing modes + stepped semantics), log.
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V