Skip to content

feat(finance): public-cloud actuals reporting prototype - #7883

Draft
wrnu wants to merge 12 commits into
mainfrom
feat/public-cloud-finance-reporting
Draft

feat(finance): public-cloud actuals reporting prototype#7883
wrnu wants to merge 12 commits into
mainfrom
feat/public-cloud-finance-reporting

Conversation

@wrnu

@wrnu wrnu commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add public-cloud finance prototype: ingest provider actuals into the registry and surface forecast-vs-actual reporting under /public-cloud/finance (snapshot, rankings, coverage, anomalies, unmatched, export), product-level Actual/Variance + FOIPPA variance notes, and Actual/Variance rows on the platform /public-cloud/forecast rollup when finance preview is on
  • Store Azure subscription IDs on products like AWS LZA accounts (azureSubscriptions + provision merge/UI portal links); finance joins prefer billingAccountLinks, then native LZA/Azure fields (classic AWS has no native account field and is out of scope for scheduled ingest)
  • Persist month-end Bank of Canada USD/CAD rates (MonthlyFxRate) for historical invoice conversion; keep archived (INACTIVE) products in finance/forecast historical rollups and ingest matching; coverage chase list stays ACTIVE-only
  • Wire Test/Prod credentials: AWS/Azure billing SPs on the app pod via Vault; Airflow DAGs only schedule/trigger ingest using Keycloak team SA client_credentials (*_FINANCE_SA_ID / *_FINANCE_SA_SECRET), same pattern as the provisioner
  • Local/Dev defaults to simulated actuals; opt-in live adapters via CLI (FINANCE_AWS_PROFILE / az login) and pnpm test:finance-live (*.live.test.ts excluded from CI)
  • Add Airflow finance ingest DAGs for dev/test/prod; pre-commit kube-linter only runs on Helm YAML/templates so Python DAGs under helm/tools/dags do not trigger full-chart lint

Test plan

  • pnpm --dir app prisma-push then pnpm --dir app seed-all-local -- --reset
  • Open /public-cloud/finance with publicCloudFinance preview on; check snapshot / rankings / unmatched / anomalies / export
  • Open /public-cloud/forecast and confirm Actual/Variance totals (and per-product rows when expanded)
  • Confirm product edit Spend forecast shows Actual/Variance + variance notes
  • Archive a product and confirm its historical spend/forecast still appear in finance and platform forecast rollups; coverage chase list should not include it
  • Confirm Azure products show portal links when azureSubscriptions are present; provision callback merges subscription IDs
  • Optional local: pnpm --dir app test:finance-live with AWS SSO / az login and FINANCE_LIVE_* env
  • Review Airflow + Vault wiring (app: AWS/Azure billing env; tools: Keycloak finance SA; previous-month schedule; DAGs paused until secrets exist)

Explicit non-goals

  • Alerts/email, chargeback, shared-cost allocation
  • Classic AWS native account storage or scheduled classic-AWS ingest
  • Billing credentials in Airflow or GitHub Actions

Ingest provider actuals for forecast-vs-actual views, store Azure
subscription IDs like LZA accounts, and persist month-end BoC FX rates.
Copilot AI lite review requested due to automatic review settings August 12, 2026 20:01
Airflow DAGs under helm/tools/dags are Python and should not trigger
full-chart kube-linter; include finance ingest DAGs in the prototype.
@wrnu wrnu self-assigned this Aug 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a prototype “Public Cloud Finance” reporting surface that ingests provider actuals, persists month-end FX rates, and exposes snapshot/rankings/coverage/anomalies/unmatched/export views under /public-cloud/finance, plus per-product Actual/Variance and FOIPPA variance notes.

Changes:

  • Adds finance ingest pipeline (simulated + opt-in live adapters), storage models (ActualSpend, rollups, flags, FX, notes), and anomaly evaluation.
  • Adds finance UI pages + export helpers, and wires product forecast UI to optionally display actuals/variance + variance notes.
  • Extends product metadata for Azure subscription identifiers and billing join links; updates provision callback and local seeding.

Reviewed changes

