- Add Gitea Actions workflow; point README to gitea.d-bis.org/Sankofa_Phoenix/SMOA - Expand .gitignore for Spring H2 data, secrets, Kotlin .kotlin/, tooling - Track docs/api/generated ReDoc bundle; refresh api docs README - Android: network/auth/sync, UI shell, tests; backend credentials/integrity APIs - Docs, scripts (generate-api-docs), modules and core updates Made-with: Cursor
525 lines
13 KiB
YAML
525 lines
13 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: SMOA API Specification
|
||
description: |
|
||
API specification for Secure Mobile Operations Application (SMOA).
|
||
|
||
**Authoritative mobile sync contract:** the running backend’s OpenAPI document
|
||
(`/v3/api-docs` via springdoc) matches Kotlin DTOs in `backend/src/main/kotlin/.../api/dto`.
|
||
This YAML is a **design reference**; prefer springdoc export in CI if drift is detected.
|
||
|
||
Credential **sync** uses `CredentialSyncRequest` (POST `/api/v1/sync/credential`), not the
|
||
legacy `Credential` resource shape below where paths differ.
|
||
version: 1.0.0
|
||
contact:
|
||
name: SMOA Development Team
|
||
email: [email protected]
|
||
license:
|
||
name: Proprietary - Government Use Only
|
||
|
||
servers:
|
||
- url: https://api.smoa.example.com/v1
|
||
description: Production server
|
||
- url: https://api-dev.smoa.example.com/v1
|
||
description: Development server
|
||
|
||
tags:
|
||
- name: Authentication
|
||
description: Authentication and authorization endpoints
|
||
- name: Credentials
|
||
description: Digital credential management
|
||
- name: Orders
|
||
description: Orders management
|
||
- name: Evidence
|
||
description: Evidence chain of custody
|
||
- name: Reports
|
||
description: Report generation
|
||
- name: Communications
|
||
description: Secure communications
|
||
- name: Directory
|
||
description: Internal directory
|
||
|
||
security:
|
||
- BearerAuth: []
|
||
- ApiKeyAuth: []
|
||
|
||
paths:
|
||
/auth/login:
|
||
post:
|
||
tags:
|
||
- Authentication
|
||
summary: Authenticate user
|
||
description: |
|
||
Authenticate user with multi-factor authentication (PIN + Biometric).
|
||
Returns authentication token on success.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/LoginRequest'
|
||
responses:
|
||
'200':
|
||
description: Authentication successful
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/LoginResponse'
|
||
'401':
|
||
description: Authentication failed
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
'429':
|
||
description: Too many login attempts
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
|
||
/auth/logout:
|
||
post:
|
||
tags:
|
||
- Authentication
|
||
summary: Logout user
|
||
description: Invalidates current session
|
||
responses:
|
||
'200':
|
||
description: Logout successful
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/credentials:
|
||
get:
|
||
tags:
|
||
- Credentials
|
||
summary: List user credentials
|
||
description: Returns list of credentials available to the authenticated user
|
||
parameters:
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [id, badge, license, permit, other]
|
||
description: Filter by credential type
|
||
responses:
|
||
'200':
|
||
description: List of credentials
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Credential'
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
post:
|
||
tags:
|
||
- Credentials
|
||
summary: Create new credential
|
||
description: Creates a new digital credential
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/CredentialCreate'
|
||
responses:
|
||
'201':
|
||
description: Credential created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Credential'
|
||
'400':
|
||
description: Invalid request
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/credentials/{id}:
|
||
get:
|
||
tags:
|
||
- Credentials
|
||
summary: Get credential by ID
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Credential ID
|
||
responses:
|
||
'200':
|
||
description: Credential details
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Credential'
|
||
'404':
|
||
description: Credential not found
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/orders:
|
||
get:
|
||
tags:
|
||
- Orders
|
||
summary: List orders
|
||
description: Returns list of orders available to the authenticated user
|
||
parameters:
|
||
- name: status
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [draft, pending_approval, approved, issued, executed, expired, revoked]
|
||
description: Filter by order status
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [authorization, assignment, search_warrant, arrest_warrant, court_order, administrative]
|
||
description: Filter by order type
|
||
responses:
|
||
'200':
|
||
description: List of orders
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Order'
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
post:
|
||
tags:
|
||
- Orders
|
||
summary: Create new order
|
||
description: Creates a new order
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/OrderCreate'
|
||
responses:
|
||
'201':
|
||
description: Order created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Order'
|
||
'400':
|
||
description: Invalid request
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/orders/{id}:
|
||
get:
|
||
tags:
|
||
- Orders
|
||
summary: Get order by ID
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Order ID
|
||
responses:
|
||
'200':
|
||
description: Order details
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/Order'
|
||
'404':
|
||
description: Order not found
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/evidence:
|
||
get:
|
||
tags:
|
||
- Evidence
|
||
summary: List evidence items
|
||
description: Returns list of evidence items
|
||
responses:
|
||
'200':
|
||
description: List of evidence items
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: '#/components/schemas/Evidence'
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
/reports:
|
||
post:
|
||
tags:
|
||
- Reports
|
||
summary: Generate report
|
||
description: Generates a report in the specified format
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ReportRequest'
|
||
responses:
|
||
'200':
|
||
description: Report generated
|
||
content:
|
||
application/pdf:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
application/json:
|
||
schema:
|
||
type: string
|
||
application/xml:
|
||
schema:
|
||
type: string
|
||
text/csv:
|
||
schema:
|
||
type: string
|
||
'400':
|
||
description: Invalid request
|
||
'401':
|
||
description: Unauthorized
|
||
|
||
components:
|
||
securitySchemes:
|
||
BearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
ApiKeyAuth:
|
||
type: apiKey
|
||
in: header
|
||
name: X-API-Key
|
||
|
||
schemas:
|
||
LoginRequest:
|
||
type: object
|
||
required:
|
||
- pin
|
||
- biometricToken
|
||
properties:
|
||
pin:
|
||
type: string
|
||
description: User PIN
|
||
minLength: 6
|
||
maxLength: 12
|
||
biometricToken:
|
||
type: string
|
||
description: Biometric authentication token
|
||
|
||
LoginResponse:
|
||
type: object
|
||
properties:
|
||
token:
|
||
type: string
|
||
description: Authentication token
|
||
expiresIn:
|
||
type: integer
|
||
description: Token expiration time in seconds
|
||
user:
|
||
$ref: '#/components/schemas/User'
|
||
|
||
User:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
username:
|
||
type: string
|
||
roles:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
Credential:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
type:
|
||
type: string
|
||
description: >
|
||
Canonical values align with Complete Credential CredentialRef.domain plus
|
||
SMOA barcode templates (see docs/reference/IDENTITY-TEMPLATE-ALIGNMENT.md).
|
||
enum:
|
||
- piv_pki
|
||
- payment
|
||
- nfc_access
|
||
- mobile
|
||
- icao9303_mrtd
|
||
- aamva_dlid
|
||
- mil_std_129
|
||
- agency_badge
|
||
- id
|
||
- badge
|
||
- license
|
||
- permit
|
||
- other
|
||
title:
|
||
type: string
|
||
issuer:
|
||
type: string
|
||
issueDate:
|
||
type: string
|
||
format: date
|
||
expirationDate:
|
||
type: string
|
||
format: date
|
||
status:
|
||
type: string
|
||
enum: [active, expired, revoked]
|
||
barcode:
|
||
type: string
|
||
description: PDF417 barcode data
|
||
|
||
CredentialCreate:
|
||
type: object
|
||
required:
|
||
- type
|
||
- title
|
||
- issuer
|
||
properties:
|
||
type:
|
||
type: string
|
||
title:
|
||
type: string
|
||
issuer:
|
||
type: string
|
||
issueDate:
|
||
type: string
|
||
format: date
|
||
expirationDate:
|
||
type: string
|
||
format: date
|
||
|
||
CredentialSyncRequest:
|
||
type: object
|
||
required:
|
||
- credentialId
|
||
- holderId
|
||
- credentialType
|
||
description: >
|
||
Mobile sync body for POST /api/v1/sync/credential. credentialType matches
|
||
SmoaCredentialType (canonical + legacy). payload is optional JSON validated
|
||
per docs/schemas when issuing ICAO/AAMVA/military document types.
|
||
properties:
|
||
credentialId:
|
||
type: string
|
||
holderId:
|
||
type: string
|
||
credentialType:
|
||
type: string
|
||
pattern: ^(piv_pki|payment|nfc_access|mobile|icao9303_mrtd|aamva_dlid|mil_std_129|agency_badge|id|badge|license|permit|other)$
|
||
issuer:
|
||
type: string
|
||
issuedAt:
|
||
type: integer
|
||
format: int64
|
||
expiresAt:
|
||
type: integer
|
||
format: int64
|
||
payload:
|
||
type: object
|
||
additionalProperties: true
|
||
clientUpdatedAt:
|
||
type: integer
|
||
format: int64
|
||
|
||
Order:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [authorization, assignment, search_warrant, arrest_warrant, court_order, administrative]
|
||
title:
|
||
type: string
|
||
status:
|
||
type: string
|
||
enum: [draft, pending_approval, approved, issued, executed, expired, revoked]
|
||
issuedBy:
|
||
type: string
|
||
issueDate:
|
||
type: string
|
||
format: date-time
|
||
expirationDate:
|
||
type: string
|
||
format: date-time
|
||
|
||
OrderCreate:
|
||
type: object
|
||
required:
|
||
- type
|
||
- title
|
||
properties:
|
||
type:
|
||
type: string
|
||
title:
|
||
type: string
|
||
content:
|
||
type: string
|
||
expirationDate:
|
||
type: string
|
||
format: date-time
|
||
|
||
Evidence:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
caseNumber:
|
||
type: string
|
||
description:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [physical, digital, biological, chemical, firearm, document]
|
||
collectionDate:
|
||
type: string
|
||
format: date-time
|
||
currentCustodian:
|
||
type: string
|
||
|
||
ReportRequest:
|
||
type: object
|
||
required:
|
||
- template
|
||
- format
|
||
properties:
|
||
template:
|
||
type: string
|
||
description: Report template name
|
||
format:
|
||
type: string
|
||
enum: [pdf, xml, json, csv]
|
||
parameters:
|
||
type: object
|
||
description: Template parameters
|
||
|
||
ErrorResponse:
|
||
type: object
|
||
properties:
|
||
error:
|
||
type: string
|
||
message:
|
||
type: string
|
||
code:
|
||
type: string
|
||
timestamp:
|
||
type: string
|
||
format: date-time
|
||
|