TenantAtlas/specs/274-billing-subscription-truth/contracts/workspace-billing-subscription-truth.logical.openapi.yaml
Ahmed Darrazi b7a587495f
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 17m36s
chore: commit all local changes
2026-05-04 23:02:19 +02:00

482 lines
14 KiB
YAML

openapi: 3.0.3
info:
title: TenantPilot Admin/System - Workspace Billing & Subscription Truth (Conceptual)
version: 0.1.0
description: |
Conceptual contract for the bounded billing and subscription truth follow-through
over existing entitlement and commercial lifecycle foundations.
NOTE: These routes are implemented as existing Filament pages, resources,
widgets, and Livewire-backed actions. Exact Livewire payload shapes are not
part of this contract. This file captures logical route boundaries, plane
separation, and the requirement that runtime gating still flows through the
shared commercial lifecycle resolver.
paths:
/directory/workspaces/{workspace}:
servers:
- url: /system
get:
summary: View current subscription truth and derived commercial posture in the system plane
parameters:
- $ref: '#/components/parameters/WorkspaceId'
responses:
'200':
description: System workspace detail rendered
content:
text/html:
schema:
type: string
x-logical-view-model:
$ref: '#/components/schemas/SystemWorkspaceSubscriptionView'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/directory/workspaces/{workspace}/actions/update-subscription-truth:
servers:
- url: /system
post:
summary: Create or update the current workspace subscription truth from the system plane
description: |
Conceptual contract for the confirmation-protected system action that
creates or updates one current workspace subscription record.
Behavior:
- Platform user with directory visibility but without the dedicated
commercial-management capability: 403
- Wrong plane or non-platform actor: 404 semantics at the panel boundary
- Authorized platform user: writes the current subscription record and
audit trail, then updates the derived lifecycle source used by current
onboarding and review-pack flows
parameters:
- $ref: '#/components/parameters/WorkspaceId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSubscriptionTruthCommand'
responses:
'204':
description: Current subscription truth updated successfully
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
/directory/workspaces/{workspace}/actions/change-commercial-state:
servers:
- url: /system
post:
summary: Change the fallback manual commercial lifecycle state when no subscription record exists
description: |
Conceptual contract for the existing manual lifecycle action after this
slice lands.
Behavior:
- available only when the workspace has no current subscription record
- remains confirmation-protected
- preserves the current settings-backed fallback semantics from Spec 251
parameters:
- $ref: '#/components/parameters/WorkspaceId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- state
- reason
properties:
state:
type: string
reason:
type: string
responses:
'204':
description: Fallback lifecycle state changed successfully
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
description: Current subscription truth exists, so fallback mutation is unavailable
/settings/workspace:
servers:
- url: /admin
get:
summary: View a read-only subscription-backed commercial summary on the admin workspace settings page
responses:
'200':
description: Workspace settings page rendered
content:
text/html:
schema:
type: string
x-logical-view-model:
$ref: '#/components/schemas/SettingsSubscriptionSummaryView'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/onboarding/{onboardingDraft}:
servers:
- url: /admin
get:
summary: View onboarding workflow with subscription-backed lifecycle gating when a subscription exists
parameters:
- $ref: '#/components/parameters/OnboardingDraftId'
responses:
'200':
description: Onboarding wizard rendered
content:
text/html:
schema:
type: string
x-logical-view-model:
$ref: '#/components/schemas/LifecycleDecisionView'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/onboarding/{onboardingDraft}/actions/complete:
servers:
- url: /admin
post:
summary: Complete onboarding when entitlement substrate and derived lifecycle both allow it
parameters:
- $ref: '#/components/parameters/OnboardingDraftId'
responses:
'204':
description: Onboarding completed
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/BusinessStateBlocked'
/review-packs/actions/generate:
servers:
- url: /admin
post:
summary: Generate a review pack through the existing shared lifecycle gate
description: |
Behavior ordering:
1. authorization
2. underlying entitlement substrate decision
3. derived lifecycle decision, potentially sourced from current subscription truth
4. existing dedupe or queued-start flow when allowed
A blocked attempt creates no new `ReviewPack`, creates no new
`OperationRun`, and emits no queued or terminal review-pack notification.
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ReviewPackGenerationCommand'
responses:
'202':
description: Generation accepted or deduped through the existing flow
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/BusinessStateBlocked'
/tenant-reviews/{tenantReview}/actions/export-executive-pack:
servers:
- url: /admin
post:
summary: Export an executive pack through the existing shared lifecycle gate
parameters:
- $ref: '#/components/parameters/TenantReviewId'
responses:
'202':
description: Export accepted or deduped through the existing flow
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/BusinessStateBlocked'
/review-packs/{reviewPack}/actions/regenerate:
servers:
- url: /admin
post:
summary: Regenerate a review pack through the existing shared lifecycle gate
parameters:
- $ref: '#/components/parameters/ReviewPackId'
responses:
'202':
description: Regeneration accepted or deduped through the existing flow
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/BusinessStateBlocked'
components:
parameters:
WorkspaceId:
name: workspace
in: path
required: true
schema:
type: integer
OnboardingDraftId:
name: onboardingDraft
in: path
required: true
schema:
type: integer
TenantReviewId:
name: tenantReview
in: path
required: true
schema:
type: integer
ReviewPackId:
name: reviewPack
in: path
required: true
schema:
type: integer
responses:
Forbidden:
description: Actor is in-scope but missing the required capability
NotFound:
description: Wrong plane or non-member access is hidden as not found
ValidationError:
description: Submitted subscription truth is invalid for the chosen state
BusinessStateBlocked:
description: The actor is otherwise authorized, but the derived lifecycle blocks the action
schemas:
UpdateSubscriptionTruthCommand:
oneOf:
- $ref: '#/components/schemas/TrialSubscriptionCommand'
- $ref: '#/components/schemas/ActiveSubscriptionCommand'
- $ref: '#/components/schemas/PastDueSubscriptionCommand'
- $ref: '#/components/schemas/CancelAtPeriodEndSubscriptionCommand'
- $ref: '#/components/schemas/EndedSubscriptionCommand'
TrialSubscriptionCommand:
type: object
required:
- state
- trial_ends_at
- status_reason
properties:
state:
type: string
enum:
- trial
billing_reference:
type: string
nullable: true
trial_ends_at:
type: string
format: date-time
status_reason:
type: string
ActiveSubscriptionCommand:
type: object
required:
- state
- current_period_starts_at
- current_period_ends_at
- status_reason
properties:
state:
type: string
enum:
- active
billing_reference:
type: string
nullable: true
current_period_starts_at:
type: string
format: date-time
current_period_ends_at:
type: string
format: date-time
status_reason:
type: string
PastDueSubscriptionCommand:
type: object
required:
- state
- current_period_starts_at
- current_period_ends_at
- status_reason
properties:
state:
type: string
enum:
- past_due
billing_reference:
type: string
nullable: true
current_period_starts_at:
type: string
format: date-time
current_period_ends_at:
type: string
format: date-time
status_reason:
type: string
CancelAtPeriodEndSubscriptionCommand:
type: object
required:
- state
- current_period_starts_at
- current_period_ends_at
- status_reason
properties:
state:
type: string
enum:
- cancel_at_period_end
billing_reference:
type: string
nullable: true
current_period_starts_at:
type: string
format: date-time
current_period_ends_at:
type: string
format: date-time
status_reason:
type: string
EndedSubscriptionCommand:
type: object
required:
- state
- current_period_ends_at
- status_reason
properties:
state:
type: string
enum:
- ended
billing_reference:
type: string
nullable: true
current_period_ends_at:
type: string
format: date-time
status_reason:
type: string
WorkspaceSubscriptionSummary:
type: object
required:
- source
- fallback_status
- subscription_present
- derived_lifecycle_state
- needs_review
properties:
source:
type: string
enum:
- workspace_subscription
- workspace_setting
- default_active_paid
fallback_status:
type: boolean
subscription_present:
type: boolean
state:
type: string
nullable: true
label:
type: string
nullable: true
billing_reference:
type: string
nullable: true
status_reason:
type: string
nullable: true
key_date_label:
type: string
nullable: true
key_date:
type: string
format: date-time
nullable: true
needs_review:
type: boolean
derived_lifecycle_state:
type: string
SystemWorkspaceSubscriptionView:
allOf:
- $ref: '#/components/schemas/WorkspaceSubscriptionSummary'
- type: object
properties:
last_changed_at:
type: string
format: date-time
nullable: true
last_changed_by:
type: string
nullable: true
SettingsSubscriptionSummaryView:
type: object
required:
- source
- derived_lifecycle_state
- fallback_status
- state_label
- explanation
properties:
source:
type: string
enum:
- workspace_subscription
- workspace_setting
- default_active_paid
derived_lifecycle_state:
type: string
state_label:
type: string
explanation:
type: string
fallback_status:
type: boolean
key_date_label:
type: string
nullable: true
key_date:
type: string
format: date-time
nullable: true
LifecycleDecisionView:
type: object
required:
- lifecycle_state
- source
- outcome
- explanation
properties:
lifecycle_state:
type: string
source:
type: string
enum:
- workspace_subscription
- workspace_setting
- default_active_paid
outcome:
type: string
enum:
- allow
- warn
- block
explanation:
type: string
ReviewPackGenerationCommand:
type: object
additionalProperties: true