Copilot reviewed 65 out of 69 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
sandbox/nats-provision/main.ts Adds mock Azure subscription payload support in provision sandbox.
pnpm-lock.yaml Locks new AWS SDK dependencies and transitive updates.
docs/business-logic/public-cloud/finance-reporting.md Documents join keys, FX behavior, live ingest, and FOIPPA notes.
app/validation-schemas/cloud-cost.ts Adds finance query/body schemas (provider filters, export, anomalies, ingest, notes).
app/types/next-auth.d.ts Adds publicCloudFinance preview flag typing.
app/services/public-cloud-finance/monthly-fx-rate.ts Persists month-end USD/CAD FX rates with fallback behavior.
app/services/public-cloud-finance/ingest/types.ts Defines normalized billing line types and ingest scope.
app/services/public-cloud-finance/ingest/simulated-source.ts Implements simulated billing source for local/dev demos.
app/services/public-cloud-finance/ingest/run-ingest.ts Implements ingest run: match/unmatched, supersede, rollups, flag evaluation.
app/services/public-cloud-finance/ingest/real-sources.ts Implements opt-in live AWS Cost Explorer + Azure Cost Management adapters and JSON export fallback.
app/services/public-cloud-finance/ingest/real-sources.live.test.ts Adds local-only live integration tests for real billing adapters.
app/services/public-cloud-finance/ingest/evaluate-flags.ts Creates anomaly flags (MoM increase, over-forecast, new service line).
app/services/public-cloud-finance/finance-measure-utils.test.ts Adds unit tests for variance/formatting and billing link normalization.
app/services/public-cloud-finance/constants.ts Adds finance defaults, thresholds, preview gating helpers.
app/services/public-cloud-finance/billing-account-links.ts Adds preferred join logic via billingAccountLinks with provider fallbacks.
app/services/public-cloud-finance/active-spend.ts Adds Prisma filter to identify “active” (not superseded) spend lines in MongoDB.
app/services/exchange-rates/index.ts Adds shared exchange-rate exports and basic currency conversion helper.
app/services/db/public-cloud-finance.ts Adds DB access layer for snapshot, rankings, coverage chase list, anomalies, unmatched, notes.
app/services/bank-of-canada/usd-cad-rate.ts Adds Bank of Canada Valet client with caching + month-end parsing.
app/services/bank-of-canada/usd-cad-rate.test.ts Adds unit tests for BoC parsing and fetch URL construction/caching.
app/services/backend/public-cloud/finance.ts Adds frontend API client for finance endpoints + export download.
app/services/azure/subscriptions.ts Adds Azure subscription normalization/merge + demo subscription inventing.
app/services/azure/subscriptions.test.ts Adds tests for Azure subscription normalization and merge behavior.
app/seed/seed-finance-local.ts Adds seed script to load simulated actuals through ingest pipeline.
app/seed/seed-demo-products.ts Seeds demo billingAccountLinks + Azure subscriptions into demo products.
app/seed/seed-all-local.ts Integrates finance seeding into all-local seed flow.
app/seed/finance-ingest-live.ts Adds opt-in local CLI to ingest live billing for allowlisted plates.
app/prisma/schema.prisma Adds finance models/enums and product metadata fields (azureSubscriptions, billingAccountLinks).
app/package.json Adds scripts for finance seeds/live ingest + adds AWS SDK deps.
app/jest.setup.ts Cleans up finance collections in Jest test teardown.
app/jest.config.mjs Excludes *.live.test.* from default Jest runs (CI-safe).
app/helpers/pdfs/emou/types.ts Excludes new product metadata fields from EMOU product type.
app/helpers/mock-resources/public-cloud-request.ts Adds new metadata fields to sample public cloud request mock.
app/helpers/mock-resources/public-cloud-product.ts Adds new metadata fields to sample public cloud product mock.
app/helpers/finance-export.ts Adds XLSX/CSV export builders and content-disposition helper.
app/core/auth-options.ts Adds publicCloudFinance preview flag to session generation.
app/constants/public-cloud.ts Adds Azure subscription naming + portal URL helpers.
app/components/public-cloud/sections/PublicCloudForecastSection.tsx Conditionally fetches/threads finance actuals into forecast panel under finance preview.
app/components/public-cloud/forecast/ProjectBudgetForecastPanel.tsx Adds “Actual” + “Variance” rows and variance notes UI under finance preview.
app/components/public-cloud/finance/ProductVarianceNotes.tsx Adds FOIPPA-gated variance note entry and list UI.
app/components/public-cloud/finance/FinanceNav.tsx Adds navigation for finance prototype pages.
app/components/public-cloud/finance/finance-measure-utils.ts Adds shared finance measure helpers (variance, coverage, FY helpers, formatting).
app/components/layouts/UserMenu.tsx Adds “Public Cloud Finance” nav entry when finance preview enabled.
app/components/form/AccountEnvironmentsPublic.tsx Adds Azure portal links when azureSubscriptions are present.
app/app/public-cloud/products/(product)/[licencePlate]/edit/page.tsx Passes normalized Azure subscriptions into edit form.
app/app/public-cloud/finance/page.tsx Adds finance snapshot page UI.
app/app/public-cloud/finance/rankings/page.tsx Adds rankings page UI.
app/app/public-cloud/finance/coverage/page.tsx Adds coverage chase list UI.
app/app/public-cloud/finance/anomalies/page.tsx Adds anomaly review queue UI.
app/app/public-cloud/finance/unmatched/page.tsx Adds unmatched billing UI + resolve action.
app/app/public-cloud/finance/export/page.tsx Adds export UI for XLSX/CSV datasets.
app/app/api/v1/public-cloud/products/[idOrLicencePlate]/provision/route.ts Persists Azure subscription IDs on provision callback (merge behavior).
app/app/api/public-cloud/products/[licencePlate]/finance/route.ts Adds product finance detail endpoint (forecast/actuals/variance notes).
app/app/api/public-cloud/products/[licencePlate]/finance/variance-notes/route.ts Adds endpoint to create variance notes.
app/app/api/public-cloud/products/_operations/delete.ts Prevents copying new product-only metadata into delete request data.
app/app/api/public-cloud/finance/snapshot/route.ts Adds finance snapshot API endpoint.
app/app/api/public-cloud/finance/rankings/route.ts Adds rankings API endpoint.
app/app/api/public-cloud/finance/coverage/route.ts Adds coverage API endpoint.
app/app/api/public-cloud/finance/anomalies/route.ts Adds anomalies queue API endpoint.
app/app/api/public-cloud/finance/anomalies/[id]/review/route.ts Adds anomaly review API endpoint.
app/app/api/public-cloud/finance/unmatched/route.ts Adds unmatched billing API endpoint.
app/app/api/public-cloud/finance/unmatched/[id]/resolve/route.ts Adds resolve-unmatched API endpoint.
app/app/api/public-cloud/finance/ingest/route.ts Adds internal ingest trigger API endpoint.
app/app/api/public-cloud/finance/export/route.ts Adds finance export API endpoint (XLSX/CSV).
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (1)

