Expand portal onboarding and administration
This commit is contained in:
parent
3d334479e9
commit
8229c6dd33
17 changed files with 1601 additions and 32 deletions
|
|
@ -1,7 +1,7 @@
|
|||
openapi: 3.1.0
|
||||
info:
|
||||
title: user-engine portal API
|
||||
version: 0.1.0
|
||||
version: 0.2.0
|
||||
servers:
|
||||
- url: /api/v1
|
||||
security:
|
||||
|
|
@ -15,6 +15,19 @@ paths:
|
|||
description: Current user and linked identities
|
||||
"403":
|
||||
$ref: "#/components/responses/Denied"
|
||||
/me/profile:
|
||||
patch:
|
||||
operationId: updateCurrentUserProfile
|
||||
description: Updates display name and versioned consent; verified email cannot be changed here.
|
||||
parameters: [{$ref: "#/components/parameters/IdempotencyKey"}]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/UpdateSelfProfile"}
|
||||
responses:
|
||||
"200": {description: Durable self-service profile state}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/registrations:
|
||||
post:
|
||||
operationId: startRegistration
|
||||
|
|
@ -49,6 +62,19 @@ paths:
|
|||
responses:
|
||||
"200": {description: Tenant-scoped memberships}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
post:
|
||||
operationId: createTenantUser
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/CreateUser"}
|
||||
responses:
|
||||
"201": {description: Tenant user and membership created}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/tenants/{tenant}/users/{userId}:
|
||||
patch:
|
||||
operationId: updateTenantUserLifecycle
|
||||
|
|
@ -62,6 +88,132 @@ paths:
|
|||
responses:
|
||||
"200": {description: Tenant account updated}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
delete:
|
||||
operationId: removeTenantUser
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/UserId"
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
responses:
|
||||
"200": {description: Login deprovisioned and tenant account disabled}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/tenants/{tenant}/invitations:
|
||||
get:
|
||||
operationId: listInvitations
|
||||
parameters: [{$ref: "#/components/parameters/Tenant"}]
|
||||
responses:
|
||||
"200": {description: Tenant invitations}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
post:
|
||||
operationId: createInvitation
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/CreateInvitation"}
|
||||
responses:
|
||||
"201": {description: Invitation created with an expiry and version}
|
||||
"409": {$ref: "#/components/responses/Conflict"}
|
||||
/tenants/{tenant}/invitations/{invitationId}/resend:
|
||||
post:
|
||||
operationId: resendInvitation
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/InvitationId"
|
||||
- $ref: "#/components/parameters/IfMatch"
|
||||
responses:
|
||||
"200": {description: Invitation expiry renewed and version advanced}
|
||||
"409": {$ref: "#/components/responses/Conflict"}
|
||||
/tenants/{tenant}/invitations/{invitationId}/expire:
|
||||
post:
|
||||
operationId: expireInvitation
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/InvitationId"
|
||||
- $ref: "#/components/parameters/IfMatch"
|
||||
responses:
|
||||
"200": {description: Invitation revoked}
|
||||
"409": {$ref: "#/components/responses/Conflict"}
|
||||
/invitations/{invitationId}/claim:
|
||||
post:
|
||||
operationId: claimInvitation
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/InvitationId"
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
responses:
|
||||
"200": {description: Invitation claimed and identity linked}
|
||||
"400": {description: Invitation expired, revoked, or already claimed}
|
||||
/onboarding/{journeyId}/steps/{stepKey}/complete:
|
||||
post:
|
||||
operationId: completeOnboardingStep
|
||||
description: Completes an active user-engine-owned step. Provider-owned steps must use their external handoff and callback.
|
||||
parameters:
|
||||
- name: journeyId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
- name: stepKey
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
responses:
|
||||
"200": {description: Updated resumable onboarding journey}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
"404": {description: Journey is absent or belongs to another user}
|
||||
/platform/tenants:
|
||||
post:
|
||||
operationId: createPlatformTenant
|
||||
description: Creates a tenant through the configured tenant authority and optionally prepares its first administrator.
|
||||
parameters: [{$ref: "#/components/parameters/IdempotencyKey"}]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/CreateTenant"}
|
||||
responses:
|
||||
"201": {description: Tenant created or resumed and first administrator prepared}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/platform/tenants/{tenant}/users/{userId}/recover:
|
||||
post:
|
||||
operationId: recoverTenantUser
|
||||
description: Reconciles or recreates the provider identity and activates the tenant account without exposing provider credentials.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Tenant"
|
||||
- $ref: "#/components/parameters/UserId"
|
||||
- $ref: "#/components/parameters/IdempotencyKey"
|
||||
responses:
|
||||
"200": {description: Redacted recovery outcome}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/platform/outbox/deliver:
|
||||
post:
|
||||
operationId: deliverOutbox
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
worker_id: {type: string}
|
||||
max_attempts: {type: integer, minimum: 1, maximum: 20}
|
||||
additionalProperties: false
|
||||
responses:
|
||||
"200": {description: Bounded delivery results}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
/platform/outbox/{eventId}/replay:
|
||||
post:
|
||||
operationId: replayOutboxEvent
|
||||
parameters:
|
||||
- name: eventId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
responses:
|
||||
"200": {description: Event returned to pending delivery}
|
||||
"403": {$ref: "#/components/responses/Denied"}
|
||||
components:
|
||||
securitySchemes:
|
||||
verifiedOidc:
|
||||
|
|
@ -78,6 +230,77 @@ components:
|
|||
in: header
|
||||
required: true
|
||||
schema: {type: string, minLength: 16, maxLength: 200}
|
||||
UserId:
|
||||
name: userId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
InvitationId:
|
||||
name: invitationId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string}
|
||||
IfMatch:
|
||||
name: If-Match
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: string, pattern: '^"?[0-9]+"?$'}
|
||||
schemas:
|
||||
CreateUser:
|
||||
type: object
|
||||
required: [primary_email, role]
|
||||
properties:
|
||||
primary_email: {type: string, format: email}
|
||||
display_name: {type: string, maxLength: 200}
|
||||
role: {type: string, enum: [user, tenant-admin]}
|
||||
additionalProperties: false
|
||||
CreateInvitation:
|
||||
type: object
|
||||
required: [primary_email]
|
||||
properties:
|
||||
primary_email: {type: string, format: email}
|
||||
display_name: {type: string, maxLength: 200}
|
||||
role: {type: string, enum: [user, tenant-admin]}
|
||||
application_id: {type: string}
|
||||
scope_id: {type: string}
|
||||
additionalProperties: false
|
||||
CreateTenant:
|
||||
type: object
|
||||
required: [tenant, display_name]
|
||||
properties:
|
||||
tenant: {type: string, pattern: '^tenant:'}
|
||||
display_name: {type: string, minLength: 1, maxLength: 200}
|
||||
first_admin:
|
||||
type: object
|
||||
required: [primary_email]
|
||||
properties:
|
||||
primary_email: {type: string, format: email}
|
||||
display_name: {type: string, maxLength: 200}
|
||||
additionalProperties: false
|
||||
additionalProperties: false
|
||||
UpdateSelfProfile:
|
||||
type: object
|
||||
required: [display_name, consent_accepted, consent_version]
|
||||
properties:
|
||||
display_name: {type: string, minLength: 1, maxLength: 200}
|
||||
consent_accepted: {type: boolean}
|
||||
consent_version: {type: string, minLength: 1, maxLength: 100}
|
||||
additionalProperties: false
|
||||
Error:
|
||||
type: object
|
||||
required: [error, message, correlation_id]
|
||||
properties:
|
||||
error: {type: string}
|
||||
message: {type: string}
|
||||
correlation_id: {type: string}
|
||||
responses:
|
||||
Denied:
|
||||
description: Caller is unauthenticated or unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/Error"}
|
||||
Conflict:
|
||||
description: Optimistic concurrency or uniqueness conflict
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: "#/components/schemas/Error"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue