406 lines
10 KiB
YAML
406 lines
10 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: EDUT Member App Channel API
|
|
version: 1.0.0
|
|
description: |
|
|
Deterministic member communication channel contract.
|
|
App notifications are derived from wallet-authenticated membership and entitlement state.
|
|
servers:
|
|
- url: https://api.edut.ai
|
|
security:
|
|
- WalletSession: []
|
|
paths:
|
|
/member/channel/device/register:
|
|
post:
|
|
summary: Register or refresh a member app device channel binding.
|
|
operationId: registerMemberDevice
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DeviceRegisterRequest'
|
|
responses:
|
|
'200':
|
|
description: Device channel binding active.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DeviceRegisterResponse'
|
|
'403':
|
|
description: Membership is not active for this wallet.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
/member/channel/device/unregister:
|
|
post:
|
|
summary: Remove a device channel binding.
|
|
operationId: unregisterMemberDevice
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DeviceUnregisterRequest'
|
|
responses:
|
|
'200':
|
|
description: Device channel binding removed.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DeviceUnregisterResponse'
|
|
'404':
|
|
description: Device channel binding not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
/member/channel/events:
|
|
get:
|
|
summary: Poll deterministic member channel events.
|
|
operationId: listMemberChannelEvents
|
|
parameters:
|
|
- in: query
|
|
name: wallet
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Wallet address tied to session.
|
|
- in: query
|
|
name: device_id
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- in: query
|
|
name: cursor
|
|
required: false
|
|
schema:
|
|
type: string
|
|
- in: query
|
|
name: limit
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 25
|
|
responses:
|
|
'200':
|
|
description: Event page for in-app inbox rendering.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EventListResponse'
|
|
'403':
|
|
description: Membership inactive or suspended.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
/member/channel/events/{event_id}/ack:
|
|
post:
|
|
summary: Acknowledge event delivery/read state.
|
|
operationId: acknowledgeMemberChannelEvent
|
|
parameters:
|
|
- in: path
|
|
name: event_id
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EventAckRequest'
|
|
responses:
|
|
'200':
|
|
description: Event acknowledged.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/EventAckResponse'
|
|
'404':
|
|
description: Event not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
/member/channel/support/ticket:
|
|
post:
|
|
summary: Open support/admin ticket (org root owner only).
|
|
operationId: createOwnerSupportTicket
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SupportTicketRequest'
|
|
responses:
|
|
'200':
|
|
description: Support ticket accepted.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SupportTicketResponse'
|
|
'403':
|
|
description: Principal is not org root owner.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
components:
|
|
securitySchemes:
|
|
WalletSession:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: EDUT-WALLET-SESSION
|
|
schemas:
|
|
DeviceRegisterRequest:
|
|
type: object
|
|
required:
|
|
- wallet
|
|
- chain_id
|
|
- device_id
|
|
- platform
|
|
- org_root_id
|
|
- principal_id
|
|
- principal_role
|
|
- app_version
|
|
properties:
|
|
wallet:
|
|
type: string
|
|
description: Hex wallet address.
|
|
chain_id:
|
|
type: integer
|
|
description: Active chain id in app session.
|
|
device_id:
|
|
type: string
|
|
description: Stable app-install identifier.
|
|
platform:
|
|
type: string
|
|
enum: [ios, android, desktop]
|
|
org_root_id:
|
|
type: string
|
|
description: Organization boundary id for channel scoping.
|
|
principal_id:
|
|
type: string
|
|
description: Human principal id for this session.
|
|
principal_role:
|
|
type: string
|
|
enum: [workspace_member, org_root_owner]
|
|
app_version:
|
|
type: string
|
|
push_provider:
|
|
type: string
|
|
enum: [apns, fcm, webpush, none]
|
|
default: none
|
|
push_token:
|
|
type: string
|
|
description: Provider token if push is enabled.
|
|
DeviceRegisterResponse:
|
|
type: object
|
|
required:
|
|
- channel_binding_id
|
|
- status
|
|
- poll_interval_seconds
|
|
- server_time
|
|
properties:
|
|
channel_binding_id:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum: [active]
|
|
poll_interval_seconds:
|
|
type: integer
|
|
minimum: 10
|
|
server_time:
|
|
type: string
|
|
format: date-time
|
|
DeviceUnregisterRequest:
|
|
type: object
|
|
required:
|
|
- wallet
|
|
- device_id
|
|
properties:
|
|
wallet:
|
|
type: string
|
|
device_id:
|
|
type: string
|
|
DeviceUnregisterResponse:
|
|
type: object
|
|
required:
|
|
- status
|
|
- wallet
|
|
- device_id
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum: [removed]
|
|
wallet:
|
|
type: string
|
|
device_id:
|
|
type: string
|
|
EventListResponse:
|
|
type: object
|
|
required:
|
|
- wallet
|
|
- device_id
|
|
- org_root_id
|
|
- principal_id
|
|
- membership_status
|
|
- identity_assurance_level
|
|
- events
|
|
- next_cursor
|
|
- server_time
|
|
properties:
|
|
wallet:
|
|
type: string
|
|
device_id:
|
|
type: string
|
|
org_root_id:
|
|
type: string
|
|
principal_id:
|
|
type: string
|
|
membership_status:
|
|
type: string
|
|
enum: [active, none, suspended, revoked, unknown]
|
|
identity_assurance_level:
|
|
type: string
|
|
enum: [none, crypto_direct_unattested, sponsored_unattested, onramp_attested]
|
|
events:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MemberEvent'
|
|
next_cursor:
|
|
type: string
|
|
nullable: true
|
|
server_time:
|
|
type: string
|
|
format: date-time
|
|
MemberEvent:
|
|
type: object
|
|
required:
|
|
- event_id
|
|
- class
|
|
- created_at
|
|
- title
|
|
- body
|
|
- dedupe_key
|
|
- policy_hash
|
|
properties:
|
|
event_id:
|
|
type: string
|
|
class:
|
|
type: string
|
|
enum:
|
|
- offer_available
|
|
- entitlement_activated
|
|
- platform_update
|
|
- publisher_update
|
|
- membership_policy
|
|
- admin_health
|
|
- admin_config
|
|
- admin_update
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
title:
|
|
type: string
|
|
body:
|
|
type: string
|
|
dedupe_key:
|
|
type: string
|
|
requires_ack:
|
|
type: boolean
|
|
default: true
|
|
policy_hash:
|
|
type: string
|
|
payload:
|
|
type: object
|
|
additionalProperties: true
|
|
visibility_scope:
|
|
type: string
|
|
enum: [member, owner_admin]
|
|
default: member
|
|
EventAckRequest:
|
|
type: object
|
|
required:
|
|
- wallet
|
|
- device_id
|
|
- acknowledged_at
|
|
properties:
|
|
wallet:
|
|
type: string
|
|
device_id:
|
|
type: string
|
|
acknowledged_at:
|
|
type: string
|
|
format: date-time
|
|
EventAckResponse:
|
|
type: object
|
|
required:
|
|
- status
|
|
- event_id
|
|
- acknowledged_at
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum: [acknowledged]
|
|
event_id:
|
|
type: string
|
|
acknowledged_at:
|
|
type: string
|
|
format: date-time
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error
|
|
- code
|
|
properties:
|
|
error:
|
|
type: string
|
|
code:
|
|
type: string
|
|
correlation_id:
|
|
type: string
|
|
SupportTicketRequest:
|
|
type: object
|
|
required:
|
|
- wallet
|
|
- org_root_id
|
|
- principal_id
|
|
- category
|
|
- summary
|
|
properties:
|
|
wallet:
|
|
type: string
|
|
org_root_id:
|
|
type: string
|
|
principal_id:
|
|
type: string
|
|
category:
|
|
type: string
|
|
enum: [admin_support, health_diagnostic, boundary_issue, update_control]
|
|
summary:
|
|
type: string
|
|
context:
|
|
type: object
|
|
additionalProperties: true
|
|
SupportTicketResponse:
|
|
type: object
|
|
required:
|
|
- status
|
|
- ticket_id
|
|
- created_at
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum: [accepted]
|
|
ticket_id:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|