GET /api/orders returnerar per order frozen advance_action (resolveAction ur lib/order-flow); admin renderar via ActionGate — policy i serverlagret, presentation i klienten (DoD §21). Terminala/okända statusar → read_only med varför-text i stället för missvisande 'klar'. tests/order-flow.test.ts 3/3; full svit 1138 godkända; typecheck grön.
2.3 KiB
ADR-0001 — Server-renderad authz-resolution för orderåtgärder
Status: Accepted
Date: 2026-09-29
Owners: 0pt (simon@siax.io)
Related requirements: DoD §21 (backend enforcement), §78 (error/why-UX), våg 3.6–3.7 (authz-ux/entitlement)
Related capabilities: @siax/contracts/authz-ux 0.10.0, @siax/ui ActionGate 0.11.1
Context
Admin-ordkön behöver gate:a advance-aktionen. 0pt saknar klientsides-policy;
requireOrderOwner är server-side. Att resolvé:a i klienten vore påhittad
policy (DoD §15).
Existing implementations
- PATCH
/api/orders/{id}enforcar ägarskap server-side (sanningsvärdet). - Admin-sidan hämtar ordrar via GET
/api/orders(owner-scopad).
Decision
Server-renderad resolution: GET /api/orders returnerar per order ett
frozen advance_action (ResolvedAction från resolveAction), derivat i
lib/order-flow.ts ur kanoniskt flöde + sessionens ägarskap. Klienten
renderar via ActionGate — ingen policylogik i UI-lagret. Ingen extra
fetch: resolutionen rids med ordningssvaret.
Ownership
0pt äger flödet och resolutionen; DES1GN äger kontraktet (authz-ux) och
renderingen (ActionGate). Product Firewall: 0pt importerar @siax/*, aldrig
tvärtom.
Contract
ResolvedAction {state, reason?} — stängda uppsättningar enligt authz-ux.
Provider boundary
Framtida pay0-entitlement projiceras via deriveEntitlement in i samma
resolve — ingen ny endpoint behövs.
Dependency rules
@siax/ui/@siax/contracts → 0pt. Aldrig reverse.
Migration
Enda konsument: admin-sidan (denna PR). Övriga ytor migreras per aktion.
Alternatives considered
- Klientsides-resolution mot ny endpoint: extra roundtrip, policy-läckage risk, mer kod — avvisad.
- Hårdkodad disabled i UI: duplicerar serverns sanningsvärde — avvisad (DoD §21: backend är enforcement, UI är presentation).
Risks
Flödesändringar måste skriva i lib/order-flow.ts (enda källan) —
lint-/test-täckning finns (tests/order-flow.test.ts).
Testing / Evidence
tests/order-flow.test.ts: available för aktiva steg, read_only för terminala (incl. okända statusar i fri-text-DB) — 3/3.- Full svit 1138+3 godkända; typecheck grön.
Rollback
Ta bort advance_action-fältet + ActionGate-wrappen — klienten faller
tillbaka till tidigare rendering (flödet oförändrat).