Files
cross-financial-management/.eslintrc.json
T
Joshua OosthuizenandClaude Sonnet 5 4acbc03b35 Initial commit: multi-company financial management system
Root company app (src/, client/) — GL foundation, AR, and AP:
- Segmented Chart of Accounts (Sage 300-style), double-entry PostingService with
  three-layer balance enforcement (app validation, CHECK constraints, deferred
  DB trigger), gap-free document numbering, RBAC with branch restrictions.
- Accounts Receivable: Customers, Invoices, Credit Notes, Receipts with
  allocation, all posting through PostingService.
- Accounts Payable: Suppliers, Supplier Invoices, Debit Notes, Payments with
  allocation, mirroring AR's posting pattern.
- Tax Codes shared between AR and AP.
- Company-app login is a token handoff from the Account Manager (RS256,
  single-use, company-scoped) rather than a local password.
- Frontend reskinned to the approved mockup: navy sidebar, dashboard, tree-view
  Chart of Accounts, Customer/Supplier 360 pages.

Account Manager (manager/, manager/client/) — central login gateway:
- Password + TOTP 2FA + Google/Microsoft OAuth, company picker, and the RS256
  handoff token issuance that the company app verifies.

Covered by unit + integration tests against a real Postgres database (GL
balance invariants, AR/AP posting correctness and allocation limits, the full
handoff exchange including replay/cross-company/expiry/forgery rejection).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tq2DbEvzHzs13jDFhLaX44
2026-09-03 13:27:19 +02:00

47 lines
1.5 KiB
JSON

{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "import"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"env": {
"node": true,
"es2022": true,
"jest": true
},
"rules": {
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.property.name='journalEntry'][callee.property.name=/^(create|createMany|createManyAndReturn|update|updateMany|upsert|delete|deleteMany)$/]",
"message": "Only src/modules/gl/posting.service.ts may write JournalEntry rows. Build a JournalEntryDraft and call PostingService.postEntry()/reverseEntry() instead."
},
{
"selector": "CallExpression[callee.object.property.name='journalEntryLine'][callee.property.name=/^(create|createMany|createManyAndReturn|update|updateMany|upsert|delete|deleteMany)$/]",
"message": "Only src/modules/gl/posting.service.ts may write JournalEntryLine rows. Build a JournalEntryDraft and call PostingService.postEntry()/reverseEntry() instead."
}
]
},
"overrides": [
{
"files": ["src/modules/gl/posting.service.ts"],
"rules": {
"no-restricted-syntax": "off"
}
},
{
"files": ["tests/integration/posting.balance.spec.ts"],
"rules": {
"no-restricted-syntax": "off"
}
}
]
}