app/services/public-cloud-finance/monthly-fx-rate.ts:82

  • Same concurrency issue in the FINANCE_USD_CAD_RATE fallback path: concurrent ingests for the same month can hit unique constraint errors on monthlyFxRate.create. Prefer upsert to keep the operation idempotent.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/app/api/public-cloud/products/[licencePlate]/finance/route.ts
Comment thread app/services/db/public-cloud-finance.ts Outdated
Comment thread app/services/public-cloud-finance/ingest/run-ingest.ts Outdated
Comment thread docs/business-logic/public-cloud/finance-reporting.md
Comment thread app/services/public-cloud-finance/monthly-fx-rate.ts Outdated
Comment thread app/services/public-cloud-finance/ingest/real-sources.ts
wrnu added 3 commits August 12, 2026 13:10
Reduce cognitive complexity with helpers, replace utcnow and role=status,
and clean up nested ternaries plus minor lint findings.
Enforce product forecast permissions on product finance APIs, make FX
rate writes race-safe, omit FX fields for CAD, and speed up rollups/chart.
Split product/link/service line builders so Sonar S3776 stays under the limit.
Capture Test/Prod service principal and Vault wiring for Cost Explorer
and Cost Management, separate from Airflow ingest auth.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 65 out of 69 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (1)

helm/tools/dags/_finance_ingest.py:9

  • The Airflow helper only triggers ingest for AWS_LZA and AZURE, but the registry ingest API and validation schema also support provider "AWS". Unless classic AWS is intentionally out of scope, this will leave AWS products perpetually un-ingested in test/prod runs (and provider=AWS filters will show no data).

Comment thread app/services/exchange-rates/index.ts
wrnu added 6 commits August 12, 2026 13:25
Use AWS default credential chain and Azure DefaultAzureCredential for
Test/Prod, with SSO profile / az login still supported for local live tests.
Skip rounding in convertCurrencyAmount for same-currency and zero paths
so CAD→CAD / USD→USD no longer drop cents.
Use client_credentials for Airflow ingest like the provisioner.
Include INACTIVE products in finance and forecast rollups so totals stay complete.
Extract helpers so Sonar cognitive complexity stays within the limit.
Wire spend rollups into the platform forecast page and export when finance
preview is on, and keep aggregators client-safe so Prisma stays off the browser.
Compare FYTD actual to forecast for the same elapsed months, add an FYTD
forecast card, and keep full-year forecast as planning context only.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants