From 7dcccafc030af11436e3abaa8f7380ae5f5c0919 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 10 Aug 2026 18:54:28 +0200 Subject: [PATCH] Plan tenant update and retirement APIs --- WORK-RECORDS.md | 6 + ...P-0005-tenant-update-and-retirement-api.md | 133 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 workplans/TEN-WP-0005-tenant-update-and-retirement-api.md diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index c70d26c..f554f27 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -13,6 +13,7 @@ | workplan | TEN-WP-0002 | finished | — | workplans/TEN-WP-0002-domain-model-and-scaffold.md | | workplan | TEN-WP-0003 | finished | — | workplans/TEN-WP-0003-flex-auth-write-authorizer.md | | workplan | TEN-WP-0004 | finished | — | workplans/TEN-WP-0004-production-runtime.md | +| workplan | TEN-WP-0005 | ready | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | | task | ADHOC-2026-07-24-T01 | done | — | workplans/ADHOC-2026-07-24.md | | task | TEN-WP-0001-T01 | done | — | workplans/TEN-WP-0001-statehub-bootstrap.md | | task | TEN-WP-0001-T02 | done | — | workplans/TEN-WP-0001-statehub-bootstrap.md | @@ -31,3 +32,8 @@ | task | TEN-WP-0004-T01 | done | — | workplans/TEN-WP-0004-production-runtime.md | | task | TEN-WP-0004-T02 | done | — | workplans/TEN-WP-0004-production-runtime.md | | task | TEN-WP-0004-T03 | done | — | workplans/TEN-WP-0004-production-runtime.md | +| task | TEN-WP-0005-T01 | todo | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | +| task | TEN-WP-0005-T02 | todo | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | +| task | TEN-WP-0005-T03 | todo | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | +| task | TEN-WP-0005-T04 | todo | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | +| task | TEN-WP-0005-T05 | wait | — | workplans/TEN-WP-0005-tenant-update-and-retirement-api.md | diff --git a/workplans/TEN-WP-0005-tenant-update-and-retirement-api.md b/workplans/TEN-WP-0005-tenant-update-and-retirement-api.md new file mode 100644 index 0000000..237ffdc --- /dev/null +++ b/workplans/TEN-WP-0005-tenant-update-and-retirement-api.md @@ -0,0 +1,133 @@ +--- +id: TEN-WP-0005 +type: workplan +title: "Tenant metadata update and reversible retirement API" +domain: infotech +repo: tenant-engine +status: ready +owner: codex +topic_slug: tenant-lifecycle +created: "2026-08-10" +updated: "2026-08-10" +depends_on: + - TEN-WP-0004 +unblocks: + - USER-WP-0021 +state_hub_workstream_id: "bc1bd413-381a-4aca-aded-73cb3d0af529" +--- + +# TEN-WP-0005 - Tenant update and retirement API + +Extend tenant-engine, the canonical tenant authority, with safe metadata update +and reversible retirement operations. Tenant identifiers remain immutable. +Retirement must preserve referential integrity, grant history, plan history, +and audit correlation; it is not a hard-delete endpoint. + +## T01 - Specify tenant lifecycle and HTTP contracts + +```task +id: TEN-WP-0005-T01 +status: todo +priority: high +state_hub_task_id: "5b7d9022-4c0f-4bc3-9f63-b268836c8efc" +``` + +Add an explicit tenant lifecycle (`active` and `retired`), mutable display +metadata, record version, and lifecycle timestamps to the domain contract. +Specify: + +- `GET /tenants/{tenant_id}` for authoritative lifecycle and metadata reads; +- `PATCH /tenants/{tenant_id}` for allow-listed metadata changes; +- `POST /tenants/{tenant_id}/retire` for reversible retirement; +- `POST /tenants/{tenant_id}/reactivate` for controlled recovery. + +Every mutation requires `Idempotency-Key`, `If-Match`, actor, reason, and +correlation ID. Tenant IDs and identifiers are immutable. Unknown fields, +empty updates, stale versions, and invalid lifecycle transitions fail closed. +Document stable response/error schemas for user-engine and other consumers. + +Done when the OpenAPI contract makes concurrency, idempotency, authorization, +and lifecycle semantics unambiguous without defining a hard-delete operation. + +## T02 - Implement durable lifecycle state and migration + +```task +id: TEN-WP-0005-T02 +status: todo +priority: high +state_hub_task_id: "3596d8f2-06cf-4bf9-bdab-00cf48a25956" +``` + +Extend the domain and both store implementations with display metadata, +lifecycle state, version, updated/retired/reactivated timestamps, and mutation +reason/correlation evidence. Add a forward-only PostgreSQL migration that +defaults existing tenants to active and preserves current identifiers, roles, +and plan assignments. Persist idempotency receipts so retries return the same +result across process restarts. + +Done when in-memory and PostgreSQL conformance prove atomic compare-and-swap, +restart-safe idempotency, and lossless migration of existing tenants. + +## T03 - Implement authorized update and lifecycle endpoints + +```task +id: TEN-WP-0005-T03 +status: todo +priority: high +state_hub_task_id: "083bcd28-47f4-4337-9bbe-e2f9f67cc2d1" +``` + +Implement the read, patch, retire, and reactivate handlers through the store +abstraction. Authorize mutations with distinct flex-auth actions: +`tenant.update`, `tenant.retire`, and `tenant.reactivate`. Return 409 for stale +versions or invalid transitions, 404 for unknown tenants, and redacted 503 +responses for authority/store failures. Never reflect policy or database +details. + +Retirement prevents new role grants and plan changes while retaining existing +history for audit and recovery. Reactivation does not silently restore revoked +grants or invent plan state. + +Done when all lifecycle mutations are authorized, versioned, idempotent, +correlated, and provider-neutral. + +## T04 - Add lifecycle security and compatibility conformance + +```task +id: TEN-WP-0005-T04 +status: todo +priority: high +state_hub_task_id: "b716d7bf-ef6b-4b1d-bac3-e3f716d1a0b8" +``` + +Cover successful update, no-op/unknown-field rejection, identifier mutation +denial, stale-version conflict, duplicate idempotency replay, conflicting-key +reuse, double retirement, reactivation, update-after-retirement denial, +role/plan mutation denial while retired, cross-tenant authorization denial, +store outage, and concurrent writers. Verify error redaction and correlation. +Prove existing create, role-read, grant/revoke, and plan clients remain +compatible. + +Done when unit, API, store-conformance, PostgreSQL, and flex-auth tests pass and +the existing API behavior has no unplanned breaking change. + +## T05 - Integrate and verify the production authority + +```task +id: TEN-WP-0005-T05 +status: wait +priority: high +state_hub_task_id: "9b21782a-1b26-4fac-81a1-06bd7e8cf70f" +``` + +Publish an immutable tenant-engine image, apply the migration, add the three +flex-auth actions, and roll out with rollback evidence. Exercise create, +update, retire, denied mutation while retired, reactivate, and idempotent replay +against a disposable production tenant. Hand the finalized contract to +user-engine so USER-WP-0021 can implement its platform operator UI/API without +duplicating tenant authority. + +Done when production evidence confirms durable lifecycle behavior and the +consumer handoff names the immutable image, API version, and authorization +policy revision. +