Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
28 KiB
SCRATCHPAD: Complete OpenAPI Documentation Coverage
2026-04-24 — Plan Created
Branch / Worktree
- Worktree:
/Users/roberisaacs/alga-psa.worktrees/docs/api-docs-input-output - Branch:
docs/api-docs-input-output - Existing uncommitted local file to avoid:
.env.localtest
Current Progress Baseline
- Completed batches: 1–16 (80 operations).
- Latest pushed commit at plan creation:
e733631bf docs(openapi): document asset history and automation execution routes. - Remaining CE placeholder count:
488. - Progress tracker:
/tmp/alga-openapi-doc-progress.md.
Required Commands
Regenerate CE/legacy specs:
npm --prefix sdk run openapi:generate
Regenerate EE specs:
npm --prefix sdk run openapi:generate -- --edition ee
Placeholder scan pattern:
python3 - <<'PY'
import json
spec=json.load(open('sdk/docs/openapi/alga-openapi.ce.json'))
items=[]
for path, methods in spec['paths'].items():
for method, op in methods.items():
if isinstance(op,dict) and ('generated automatically' in op.get('description','') or (op.get('extensions') or {}).get('x-placeholder')):
items.append((path,method.upper(),op.get('summary')))
print('remaining', len(items))
for row in items[:50]:
print(row)
PY
Batch Workflow Decisions
- Continue in batches of 5 operations.
- Use subagents for investigation where possible.
- Preferred model:
deepseek/deepseek-v4-pro. - Investigators are read-only and should report source evidence, auth/security, tenant behavior, inputs, outputs, statuses, and ID provenance.
- Main agent writes registrars and generated specs.
- Commit/push periodically.
- Do not stage
.env.localtest.
Registrar Rules
- Put domain registrars under
server/src/lib/api/openapi/routes/. - Import/register new registrars in
server/src/lib/api/openapi/index.tsbeforeregisterInventoryBackfillRoutes. - Manual route registration key is method+path. If manual route is registered before inventory backfill, placeholder is skipped.
- Prefer actual source behavior over intended behavior when they differ.
- When source has implementation bugs, document them in descriptions/extensions rather than fixing runtime code.
Current Remaining Placeholder Domains (CE)
Total: 488 placeholders.
Top route families at plan creation:
- 37
/api/v1/integrations - 37
/api/v1/quickbooks - 37
/api/v1/webhooks - 34
/api/v1/workflows - 31
/api/v1/invoices - 29
/api/v1/financial - 26
/api/v1/users - 24
/api/v1/contract-lines - 22
/api/v1/teams - 21
/api/v1/quotes - 19
/api/v1/tags - 18
/api/v1/projects - 17
/api/v1/time-entries - 17
/api/v1/time-sheets - 14
/api/v1/automation - 14
/api/v1/categories - 12
/api/v1/tickets - 10
/api/v1/roles - 9
/api/v1/clients - 8
/api/v1/contacts - 8
/api/v1/meta - 8
/api/v1/time-periods - 7
/api/v1/permissions - 7
/api/v1/schedules - 4
/api/v1/contracts - 4
/api/v1/user - 3
/api/v1/client-contract-lines - 2
/api/v1/feature-flags - 2
/api/v1/contract-line-templates - 2
/api/v1/rbac - 1
/api/v1/billing-analytics - 1
/api/v1/feature-access - 1
/api/v1/permission-checks - 1
/api/v1/test-auth - 1
/api/v1/user-roles
Next Batch at Plan Creation
Batch 17:
GET /api/v1/automation/performanceGET /api/v1/automation/rulesPOST /api/v1/automation/rulesPOST /api/v1/automation/rules/bulk-executePOST /api/v1/automation/rules/bulk-status
Known Gotchas Discovered So Far
- Some v1 asset routes have edge middleware that checks only
x-api-keypresence, but route files lack a wrapper that setsreq.context; these routes can fail withRequest context not available. Document actual behavior. - Several controllers return v2 HATEOAS links from v1 routes. Document where observed.
- Some service methods throw generic
Errorfor not-found/invalid state, producing 500 rather than expected 404/400. Document current behavior. - Some inventory routes point to missing route files. Document as inventory-only/missing-handler rather than inventing behavior.
deepseek/deepseek-v4failed earlier;deepseek/deepseek-v4-prois the working provider-qualified model when provider balance is available.
Commit Discipline
Before every commit:
git status --short
Expected persistent unstaged file:
M .env.localtest
Do not git add .; stage exact registrar/spec/plan files only.
2026-04-24 — Batch 17 Completed (Automation Rules/Performance + Remaining Automation Family)
Scope completed
- Documented all remaining placeholder automation endpoints in
server/src/lib/api/openapi/routes/automation.ts:GET /api/v1/automation/performanceGET /api/v1/automation/rulesPOST /api/v1/automation/rulesPOST /api/v1/automation/rules/bulk-executePOST /api/v1/automation/rules/bulk-statusDELETE /api/v1/automation/rules/{id}GET /api/v1/automation/rules/{id}PUT /api/v1/automation/rules/{id}POST /api/v1/automation/rules/{id}/executeGET /api/v1/automation/statisticsGET /api/v1/automation/templatesPOST /api/v1/automation/templatesGET /api/v1/automation/templates/{id}POST /api/v1/automation/templates/{id}/use
Key source-grounded decisions (with rationale)
- Documented service/controller mismatch where
manualExecutionSchemarequiresautomation_rule_idin request body but execution uses path/rules/{id}. Kept this explicit in schema/description to avoid hiding runtime behavior. - Documented known 500-vs-404/400 gaps where
AutomationServicethrows genericErrorfor not-found or invalid-state conditions. - Documented query-array parsing gap on performance route because controller query parsing (
validateQueryParams) maps URL params to string values while schema expects arrays forrule_idsandmetrics. - Preserved tenant/RBAC metadata using base-controller auth flow (
x-api-key+ optionalx-tenant-id,hasPermissionagainst resourceautomation).
Commands / runbook executed
npm --prefix sdk run openapi:generate
npm --prefix sdk run openapi:generate -- --edition ee
python3 <placeholder scan script for CE+EE targeted automation ops + remaining counts>
Validation results
- CE targeted automation placeholder check: all 14 automation operations now non-placeholder.
- EE targeted automation placeholder check: all 14 automation operations now non-placeholder.
- Remaining placeholder counts after batch:
- CE:
474(down from 488) - EE:
482
- CE:
Updated next cursor
- Next unresolved CE operations:
GET /api/v1/billing-analytics/overviewGET /api/v1/contract-linesPOST /api/v1/contract-linesDELETE /api/v1/contract-lines/bulkPOST /api/v1/contract-lines/bulk
Gotchas reinforced
- OpenAPI registry request bodies must be registered as
request: { body: { schema: ... } }; passing the schema directly (body: Schema) causeszod-to-openapigeneration failure.
2026-04-24 — Contract Line/Template Family Completed (F002)
Scope completed
- Added new registrar:
server/src/lib/api/openapi/routes/contractLines.ts. - Imported and registered it before inventory backfill in
server/src/lib/api/openapi/index.ts. - Documented all 26 previously-placeholder operations across:
/api/v1/contract-lines/api/v1/contract-lines/{id}and subresources (activation,analytics,copy,fixed-config,services,usage-metrics)/api/v1/contract-lines/bulk+ explicit bulk subpaths/api/v1/contract-line-templates/api/v1/contract-line-templates/{id}/create-contract-line
Key decisions / discovered gaps
- These controllers depend on
requireRequestContext(req)but the global middleware only checks x-api-key presence for/api/*and does not populate request context. Documented as current auth wiring gap (x-request-context-wiring-gap). POST /api/v1/contract-lines/{id}/copycurrently usessource_contract_line_idfrom body and does not consume the path id.POST /api/v1/contract-line-templates/{id}/create-contract-linecurrently validates/uses bodytemplate_idand does not consume the path id.GET /api/v1/contract-lines/{id}/services/{serviceId}currently delegates togetContractLineServices()and returns full service list for{id};serviceIdis effectively ignored in GET behavior.
Validation results
- CE contract-line/template placeholder check: all 26 operations are non-placeholder.
- EE contract-line/template placeholder check: all 26 operations are non-placeholder.
- Remaining placeholders after this pass:
- CE:
448 - EE:
456
- CE:
Commands executed
npm --prefix sdk run openapi:generate
npm --prefix sdk run openapi:generate -- --edition ee
python3 <targeted CE/EE contract-line placeholder checks + global counts>
Next cursor (CE)
GET /api/v1/billing-analytics/overviewGET /api/v1/categories/analyticsPOST /api/v1/categories/bulk/deleteGET /api/v1/categories/searchDELETE /api/v1/categories/service/{id}
2026-04-24 — Category Family Completed (F003)
Scope completed
- Extended
server/src/lib/api/openapi/routes/serviceCategories.tsto document all previously-placeholder category operations:GET /api/v1/categories/analyticsPOST /api/v1/categories/bulk/deleteGET /api/v1/categories/searchDELETE|GET|PUT /api/v1/categories/service/{id}GET|POST /api/v1/categories/ticketPOST /api/v1/categories/ticket/moveGET /api/v1/categories/ticket/treeGET /api/v1/categories/ticket/tree/{boardId}DELETE|GET|PUT /api/v1/categories/ticket/{id}
Key source-grounded notes
- Permission resource is dynamic for search/analytics/bulk delete endpoints (
billing_settingsfor service categories,ticket_settingsotherwise). GET /api/v1/categories/ticket/treecurrently derives board id from URL last segment; on this route it passes literaltreeto service (implementation quirk documented).- Tree-by-board route currently works because the final path segment is the board id, even though controller still parses from URL rather than params.
Validation
- CE category placeholder set: all targeted operations are non-placeholder.
- EE category placeholder set: all targeted operations are non-placeholder.
- Remaining placeholder counts after this pass:
- CE:
434 - EE:
442
- CE:
Next cursor (CE)
GET /api/v1/billing-analytics/overviewGET /api/v1/clientsPOST /api/v1/clientsGET /api/v1/clients/statsDELETE /api/v1/clients/{id}
2026-04-24 — Client/Contact Family Completed (F004)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/clientsContacts.ts. - Registered in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all 20 previously-placeholder operations under:
/api/v1/clients*/api/v1/contacts*/api/v1/client-contract-lines*
Key source-grounded notes
- Client/contact custom routes (
stats,search,export, nested client subresources) perform explicit API key validation in-controller and set request context directly. - Client-contract-line routes reuse
ApiContractLineControllerrequest-context-dependent methods; documented current request-context wiring gap and TODO-stub behavior for list endpoint. - Contact export can return CSV file response when
format=csv; documented this response-mode distinction.
Validation
- CE placeholder check for the full client/contact/client-contract-line set: all operations are non-placeholder.
- EE placeholder check for the same set: all operations are non-placeholder.
- Remaining placeholder counts after this pass:
- CE:
414 - EE:
422
- CE:
Next cursor (CE)
GET /api/v1/billing-analytics/overviewPOST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsPOST /api/v1/financial/billing/calculate
2026-04-24 — Financial/Invoice/Billing-Analytics Family Completed (F005)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/financialInvoices.ts. - Registered in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder operations under:
/api/v1/billing-analytics/overview/api/v1/financial/*/api/v1/invoices/*
Key source-grounded decisions / gaps documented
GET /api/v1/billing-analytics/overviewmaps toApiContractLineController.getBillingOverviewAnalytics()and currently requiresreq.contextwithout route-level auth wiring; documentedx-request-context-wiring-gap.- Multiple
/api/v1/financial/*routes are currently wired to genericApiFinancialController.list/create/update/getById/deletemethods (transaction-oriented) rather than route-name-specific resources (payment-methods,tax/rates,financial/invoices/{id}/*); documented as route-to-controller mismatches. POST /api/v1/financial/bulk/transactionsandPOST /api/v1/financial/bulk/creditscurrently return501 Not implemented; documented as implementation gaps.- Recurring invoice template routes include TODO stubs (
listreturns empty array,updatesynthetic response,deletedirect 204); documented explicitly. GET /api/v1/invoices/{id}/pdfreturns redirect behavior (307) whendownload_urlexists; documented as redirect endpoint.
Validation / tests completed in this pass
T001completed: CE placeholder scan for the F005 route family (ce_f005_remaining = 0).T002completed: EE placeholder scan for the same family (ee_f005_remaining = 0).T003completed:npm --prefix sdk run openapi:generatesucceeded.T004completed:npm --prefix sdk run openapi:generate -- --edition eesucceeded.T005completed: verifiedregisterFinancialInvoiceRoutes()is imported and called inopenapi/index.tsbeforeregisterInventoryBackfillRoutes().
Remaining placeholder counts after this pass
- CE:
353 - EE:
361
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/integrations/quickbooks/accountsGET /api/v1/integrations/quickbooks/accounts/mappings
Commands / runbook executed
npm --prefix sdk run openapi:generate
npm --prefix sdk run openapi:generate -- --edition ee
python3 <CE and EE placeholder scans for F005 family + global counts>
2026-04-24 — QuickBooks Duplicate Families Completed (F006)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/quickbooksV1.ts. - Registered in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder routes in both v1 QuickBooks families:
/api/v1/integrations/quickbooks/*/api/v1/quickbooks/*
Alias verification (T008)
- Verified both families map method-for-method to the same
ApiQuickBooksControllerhandler methods. - Distinction documented in operation descriptions/extensions:
/api/v1/integrations/quickbooks/*: route files generally wrap controller calls in explicittry/catchwithhandleApiError./api/v1/quickbooks/*: route files generally bind controller handlers directly (export const GET = controller.method()).
- Since controller methods already return
handleApiErroron failure, current runtime behavior is functionally aliased despite route-wrapper style differences.
Key source-grounded implementation notes captured
- Controller authenticates via
x-api-key+ optionalx-tenant-id, then RBAC checks against resourcequickbookswith actionsread|write|admin. - Multiple handler methods intentionally return temporary/stub payloads or TODO behavior (for example connection refresh, mapping deletes, sync cancel, account/tax mapping reads); these gaps are called out in descriptions.
Validation / tests completed in this pass
T003andT004rerun successfully:npm --prefix sdk run openapi:generatenpm --prefix sdk run openapi:generate -- --edition ee
T008completed:- CE QuickBooks placeholder check:
ce_quickbooks_remaining = 0 - EE QuickBooks placeholder check:
ee_quickbooks_remaining = 0
- CE QuickBooks placeholder check:
Remaining placeholder counts after this pass
- CE:
279 - EE:
287
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/quotesPOST /api/v1/quotes
2026-04-24 — Webhook Family Completed (F007)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/webhooks.ts. - Registered in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder webhook routes under
/api/v1/webhooks*(37 operations).
Key source-grounded wiring notes documented
/api/v1/webhooks/searchroute currently callsApiWebhookController.list()(notsearch()); documented as route-to-controller mismatch./api/v1/webhooks/templates/{id}GET|PUT|DELETEroutes currently call generic webhookgetById|update|deletemethods; documented as template-route wiring mismatch.- Global subscription routes (
/api/v1/webhooks/subscriptionsGET|POST) call methods that require webhook{id}path extraction; current behavior yields UUID validation failure for literalsubscriptionspath segment. - Several controller paths intentionally return stub/TODO responses (health checks, validation, secret rotation, template/subscription helpers, delivery detail helpers); these are explicitly called out in descriptions/extensions.
Validation results
- CE webhook placeholder check:
ce_webhooks_remaining = 0. - EE webhook placeholder check:
ee_webhooks_remaining = 0. - Regeneration commands succeeded:
npm --prefix sdk run openapi:generatenpm --prefix sdk run openapi:generate -- --edition ee
Remaining placeholder counts after this pass
- CE:
242 - EE:
250
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/quotesPOST /api/v1/quotes
2026-04-24 — Workflow Family Completed (F008)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/workflowsV1.ts. - Registered in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder
/api/v1/workflows*operations (34 routes).
Source-grounded findings and decisions
- There are no
server/src/app/api/v1/workflows/**/route.tshandlers in this worktree. - The inventory placeholders for
/api/v1/workflows*were documented explicitly as inventory-only/missing-handler routes rather than inventing behavior. - Descriptions now point to existing workflow APIs under
/api/workflow-definitions,/api/workflow-runs, and/api/workflow/eventsto avoid ambiguity.
Validation / tests completed in this pass
- CE workflow placeholder check:
ce_workflows_remaining = 0. - EE workflow placeholder check:
ee_workflows_remaining = 0. - Regeneration commands succeeded:
npm --prefix sdk run openapi:generatenpm --prefix sdk run openapi:generate -- --edition ee
T009completed by documenting webhook family security/payload behavior and workflow family missing-handler reality with security/missing-route behavior.
Remaining placeholder counts after this pass
- CE:
208 - EE:
216
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/quotesPOST /api/v1/quotes
2026-04-24 — Access Control/User/Role/Permission/Team Families Completed (F009)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/accessControlUsers.ts. - Registered it in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder operations across:
/api/v1/users*/api/v1/user-roles/api/v1/roles*/api/v1/permissions*/api/v1/permission-checks/api/v1/rbac/*/api/v1/teams*
Key source-grounded notes / gaps documented
GET /api/v1/rbac/auditis currently a hardcoded 501 stub route and does not call an RBAC controller.POST /api/v1/users/bulk/createcurrently delegates toApiUserController.create()(single-user schema/behavior), not bulk-create logic.PUT /api/v1/users/bulk/deactivatecurrently delegates toApiUserController.update()and fails UUID path extraction because the route segmentbulkis treated as{id}.POST /api/v1/users/{id}/teamscurrently delegates toApiUserController.create()(create-user behavior), not team membership creation.DELETE /api/v1/users/{id}/teams/{teamId}currently delegates toApiUserController.delete();teamIdis ignored and operation acts on user id.GET /api/v1/teams/hierarchycurrently parses team id from URL tail and uses literalhierarchyas id on this route.DELETE /api/v1/teams/{id}/permissions/{permissionId}revokes by permission id and does not use team id in service call.
Validation
- CE F009 placeholder check:
ce_f009_remaining = 0. - EE F009 placeholder check:
ee_f009_remaining = 0. - Regeneration commands succeeded:
npm --prefix sdk run openapi:generatenpm --prefix sdk run openapi:generate -- --edition ee
Remaining placeholder counts after this pass
- CE:
139 - EE:
147
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/quotesPOST /api/v1/quotes
2026-04-24 — Project/Ticket/Tag/Schedule/Time Families Completed (F010)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/workManagementV1.ts. - Registered it in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder operations across:
/api/v1/projects*/api/v1/tickets*/api/v1/tags*/api/v1/schedules*/api/v1/time-entries*/api/v1/time-sheets*/api/v1/time-periods*
Key source-grounded notes / wiring gaps documented
GET /api/v1/schedules/searchandGET /api/v1/schedules/{id}/conflictscurrently delegate toApiTimeSheetController.list().GET /api/v1/schedules/{id}currently delegates toApiTimeSheetController.getById()(time-sheet read path) instead of schedule-specific getter.GET /api/v1/time-periods/currentcurrently delegates toApiTimeSheetController.list().POST /api/v1/time-periods/{id}/closeand/reopencurrently delegate toApiTimeSheetController.update()(time-sheet update path).- Several time-sheet subroutes are currently wired to generic handlers rather than route-intent-specific methods:
POST /api/v1/time-sheets/bulk->list()GET /api/v1/time-sheets/search->list()POST /api/v1/time-sheets/{id}/add-entry->create()GET /api/v1/time-sheets/{id}/entries->list()POST /api/v1/time-sheets/{id}/reject->update()DELETE /api/v1/time-sheets/{id}/remove-entry->delete()GET /api/v1/time-sheets/{id}/summary->list()
Validation
- CE F010 placeholder check:
ce_f010_remaining = 0. - EE F010 placeholder check:
ee_f010_remaining = 0. - Regeneration commands succeeded:
npm --prefix sdk run openapi:generatenpm --prefix sdk run openapi:generate -- --edition ee
Remaining placeholder counts after this pass
- CE:
41 - EE:
49
Next cursor (CE)
POST /api/v1/feature-accessGET /api/v1/feature-flagsPOST /api/v1/feature-flagsGET /api/v1/quotesPOST /api/v1/quotes
2026-04-24 — Quotes/Contracts + Meta/Utility Families Completed (F011, F012)
Scope completed
- Added registrar:
server/src/lib/api/openapi/routes/quotesContractsV1.ts. - Added registrar:
server/src/lib/api/openapi/routes/metaUtilityV1.ts. - Added registrar:
server/src/lib/api/openapi/routes/eeInventoryOnly.ts(EE-only inventory placeholders). - Registered all three in
server/src/lib/api/openapi/index.tsbefore inventory backfill. - Documented all previously-placeholder operations under:
/api/v1/quotes*/api/v1/contracts*/api/v1/feature-access/api/v1/feature-flags/api/v1/meta/*/api/v1/test-auth/api/v1/user/telemetry-*- EE-only inventory placeholders:
/api/ext-bundles/*/api/extensions/install-info/api/extensions/registry-db-check/api/extensions/reprovision/api/provisioning/tenants/api/v1/auth/verify
Key source-grounded notes / gaps documented
- Quote read authorization uses billing-resource authorization context in
ApiQuoteController.assertQuoteReadAllowed()while controller CRUD permissions are checked onquoteresource; documented this distinction. - Contract v1 routes currently mount
ApiContractLineController(v2 controller) and callrequireRequestContext(req); documented request-context wiring dependency/gap on those paths. - Feature flag and telemetry routes are session-oriented (
getSession/getCurrentUser) while global/api/*middleware can still require API key presence unless path is explicitly skipped; documented as mixed auth behavior. - EE-only placeholder paths that have no handler files in this worktree were converted to explicit inventory-only route docs instead of leaving generated placeholders.
2026-04-24 — Final Validation and Closeout (F013–F024, T006–T012)
Final placeholder results
- CE full scan:
0placeholders. - EE full scan:
0placeholders.
Representative auth/RBAC verification (T006)
Reviewed representative read/mutation flows across major API-key v1 domains and confirmed docs align with source behavior:
- User domain:
- Read:
ApiUserController.stats()/getPermissions()enforcehasPermission(..., 'user', 'read', ...). - Mutation:
assignRoles()/changePassword()enforce update checks and contextual constraints.
- Read:
- Team domain:
- Read:
ApiTeamController.getMembers()enforcesteam:read. - Mutation:
addMember()enforcesteam:update.
- Read:
- Project domain:
- Read:
ApiProjectController.list()/search()/stats()enforce read checks and authorization filtering. - Mutation:
bulkUpdate()/createPhaseTask()enforce update checks.
- Read:
- Ticket domain:
- Read:
ApiTicketController.list()/stats()enforce read checks. - Mutation:
updateStatus()/updateAssignment()enforce update checks.
- Read:
Representative billing/financial/invoice verification (T007)
Re-validated representative endpoints in server/src/lib/api/openapi/routes/financialInvoices.ts against source-backed request/response behavior:
POST /api/v1/financial/billing/calculate: request body schema registered and required underrequest.body.schema; response envelope documented as API success/error.- Invoice lifecycle request schemas (
InvoiceSendBody,InvoiceFinalizeBody,InvoicePaymentBody, bulk schemas) are registered and attached to route request bodies. - Financial/invoice responses retain documented envelope patterns (
ApiSuccess/ApiPaginated/ error structure) and known implementation-gap notes from earlier F005 work.
Commit/staging discipline verification (T010)
- Before each commit in this pass,
git status --shortconfirmed.env.localtestremained unstaged while intended plan/registrar/spec files were staged explicitly.
Plan consistency review (T012)
Reviewed final alignment among:
PRD.mdfeatures.jsontests.jsonSCRATCHPAD.md/tmp/alga-openapi-doc-progress.md
Result: all tracked workstreams and acceptance checkpoints are synchronized with final generated OpenAPI state (CE/EE placeholder scans at zero).
Final summary of discovered implementation gaps (F024)
Representative deferred runtime issues captured in OpenAPI docs instead of code fixes:
- Route-to-controller mismatches on several v1 legacy paths (notably some user/team/time-period/time-sheet/schedule routes).
- Session-vs-API-key mixed auth behavior on feature flag and telemetry endpoints.
- Contract v1 routes using v2 controller assumptions (
requireRequestContext). - Inventory-only EE paths with missing handlers documented as such.
No runtime behavior changes were made as part of this documentation pass.