Files
0pt/docs/adr/ADR-0001-server-rendered-authz.md
T
admin a49bc148fc
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 7s
masterplan-lock / check (push) Successful in 8s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
CI (SIAX Cloud) / security (pull_request) Successful in 20s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / quality (push) Failing after 1m31s
CI (SIAX Cloud) / quality (pull_request) Failing after 1m33s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m34s
feat(admin): authz-pilot — server-renderad advance-resolution + ActionGate (ADR-0001)
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.
2026-09-29 12:21:02 +02:00

2.3 KiB
Raw Blame History

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).