mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-03 02:13:31 +00:00
61 lines
2.6 KiB
Markdown
61 lines
2.6 KiB
Markdown
# ADR 0001: Work-order media uses single-org scope (board-aligned)
|
|
|
|
## Status
|
|
|
|
**Superseded** (2026-08-06) by the SH-221 media slice in PR #47, with
|
|
**fail-closed** account scope (follow-up on the same PR):
|
|
|
|
- `WorkOrder.AccountId` / `ApplicationUser.AccountId` schema keys
|
|
- JWT `account_id` when `ApplicationUser.AccountId` is set
|
|
- JWT `org_scope=all` when Admin has no AccountId (explicit signed elevation)
|
|
- Media loads: `ApplyBaseScope` + `ApplyAccountScope(int)` when account-scoped;
|
|
org-wide path skips account filter
|
|
- Missing/malformed scope → **Forbidden** (absence of claim does not elevate)
|
|
|
|
Board, detail, and search outside media still use base scope only until the
|
|
remainder of [SH-221](https://luby-us.atlassian.net/browse/SH-221) lands.
|
|
|
|
## Context (historical)
|
|
|
|
SH-116 requires that cross-tenant, unauthorized, and out-of-scope media access
|
|
be rejected without metadata disclosure. An interim Proposed ADR allowed
|
|
org-wide staff access via absence of an account claim; that path was rejected
|
|
in review (fail-open) and replaced by the contract below.
|
|
|
|
## Current media contract (superseding)
|
|
|
|
1. **Organization boundary** = `ApplyBaseScope` (non-deleted, non-template).
|
|
2. **Account boundary** = claim `account_id` → `WorkOrder.AccountId == claim`.
|
|
3. **Org-wide** = claim `org_scope=all` only (issued to Admin without
|
|
AccountId). Not inferred from missing `account_id`.
|
|
4. **Fail-closed** = no valid account or org-scope claim → Forbidden.
|
|
5. **Authorization at service entry**: staff roles may read/mutate any resulting
|
|
work order; role `User` only when `AssignTo == actorId`; delete staff-only.
|
|
6. **User lifecycle** persists `AccountId` on create/edit so non-Admin principals
|
|
can receive `account_id`.
|
|
|
|
## Consequences
|
|
|
|
- Cross-account and missing-scope media tests are required.
|
|
- Dispatcher/Manager/Supervisor/User without AccountId cannot access media until
|
|
AccountId is assigned (or they are Admin with `org_scope=all`).
|
|
- Board/search/detail without account filtering remain a SH-221 follow-up.
|
|
|
|
## Excepted rule
|
|
|
|
None for media. Hard rule **server-derived tenant scope**
|
|
(`ARCHITECTURE_AND_CODE_QUALITY.md` §2) is enforced via claims.
|
|
|
|
## Review / expiry
|
|
|
|
Re-review when SH-221 closes remaining board/search/detail account filters, or
|
|
by **2027-02-04**.
|
|
|
|
## References
|
|
|
|
- SH-116 — Completion document: fields + media categorization
|
|
- SH-221 — Server-derived tenant/customer scope for Work Order domain
|
|
- PR: Sea-Haven-Industries/shoc-backend#47
|
|
- `WorkOrderBoardQueryFilters.ApplyBaseScope` / `ApplyAccountScope`
|
|
- `WorkOrderMediaAuthorization` / `SeaHavenClaimTypes`
|
|
- `ARCHITECTURE_AND_CODE_QUALITY.md` §2, §10
|