seahaven-ap/packages/api/openapi/components/schemas.yaml
Adam Moussa 864531b51e
feat(api): portal contract, cookie auth, and domain stubs (AP-51) (#64)
* feat(api): serve portal-shaped health and error envelope

Move liveness to GET /api/health { stage, sha } with a Node 24 image on 8080 so ALB probes and deploy verify do not need auth or a database ping.

* feat(api): switch live auth to host cookie BFF

Replace Bearer as the documented session path with Cognito hosted UI plus __Host-ap_* cookies so the SPA can call /api with credentials include.

* feat(web): add unused cookie SPA API client

Land a credentials-include fetch helper and hand-synced health/me types without wiring pages or domain hooks, so mocks stay the default data path.

* feat(api): add master-data OpenAPI and Hono stubs

* feat(api): add invoice, line, and document stubs

* feat(api): add approval policy, inbox, and activity stubs

* test(web): fix SPA client fetch mock types

* test(web): cast fetch mock call args for tsc

* fix(api): do not default DEV_AUTH_BYPASS outside local migrate

* fix(api): replace invoice lines in a single transaction

* fix(api): create invoices and lines in one transaction

* fix(api): inline GIT_SHA from the image build arg

* fix(api): stop PATCH from skipping the approval workflow

* fix(api): address review feedback

* fix(ci): format upsert-user test

* fix(api): document only the auth statuses the routes return

* fix(api): drop health 400 responses the routes never return
2026-09-25 22:43:44 +00:00

486 lines
12 KiB
YAML

Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
- correlationId
properties:
code:
type: string
description: Machine-readable error code.
example: NOT_FOUND
message:
type: string
description: Human-readable error message.
example: Not found.
correlationId:
type: string
description: Request correlation identifier echoed from x-correlation-id when present.
example: 11111111-1111-4111-8111-111111111111
HealthResponse:
type: object
required:
- stage
- sha
properties:
stage:
type: string
description: Deployment stage name.
example: local
sha:
type: string
description: Git SHA inlined at image build.
example: deadbeef
ReadyResponse:
type: object
required:
- status
- database
properties:
status:
type: string
description: Process readiness marker.
example: ok
database:
type: string
description: Database ping result.
example: up
MeResponse:
type: object
required:
- id
- email
- name
- role
properties:
id:
type: string
format: uuid
description: Internal user primary key.
example: 11111111-1111-4111-8111-111111111111
email:
type: string
format: email
description: Caller email address.
example: admin@seahavenind.com
name:
type: string
description: Display name for the caller.
example: Dev Admin
role:
type: string
description: Authorization role for RBAC checks.
enum:
- admin
- ap_processor
- approver
- viewer
example: admin
Vendor:
type: object
required:
- id
- name
- defaultPaymentMethod
- createdAt
- updatedAt
properties:
id:
type: string
format: uuid
description: Vendor primary key.
example: 55555555-5555-4555-8555-555555555555
name:
type: string
description: Vendor display name.
example: Acme Facilities Supply
email:
type: [string, "null"]
description: Billing email when present.
example: billing@acmefacilities.example
defaultPaymentMethod:
type: string
enum: [check, ach]
description: Default payment method for new invoices.
example: check
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
GlAccount:
type: object
required: [id, code, name, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
description: GL account primary key.
example: 66666666-6666-4666-8666-666666666666
code:
type: string
description: Account code.
example: "6100"
name:
type: string
description: Account name.
example: Facilities Expense
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
Department:
type: object
required: [id, code, name, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
description: Department primary key.
example: 77777777-7777-4777-8777-777777777777
code:
type: string
description: Department code.
example: OPS
name:
type: string
description: Department name.
example: Operations
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
User:
type: object
required: [id, email, name, role, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
description: User primary key.
example: 11111111-1111-4111-8111-111111111111
email:
type: string
format: email
description: User email address.
example: admin@seahavenind.com
name:
type: string
description: Display name.
example: Dev Admin
role:
type: string
enum: [admin, ap_processor, approver, viewer]
description: Authorization role.
example: admin
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
Invoice:
type: object
required:
- id
- vendorId
- invoiceNumber
- amount
- amountDue
- dueDate
- status
- paymentMethod
- memo
- createdAt
- updatedAt
- lines
properties:
id:
type: string
format: uuid
description: Invoice primary key.
example: 88888888-8888-4888-8888-888888888888
vendorId:
type: string
format: uuid
description: Vendor foreign key.
example: 55555555-5555-4555-8555-555555555555
invoiceNumber:
type: string
description: Vendor-issued invoice number.
example: INV-1001
amount:
type: string
description: Invoice total as numeric(14,2) text.
example: "1250.00"
amountDue:
type: string
description: Remaining amount due as numeric(14,2) text.
example: "1250.00"
dueDate:
type: string
description: Due date as YYYY-MM-DD.
example: "2026-09-01"
payDate:
type: [string, "null"]
description: Optional pay date as YYYY-MM-DD.
example: "2026-09-15"
sendPaymentOn:
type: [string, "null"]
description: Optional send date as YYYY-MM-DD.
example: "2026-09-10"
status:
type: string
enum: [pending_approval, approved, scheduled, paid, rejected, void]
description: Invoice workflow status.
example: pending_approval
paymentMethod:
type: string
enum: [check, ach]
description: Payment method for this invoice.
example: check
memo:
type: string
description: Free-form memo.
example: Seed invoice for local smoke.
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
lines:
type: array
description: Coding lines attached to the invoice.
items:
$ref: "#/InvoiceLine"
InvoiceLine:
type: object
required: [id, invoiceId, description, amount, createdAt]
properties:
id:
type: string
format: uuid
description: Line primary key.
example: 99999999-9999-4999-8999-999999999999
invoiceId:
type: string
format: uuid
description: Parent invoice id.
example: 88888888-8888-4888-8888-888888888888
description:
type: string
description: Line description.
example: Monthly maintenance
amount:
type: string
description: Line amount as numeric(14,2) text.
example: "1250.00"
glAccountId:
type: [string, "null"]
format: uuid
description: Optional GL account id.
departmentId:
type: [string, "null"]
format: uuid
description: Optional department id.
createdAt:
type: string
format: date-time
description: Row creation time.
Document:
type: object
required: [id, objectKey, contentType, fileName, createdAt]
properties:
id:
type: string
format: uuid
description: Document primary key.
example: dddddddd-dddd-4ddd-8ddd-dddddddddddd
invoiceId:
type: [string, "null"]
format: uuid
description: Parent invoice id when attached.
objectKey:
type: string
description: Object key in the documents bucket.
example: seed/inv-1001.pdf
contentType:
type: string
description: Uploaded object MIME type.
example: application/pdf
fileName:
type: string
description: Original file name.
example: inv-1001.pdf
uploadedByUserId:
type: [string, "null"]
format: uuid
description: User who started the upload.
createdAt:
type: string
format: date-time
description: Row creation time.
uploadUrl:
type: string
description: Presigned PUT URL returned on create.
uploadHeaders:
type: object
additionalProperties:
type: string
description: Headers the browser must send with the presigned PUT.
downloadUrl:
type: string
description: Presigned GET URL returned on confirm or get.
ApprovalPolicy:
type: object
required: [id, name, priority, active, createdAt, updatedAt]
properties:
id:
type: string
format: uuid
description: Policy primary key.
example: cccccccc-cccc-4ccc-8ccc-cccccccccccc
name:
type: string
description: Policy display name.
example: Default approver policy
priority:
type: integer
description: Lower numbers match first.
example: 10
amountThreshold:
type: [string, "null"]
description: Minimum invoice amount that matches this policy.
example: "0.00"
skipBelowAmount:
type: [string, "null"]
description: Amounts below this skip the approval step.
example: "25.00"
active:
type: boolean
description: Whether the policy is considered when matching.
example: true
createdAt:
type: string
format: date-time
description: Row creation time.
updatedAt:
type: string
format: date-time
description: Row update time.
ApprovalStep:
type: object
required: [id, invoiceId, stepOrder, approverRole, status, createdAt]
properties:
id:
type: string
format: uuid
description: Step primary key.
example: eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee
invoiceId:
type: string
format: uuid
description: Parent invoice id.
policyId:
type: [string, "null"]
format: uuid
description: Policy that created the step.
stepOrder:
type: integer
description: Order within the invoice.
example: 1
approverRole:
type: string
enum: [admin, ap_processor, approver, viewer]
description: Role allowed to act when no assignee is set.
example: approver
assigneeUserId:
type: [string, "null"]
format: uuid
description: Optional assigned user.
status:
type: string
enum: [pending, approved, rejected, skipped]
description: Step status.
example: pending
actedByUserId:
type: [string, "null"]
format: uuid
description: User who acted.
actedAt:
type: [string, "null"]
format: date-time
description: When the step was acted on.
createdAt:
type: string
format: date-time
description: Row creation time.
InvoiceComment:
type: object
required: [id, invoiceId, body, createdAt]
properties:
id:
type: string
format: uuid
description: Comment primary key.
invoiceId:
type: string
format: uuid
description: Parent invoice id.
authorUserId:
type: [string, "null"]
format: uuid
description: Author user id.
body:
type: string
description: Comment text.
example: Looks good.
createdAt:
type: string
format: date-time
description: Row creation time.
ActivityLog:
type: object
required: [id, invoiceId, message, createdAt]
properties:
id:
type: string
format: uuid
description: Activity row primary key.
invoiceId:
type: string
format: uuid
description: Parent invoice id.
actorUserId:
type: [string, "null"]
format: uuid
description: Actor user id.
message:
type: string
description: Activity message.
example: Step approved.
createdAt:
type: string
format: date-time
description: Row creation time.