Source document
docs/platform/PARTNER-LIFECYCLE.md
Source version
0.0.0
Generated time
2026-07-06T14:59:22.158Z
Owner
Unassigned
Audience
Internal
Status
Approved

Partner Lifecycle — Specification (Beta-4)

Đặc tả vòng đời Partner (đối tác) của BNG Booking Platform. Nguồn sự thật code:
packages/platform-infrastructure/src/provisioning/provisioning-service.ts (transition + audit),
packages/platform-infrastructure/src/auth/api-key-store.ts (cổng auth theo Partner status).
Kiểm chứng E2E: src/__tests__/partner-management-e2e.test.ts, src/__tests__/ops-partner.test.ts.

Partner là gì

Partner = một Customer trong mô hình hiện có (1 Partner ↔ tối đa 1 Tenant). Beta-4 KHÔNG thêm bảng mới — tái dùng customers.status (đã có sẵn) làm trạng thái vòng đời. partnerId == customerId.

Trạng thái

Trạng tháiÝ nghĩaKey của partner auth được?
pendingVừa tạo, chưa kích hoạt.❌ (cổng Partner chặn)
activeĐang hoạt động bình thường.✅ (nếu key active/rotating + còn hạn)
suspendedTạm ngưng (nợ phí/nghi lạm dụng). Thuận nghịch.❌ (cổng Partner chặn — key KHÔNG bị huỷ)
revokedChấm dứt vĩnh viễn. Terminal.❌ (mọi key bị revoke)
Cổng Partner (auth): findActiveKey từ chối key nếu Partner chủ quản không active.
Nhờ vậy suspend/reactivate là THUẬN NGHỊCH: suspend chỉ đổi status, không đụng row key;
reactivate đưa status về activeđúng key cũ hoạt động trở lại (không cần cấp lại).

Sơ đồ chuyển trạng thái

          create                 activate                suspend
   (∅) ──────────▶ pending ─────────────▶ active ──────────────▶ suspended
                     │                      ▲   │                    │
                     │                      └───┘ reactivate ────────┘
                     │                      │
                     │ revoke               │ revoke                  │ revoke
                     ▼                      ▼                         ▼
                              revoked  (TERMINAL — huỷ mọi key)

Transition hợp lệ

TừThao tácĐếnAudit event
createPartnerpendingpartner.created
pendingactivatePartneractivepartner.activated
activesuspendPartnersuspendedpartner.suspended
suspendedreactivatePartneractivepartner.reactivated
pending / active / suspendedrevokePartnerrevokedpartner.revoked

Transition KHÔNG hợp lệ (⇒ PARTNER_INVALID_TRANSITION, exit code 2)

activate ép nguồn pending; reactivate ép nguồn suspended (guard expectFrom) — hai lối vào active
phân biệt rõ để audit đúng ngữ nghĩa.

Invariant

  1. Terminal: revoked không có transition ra. (Khôi phục = tạo Partner mới.)
  2. Suspend thuận nghịch: suspend không huỷ/đổi status key ⇒ reactivate khôi phục nguyên trạng key.
  3. Revoke terminal huỷ key: revokePartner revoke mọi key còn sống của partner (không thể auth lại kể cả khi… không có "un-revoke").
  4. Cổng auth = Partner status: nguồn sự thật cho "được gọi API không" là customers.status = active key hợp lệ. Không có đường vòng.
  5. Audit đầy đủ & bất biến: mỗi transition sinh đúng 1 AuditEvent (append-only). Không thao tác nào đổi trạng thái mà không audit.
  6. Không secret trong audit: metadata sanitize ở domain (drop secret/token/apikey/...); raw key không bao giờ vào audit.

Audit event (đối chiếu Deliverable #5)

Scope audit đối tác: AuditEvent.tenantId = partnerId (audit quản trị đối tác ở cấp nền, tách khỏi audit nghiệp vụ theo tenant). entityRef = partnerId (event partner.*) hoặc keyId (event apikey.*).

Thao tácAudit action
Tạo Partnerpartner.created
Kích hoạtpartner.activated
Suspendpartner.suspended
Reactivatepartner.reactivated
Cấp keyapikey.issued
Rotate keyapikey.rotated
Revoke keyapikey.revoked
Revoke Partner (kèm huỷ mọi key)partner.revoked

Xem PARTNER-AUDIT-VERIFICATION.md để biết cách tự kiểm chứng.

Quan hệ với API Key lifecycle

pending_delivery → active → (rotating) → revoked | expired — độc lập với Partner status, nhưng cổng Partner đứng trước: dù key active, nếu Partner không active thì vẫn 401. Chi tiết vận hành: ../operations/PARTNER-OPERATIONS.md.