Skip to content

feat(accounting): intercompany netting workbench — data model (#1058)#1239

Open
carbon-agent wants to merge 1 commit into
feature/intercompany-maturity-matchingfrom
feature/intercompany-netting
Open

feat(accounting): intercompany netting workbench — data model (#1058)#1239
carbon-agent wants to merge 1 commit into
feature/intercompany-maturity-matchingfrom
feature/intercompany-netting

Conversation

@carbon-agent

Copy link
Copy Markdown
Collaborator

What

Workstream 4 (netting) data-model foundation for intercompany maturity (issue #1058), from .ai/specs/2026-07-04-intercompany-maturity.md.

Stacked on #1224 (tolerance + FX matching). Base is feature/intercompany-maturity-matching; GitHub will retarget to main when #1224 merges. Review #1224 first.

Scope: schema only, on purpose

The consuming statement-lifecycle RPCs, accounting service functions, and workbench UI reference these new tables/columns in TypeScript, which requires regenerating packages/database/src/types.ts against a migrated local DB. The build environment for this branch has no running stack, and repo policy is to not rebuild the DB autonomously (AGENTS.md: "Never rebuild the database to test changes — wait for the user"). So this PR lands the migration + seed only — every line is SQL or pure seed data, grounded in existing precedent — and the consuming code follows once types can be regenerated. This mirrors how #1224 shipped matching without new TS-referenced DB objects.

Migration 20260725143012_intercompany-netting-foundation.sql

  • accountDefault.intercompanyNettingAccount (FK to account.id, by id per the control-account lesson) + a per-group 1135 Intercompany Netting Clearing current-asset account, seeded (sibling of 1130, parent resolved by isGroup+name+class, never by number) and backfilled. Left NULLABLE so an unset account makes the future settlement path raise, rather than posting to the wrong clearing account.
  • intercompanyNettingStatement + intercompanyNettingStatementLine — group-level, so they follow the intercompanyTransaction precedent (single-column PK, companyGroupId + explicit company columns, currencyCode a bare TEXT with no FK because a two-company row can't reference the per-company currency(code, companyId) table).
  • payment.nettingStatementId back-reference + partial index (settlement audit trail).
  • ICNS-%{yyyy}- readable sequence backfilled for existing companies + seeded in seed.data.ts for new ones.
  • RLS mirrors the intercompanyTransaction source-OR-target shape (accounting_create/update/delete). Line policies gate on the parent statement's two companies via EXISTS, fully-qualifying the line's statementId to disambiguate it from the statement's readable-number column of the same name (a bug I caught and fixed during review).

Verification

  • pnpm exec biome check on seed.data.ts — clean.
  • pnpm exec turbo run typecheck --filter=@carbon/database — passes.
  • The migration cannot be applied/db:migrate'd here (no local stack); the SQL is grounded line-for-line in 20260724100357 (the matching migration) and 20260630093809 (AR/AP payments). Please apply + regenerate types on a real stack before merge — that step also produces the types.ts update every DB PR carries.

Follow-up (still needed for #1058)

  • Netting statement-lifecycle RPCs (createNettingStatement / propose / agree / cancel) + settlement. Design note: settlement should ride the existing post-payment edge function (stage Draft payment + invoiceSettlement rows, invoke per company) rather than a self-contained settleNettingStatement RPC as the spec's RPC sketch implied — posting lives in the edge function, not an RPC. Resolve that gap when building settlement.
  • The matrix → statement-list → statement-Drawer workbench UI, and the group IC-settings form (validator already exists, unwired).
  • Workstream 3 (document mirroring) — Inngest job, cross-company writes, item-reference table, UI — entirely remaining.

Tracking spec: .ai/specs/2026-07-04-intercompany-maturity.md

🤖 Generated with Claude Code

Workstream 4 (netting) data-model foundation, stacked on the tolerance/FX
matching phase (#1224). Schema only, deliberately ahead of the consuming
RPCs/service/UI: those reference the new tables in TypeScript and require
regenerated @carbon/database types (a running local stack the build env lacks).

- accountDefault.intercompanyNettingAccount (by id) + per-group
  "1135 Intercompany Netting Clearing" current-asset account seeded (sibling of
  1130, parent resolved by isGroup+name+class) and backfilled; left NULLABLE so
  the settlement path raises rather than posting to the wrong clearing account.
- intercompanyNettingStatement + intercompanyNettingStatementLine — group-level,
  single-column PK + companyGroupId/company columns per the intercompanyTransaction
  precedent (currencyCode a bare TEXT with no FK, same reason).
- payment.nettingStatementId back-reference + partial index.
- ICNS-%{yyyy}- readable sequence backfilled for existing companies + seeded for new.
- RLS mirrors the intercompanyTransaction source-OR-target shape
  (accounting_create/update/delete); line policies gate on the parent statement's
  two companies via EXISTS, fully-qualifying the line's statementId to disambiguate
  from the statement's readable-number column of the same name.

Follow-up (needs the stack for type regen + posting verification): statement
lifecycle RPCs + settlement (rides the existing post-payment edge function, not a
self-contained RPC), the workbench UI, and workstream 3 (document mirroring).

Tracking spec: .ai/specs/2026-07-04-intercompany-maturity.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
academy Ready Ready Preview, Comment Jul 25, 2026 6:51am
carbon Ready Ready Preview, Comment Jul 25, 2026 6:51am
docs Ready Ready Preview, Comment Jul 25, 2026 6:51am
mes Ready Ready Preview, Comment Jul 25, 2026 6:51am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ee9bb884-fa55-42fb-9fdd-1a45f2106ba6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/intercompany-netting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant