InfraNotes Project Finance · v0
Welcome
Select a document from the sidebar to read it.
Project Finance — Release 0 Canonical API
- Jira:
INFT-72 - Source of truth: this file. Frozen contract for the Release 0 frontend cutover.
- Owner:
infranotes-project-finance - Gateway entitlements:
business_financial,business_accounting - Tenant-aware: yes, enforced at the data layer via RLS
- Idempotency-Key required on POST/PUT/PATCH/DELETE per gateway manifest
Authentication contract
- Issuer:
https://iam.staging.infranotes.io(staging) - Audience:
infranotes-project-finance - JWKS:
https://iam.staging.infranotes.io/.well-known/jwks.json - Trust profile: B (gateway-forwarded headers in production, direct JWT validation in local dev)
- Canonical IAM
roles[]are translated bymapCoreRoleToFinanceRoleto PF native roles. Coverage:
| IAM role-template | PF role | Project access scope |
|---|---|---|
tenant_admin |
system_admin |
All projects |
admin |
system_admin |
All projects |
finance_manager |
project_manager |
Assigned projects (RLS) |
manager |
project_manager |
Assigned projects (RLS) |
accountant |
finance_analyst |
All projects (read-only) |
analyst |
finance_analyst |
All projects (read-only) |
user |
team_member |
Assigned projects (RLS) |
premium |
team_member |
Assigned projects (RLS) |
readonly |
client_viewer |
Assigned projects (RLS) |
Read-model endpoints (canonical Release 0 surface)
These are the endpoints the frontend should consume to populate project-finance pages without browser-side multi-service stitching.
Project CRUD
POST /api/project-finance— create project (Idempotency-Key required)GET /api/project-finance— list, paginatedGET /api/project-finance/{id}— single projectPUT /api/project-finance/{id}— update (Idempotency-Key required)DELETE /api/project-finance/{id}— delete (Idempotency-Key required)
Project read models
GET /api/project-finance/{id}/command-center— command-center workspace dataGET /api/project-finance/{id}/billing— billing workspace, invoice resolution server-sideGET /api/project-finance/{id}/operations— operations workspace, team resolution server-side. Degrades gracefully when the upstreamInfra_Notesavailable-users call fails: returns the read model withavailable_users: [], team members withoutname/emailenrichment,degraded: true, anddegraded_sources: ["infra_notes_available_team_users"], so the workspace stays usable while Infra_Notes service-to-service auth is being hardened (Profile B/C cutover). The degradation is logged atWARNwithproject_finance_id,tenant_id, and the upstream error.GET /api/project-finance/{id}/activity— server-filtered activity feed (limit,offset)
Portfolio read models
GET /api/project-finance/portfolio/overview— portfolio overviewGET /api/project-finance/portfolio/dashboard— supports filters:status,billing_model,currency,client,team; includes dashboard source freshness metadata infreshness,degraded, anddegraded_reasonsGET /api/project-finance/portfolio/capacity— capacity rollupsGET /api/project-finance/migration-validation/reconciliation— Release 5 reconciliation facts for portfolio controls and milestone billing validation
Dashboard read model freshness
GET /api/project-finance/project/{id}/dashboardandGET /api/project-finance/portfolio/dashboardexpose first-class freshness metadata.- Freshness rows include
source,state,observed_count,latest_at, andage_seconds. stateisfresh,stale, ormissing; sources becomestaleafter 72 hours.degraded=truemeans one or more dashboard sources are stale or missing; usedegraded_reasonsfor machine-readable details in<source>:<state>form.
Migration-validation reconciliation
GET /api/project-finance/migration-validation/reconciliationexposesdata.factsforportfolio_projectsandmilestones.- Money facts include exact
amount_minor, major-unit stringamount, andcurrency. - Count facts include integer
count. - Freshness uses the same
fresh,stale, andmissingsemantics as dashboard freshness. Mixed-currency portfolio totals setdegraded=truewithportfolio_projects:mixed_currency.
Analytics (PF-owned)
GET /api/analytics/portfolio— owner: PF (post-INFT-80 manifest correction)POST /api/analytics/projects/{id}/forecastGET /api/analytics/projects/{id}/health
Compliance and export
GET /api/compliance/reports/audit-trailGET /api/compliance/reports/gdprGET /api/compliance/reports/sox-404POST /api/export
Frontend handoff guidance
- The browser must not stitch project finance pages by calling
Infra_Notes(invoices) andinfranotes-financial-intelligence(budgets) directly. Use the read-model endpoints above. - The deprecated route families
/api/phases/**,/api/team/**,/api/scope-changes/**,/api/audit-trail/**,/api/milestones/**,/api/cost-centers/**,/api/approvals/**are scheduled to sunset on2026-07-31per the gateway ownership manifest. Migrate consumers under/api/project-finance/**before that date.
Out of scope for Release 0
- Vertical-specific overlays (per Jira INFT-72: not before generic project-finance core is excellent).
- Vendor, payroll, asset, or core-ledger feature breadth — those stay in their own service tickets.
- Frontend implementation. The PF role of this document is to freeze the contract; the FE migration off legacy paths happens under
INFT-66.
Acceptance evidence
Evidence supporting the Release 0 acceptance gates is appended to TEST_LOG.md and the workspace RELEASE_0_HANDOFF_SUMMARY.md. Required gate checks:
- canonical IAM roles
accountantandanalystresolve to a defined PF role and pass RBAC checks (regression offinance_analystundefined-role bug) - one authenticated happy path against a read-model endpoint via the gateway
- one negative path: missing token returns
401 - one negative path: missing
Idempotency-Keyon a write returns428