@fin.cx/skr 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.smartconfig.json +33 -6
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/core/core.accountpolicy.d.ts +67 -0
  4. package/dist_ts/core/core.accountpolicy.js +91 -0
  5. package/dist_ts/core/core.bukeys.d.ts +38 -0
  6. package/dist_ts/core/core.bukeys.js +117 -0
  7. package/dist_ts/core/core.datev.captions.d.ts +7 -0
  8. package/dist_ts/core/core.datev.captions.js +134 -0
  9. package/dist_ts/core/core.datev.d.ts +47 -0
  10. package/dist_ts/core/core.datev.js +129 -0
  11. package/dist_ts/core/core.hash.d.ts +27 -0
  12. package/dist_ts/core/core.hash.js +72 -0
  13. package/dist_ts/core/core.plugins.d.ts +3 -0
  14. package/dist_ts/core/core.plugins.js +9 -0
  15. package/dist_ts/core/core.recipes.d.ts +118 -0
  16. package/dist_ts/core/core.recipes.js +504 -0
  17. package/dist_ts/core/core.taxscenario.d.ts +27 -0
  18. package/dist_ts/core/core.taxscenario.js +85 -0
  19. package/dist_ts/core/core.types.d.ts +48 -0
  20. package/dist_ts/core/core.types.js +2 -0
  21. package/dist_ts/core/core.validate.d.ts +17 -0
  22. package/dist_ts/core/core.validate.js +89 -0
  23. package/dist_ts/core/index.d.ts +15 -0
  24. package/dist_ts/core/index.js +16 -0
  25. package/dist_ts/index.d.ts +15 -0
  26. package/dist_ts/index.js +10 -1
  27. package/dist_ts/plugins.d.ts +2 -1
  28. package/dist_ts/plugins.js +4 -2
  29. package/dist_ts/skr.api.d.ts +91 -22
  30. package/dist_ts/skr.api.js +357 -42
  31. package/dist_ts/skr.balances.d.ts +28 -0
  32. package/dist_ts/skr.balances.js +96 -0
  33. package/dist_ts/skr.classes.journalentry.d.ts +19 -3
  34. package/dist_ts/skr.classes.journalentry.js +67 -4
  35. package/dist_ts/skr.classes.reports.js +49 -102
  36. package/dist_ts/skr.database.d.ts +2 -0
  37. package/dist_ts/skr.database.js +1 -1
  38. package/dist_ts/skr.errors.d.ts +18 -0
  39. package/dist_ts/skr.errors.js +34 -0
  40. package/dist_ts/skr.export.js +4 -7
  41. package/dist_ts/skr.invoice.adapter.d.ts +15 -1
  42. package/dist_ts/skr.invoice.adapter.js +253 -41
  43. package/dist_ts/skr.invoice.booking.js +14 -28
  44. package/dist_ts/skr.migrate.d.ts +20 -0
  45. package/dist_ts/skr.migrate.js +223 -0
  46. package/dist_ts/skr.period.d.ts +47 -0
  47. package/dist_ts/skr.period.js +95 -0
  48. package/dist_ts/skr.posting.d.ts +74 -0
  49. package/dist_ts/skr.posting.js +209 -0
  50. package/dist_ts/skr.security.d.ts +6 -9
  51. package/dist_ts/skr.security.js +16 -89
  52. package/dist_ts/skr.sequence.d.ts +32 -0
  53. package/dist_ts/skr.sequence.js +51 -0
  54. package/dist_ts/skr.txview.d.ts +46 -0
  55. package/dist_ts/skr.txview.js +235 -0
  56. package/dist_ts/skr.types.d.ts +35 -1
  57. package/dist_ts/skr.verify.d.ts +13 -0
  58. package/dist_ts/skr.verify.js +84 -0
  59. package/package.json +21 -24
  60. package/readme.hints.md +37 -0
  61. package/readme.md +94 -1
  62. package/readme.plan.md +180 -243
  63. package/ts/00_commitinfo_data.ts +1 -1
  64. package/ts/core/core.accountpolicy.ts +154 -0
  65. package/ts/core/core.bukeys.ts +146 -0
  66. package/ts/core/core.datev.captions.ts +133 -0
  67. package/ts/core/core.datev.ts +174 -0
  68. package/ts/core/core.hash.ts +76 -0
  69. package/ts/core/core.plugins.ts +9 -0
  70. package/ts/core/core.recipes.ts +659 -0
  71. package/ts/core/core.taxscenario.ts +156 -0
  72. package/ts/core/core.types.ts +74 -0
  73. package/ts/core/core.validate.ts +119 -0
  74. package/ts/core/index.ts +15 -0
  75. package/ts/index.ts +31 -0
  76. package/ts/plugins.ts +4 -0
  77. package/ts/skr.api.ts +432 -46
  78. package/ts/skr.balances.ts +127 -0
  79. package/ts/skr.classes.journalentry.ts +54 -5
  80. package/ts/skr.classes.reports.ts +54 -126
  81. package/ts/skr.database.ts +3 -0
  82. package/ts/skr.errors.ts +44 -0
  83. package/ts/skr.export.ts +3 -6
  84. package/ts/skr.invoice.adapter.ts +291 -45
  85. package/ts/skr.invoice.booking.ts +22 -34
  86. package/ts/skr.migrate.ts +268 -0
  87. package/ts/skr.period.ts +139 -0
  88. package/ts/skr.posting.ts +273 -0
  89. package/ts/skr.security.ts +18 -93
  90. package/ts/skr.sequence.ts +89 -0
  91. package/ts/skr.txview.ts +268 -0
  92. package/ts/skr.types.ts +37 -1
  93. package/ts/skr.verify.ts +99 -0
  94. /package/{license.md → license} +0 -0
package/readme.plan.md CHANGED
@@ -1,243 +1,180 @@
1
- # @fin.cx/skr Implementation Plan
2
-
3
- ## Command to reread CLAUDE.md
4
-
5
- `cat /home/philkunz/.claude/CLAUDE.md`
6
-
7
- ## Project Overview
8
-
9
- TypeScript module implementing SKR03 and SKR04 German accounting standards for double-entry bookkeeping with MongoDB persistence via @push.rocks/smartdata.
10
-
11
- ## Implementation Tasks
12
-
13
- ### Phase 1: Project Setup
14
-
15
- - [ ] Initialize npm project with pnpm
16
- - [ ] Create package.json with proper metadata (@fin.cx/skr)
17
- - [ ] Install core dependencies
18
- - [ ] @push.rocks/smartdata
19
- - [ ] @git.zone/tstest (dev dependency)
20
- - [ ] Create tsconfig.json based on @push.rocks/smarthash pattern
21
- - [ ] Create .smartconfig.json for additional configuration
22
- - [ ] Create .gitignore file
23
- - [ ] Create directory structure
24
- - [ ] ts/ directory for source code
25
- - [ ] test/ directory for tests
26
- - [ ] .vscode/ for VS Code settings
27
- - [ ] Create initial readme.md with project description
28
-
29
- ### Phase 2: Core Infrastructure
30
-
31
- - [ ] Create ts/index.ts with main exports
32
- - [ ] Create ts/plugins.ts for dependency management
33
- - [ ] Import and export @push.rocks/smartdata
34
- - [ ] Import and export @push.rocks/smartunique for ID generation
35
- - [ ] Import and export @push.rocks/smarttime for date handling
36
- - [ ] Set up database connection helper in ts/skr.database.ts
37
- - [ ] Create type definitions in ts/skr.types.ts
38
- - [ ] Define AccountType enum
39
- - [ ] Define SKRType enum
40
- - [ ] Define TransactionStatus enum
41
- - [ ] Define report interfaces
42
-
43
- ### Phase 3: Data Models
44
-
45
- - [ ] Create ts/skr.classes.account.ts
46
- - [ ] Define Account class extending SmartDataDbDoc
47
- - [ ] Add accountNumber field with unique index
48
- - [ ] Add accountName with searchable decorator
49
- - [ ] Add accountClass (0-9)
50
- - [ ] Add accountType (asset/liability/equity/revenue/expense)
51
- - [ ] Add skrType (SKR03/SKR04)
52
- - [ ] Add balance field
53
- - [ ] Add validation methods
54
- - [ ] Add helper methods for balance updates
55
- - [ ] Create ts/skr.classes.transaction.ts
56
- - [ ] Define Transaction class extending SmartDataDbDoc
57
- - [ ] Add transactionId with unique index
58
- - [ ] Add date field with index
59
- - [ ] Add debitAccount and creditAccount fields
60
- - [ ] Add amount field
61
- - [ ] Add description with searchable decorator
62
- - [ ] Add reference field
63
- - [ ] Add validation for double-entry rules
64
- - [ ] Add beforeSave hook for validation
65
- - [ ] Create ts/skr.classes.journalentry.ts
66
- - [ ] Define JournalEntry class for multi-line entries
67
- - [ ] Support split transactions
68
- - [ ] Add validation for balanced entries
69
-
70
- ### Phase 4: SKR Account Definitions
71
-
72
- - [ ] Create ts/skr03.data.ts
73
- - [ ] Define account class 0 (Capital accounts)
74
- - [ ] Define account class 1 (Fixed assets)
75
- - [ ] Define account class 2 (Current assets)
76
- - [ ] Define account class 3 (Equity and liabilities)
77
- - [ ] Define account class 4 (Operating income)
78
- - [ ] Define account class 5 (Operating expenses - materials)
79
- - [ ] Define account class 6 (Operating expenses - personnel)
80
- - [ ] Define account class 7 (Operating expenses - other)
81
- - [ ] Define account class 8 (Financial accounts)
82
- - [ ] Define account class 9 (Closing accounts)
83
- - [ ] Create ts/skr04.data.ts
84
- - [ ] Define account class 0 (Capital accounts)
85
- - [ ] Define account class 1 (Financial accounts)
86
- - [ ] Define account class 2 (Expenses)
87
- - [ ] Define account class 3 (Expenses continued)
88
- - [ ] Define account class 4 (Revenues)
89
- - [ ] Define account class 5 (Revenues continued)
90
- - [ ] Define account class 6 (Special accounts)
91
- - [ ] Define account class 7 (Cost accounting)
92
- - [ ] Define account class 8 (Free for use)
93
- - [ ] Define account class 9 (Closing accounts)
94
-
95
- ### Phase 5: Business Logic
96
-
97
- - [ ] Create ts/skr.classes.chartofaccounts.ts
98
- - [ ] Implement initializeSKR03() method
99
- - [ ] Implement initializeSKR04() method
100
- - [ ] Implement getAccountByNumber() method
101
- - [ ] Implement getAccountsByClass() method
102
- - [ ] Implement createCustomAccount() method
103
- - [ ] Implement validateAccountNumber() method
104
- - [ ] Implement importFromCSV() method
105
- - [ ] Implement exportToCSV() method
106
- - [ ] Create ts/skr.classes.ledger.ts
107
- - [ ] Implement postTransaction() method
108
- - [ ] Implement postJournalEntry() method
109
- - [ ] Implement validateDoubleEntry() method
110
- - [ ] Implement updateAccountBalances() method
111
- - [ ] Implement reverseTransaction() method
112
- - [ ] Implement getAccountHistory() method
113
- - [ ] Implement closeAccountingPeriod() method
114
-
115
- ### Phase 6: Reporting
116
-
117
- - [ ] Create ts/skr.classes.reports.ts
118
- - [ ] Implement getTrialBalance() method
119
- - [ ] Implement getIncomeStatement() for SKR03
120
- - [ ] Implement getIncomeStatement() for SKR04
121
- - [ ] Implement getBalanceSheet() for SKR03
122
- - [ ] Implement getBalanceSheet() for SKR04
123
- - [ ] Implement getGeneralLedger() method
124
- - [ ] Implement getAccountStatement() method
125
- - [ ] Implement getCashFlowStatement() method
126
- - [ ] Add DATEV export format support
127
-
128
- ### Phase 7: API Layer
129
-
130
- - [ ] Create ts/skr.api.ts
131
- - [ ] Implement REST-style account methods
132
- - [ ] createAccount()
133
- - [ ] getAccount()
134
- - [ ] updateAccount()
135
- - [ ] deleteAccount()
136
- - [ ] listAccounts()
137
- - [ ] Implement transaction methods
138
- - [ ] postTransaction()
139
- - [ ] getTransaction()
140
- - [ ] listTransactions()
141
- - [ ] reverseTransaction()
142
- - [ ] Implement report methods
143
- - [ ] generateTrialBalance()
144
- - [ ] generateIncomeStatement()
145
- - [ ] generateBalanceSheet()
146
- - [ ] Implement search methods
147
- - [ ] searchAccounts()
148
- - [ ] searchTransactions()
149
- - [ ] Add pagination support
150
- - [ ] Add filtering support
151
-
152
- ### Phase 8: Testing
153
-
154
- - [ ] Create test/test.basic.ts
155
- - [ ] Test database connection
156
- - [ ] Test basic model creation
157
- - [ ] Create test/test.skr03.ts
158
- - [ ] Test SKR03 account initialization
159
- - [ ] Test SKR03 specific account structure
160
- - [ ] Test process-oriented organization
161
- - [ ] Test SKR03 reporting
162
- - [ ] Create test/test.skr04.ts
163
- - [ ] Test SKR04 account initialization
164
- - [ ] Test SKR04 specific account structure
165
- - [ ] Test financial statement organization
166
- - [ ] Test SKR04 reporting
167
- - [ ] Create test/test.transactions.ts
168
- - [ ] Test simple transaction posting
169
- - [ ] Test complex journal entries
170
- - [ ] Test double-entry validation
171
- - [ ] Test balance updates
172
- - [ ] Test transaction reversal
173
- - [ ] Create test/test.reports.ts
174
- - [ ] Test trial balance generation
175
- - [ ] Test income statement
176
- - [ ] Test balance sheet
177
- - [ ] Test report accuracy
178
- - [ ] Create test/test.api.ts
179
- - [ ] Test API CRUD operations
180
- - [ ] Test API search functionality
181
- - [ ] Test API pagination
182
- - [ ] Test API error handling
183
-
184
- ### Phase 9: Documentation
185
-
186
- - [ ] Update readme.md with comprehensive documentation
187
- - [ ] Installation instructions
188
- - [ ] Quick start guide
189
- - [ ] API reference
190
- - [ ] SKR03 vs SKR04 explanation
191
- - [ ] Code examples
192
- - [ ] Add inline JSDoc comments to all classes and methods
193
- - [ ] Create example usage files
194
- - [ ] Document CSV import/export format
195
- - [ ] Document DATEV compatibility
196
-
197
- ### Phase 10: Build and Quality
198
-
199
- - [ ] Run pnpm build and fix any TypeScript errors
200
- - [ ] Run pnpm test and ensure all tests pass
201
- - [ ] Check for missing type definitions
202
- - [ ] Optimize database indexes
203
- - [ ] Add data validation and error handling
204
- - [ ] Performance testing with large datasets
205
- - [ ] Security review for data access
206
-
207
- ### Phase 11: Advanced Features
208
-
209
- - [ ] Add multi-currency support
210
- - [ ] Add VAT/tax calculation helpers
211
- - [ ] Add cost center accounting
212
- - [ ] Add budget management
213
- - [ ] Add audit trail functionality
214
- - [ ] Add data migration tools
215
- - [ ] Add backup/restore functionality
216
-
217
- ### Phase 12: Finalization
218
-
219
- - [ ] Final code review
220
- - [ ] Update all documentation
221
- - [ ] Create migration guide from other systems
222
- - [ ] Prepare for npm publication
223
- - [ ] Create changelog
224
- - [ ] Tag version 1.0.0
225
-
226
- ## Notes
227
-
228
- - SKR03 uses process structure principle (operating procedures)
229
- - SKR04 uses financial classification principle (financial statements)
230
- - Account numbers are 4-digit (0000-9999)
231
- - Must maintain double-entry bookkeeping rules
232
- - Use @push.rocks/smartdata for all database operations
233
- - Follow existing code patterns from @push.rocks modules
234
- - Test with @git.zone/tstest using expect from tapbundle
235
-
236
- ## Success Criteria
237
-
238
- - [ ] All account classes (0-9) implemented for both SKR03 and SKR04
239
- - [ ] Double-entry bookkeeping validation working
240
- - [ ] Reports generating correctly
241
- - [ ] All tests passing
242
- - [ ] TypeScript compilation successful
243
- - [ ] Documentation complete
1
+ # fin.cx Accounting Program — "No External Tax Accountant"
2
+
3
+ Program-level plan anchored in @fin.cx/skr. Supersedes the original build checklist
4
+ (that scaffold was stale; the package is long past it — see changelog).
5
+ Status source of truth for current findings: `readme.hints.md`.
6
+
7
+ ## Context
8
+
9
+ Run German company books end-to-end bookkeeping, VAT filings, year-end without an
10
+ external Steuerberater for the mechanical work. skr v1.x is a solid bookkeeping core but
11
+ not filing-grade: float money with 0.01-epsilon balance checks, non-atomic 3-write
12
+ posting, no GoBD Festschreibung (mutable docs, non-gapless numbering, no audit trail),
13
+ 6 BU keys, ~110-account chart subsets, non-importable DATEV export stub, no stateless
14
+ booking API, and zero filing coverage (ELSTER/E-Bilanz/HGB statements/OPOS/
15
+ Anlagenbuchhaltung/bank reconciliation).
16
+
17
+ **Critical path:** skr v2 hardening → complete FiBu → UStVA via ELSTER (removes monthly
18
+ StB dependency) → E-Bilanz + HGB year-end (removes annual dependency).
19
+
20
+ ## Decisions (assumptions where user confirmation pending)
21
+
22
+ 1. Full program roadmap; each milestone gets its own detailed plan when it starts.
23
+ 2. Own company books first; APIs product-grade; multi-tenant/RBAC deferred.
24
+ 3. ELSTER owned: ERiC native lib via @git.zone/tsrust + @push.rocks/smartrust
25
+ `@fin.cx/elster`.
26
+ 4. Full SKR03/04 + E-Bilanz taxonomy mapping from public sources (no DATEV license);
27
+ legal review before public release.
28
+ 5. Payroll OUT of scope (integrate provider, import GL postings).
29
+ 6. Statutory WP audit (§316 HGB) out of scope by law. Goal = "StB consulted on judgment
30
+ calls only".
31
+
32
+ ## Calendar anchors (from 2026-07-09, FY = calendar year)
33
+
34
+ UStVA parallel-run 09–11/2026 first live self-filed UStVA 12/2026 or 01/2027
35
+ FY2026 Jahresabschluss self-prepared H1 2027 (one paid StB review as backstop;
36
+ KSt/GewSt/UStJE deadline ~31 Jul 2027; Offenlegung 31 Dec 2027) → fully solo from FY2027.
37
+
38
+ **Week-0 actions (hard external clocks, user):**
39
+ 1. ELSTER developer registration (Bayerisches LfSt) → Hersteller-ID + ERiC access
40
+ (days–4 wks).
41
+ 2. Confirm/obtain ELSTER Organisationszertifikat for TVC GmbH (post, 1–2 wks).
42
+ 3. Bundesanzeiger/Unternehmensregister publisher registration.
43
+
44
+ ## Milestones
45
+
46
+ ### M0 skr v2.0.0 core hardening (foundation; blocks B, C2, D, E1)
47
+
48
+ After **@fin.cx/calculation v1.1.0** (cents module RELEASED 2026-07-09 ✓).
49
+
50
+ - **Money:** ledger amounts = integer cents (`TCents`); exact `===` balance checks.
51
+ Fractional math via calculation cents module (`vatFromNetCents`, `splitGrossCents`
52
+ with net+vat===gross guarantee, `allocateCents` largest-remainder, `convertCents`,
53
+ `centsFromFloat` with drift guard). ROUND_HALF_UP = kaufmännisches Runden.
54
+ - **Stateless core `ts/core/`** (imports only @fin.cx/calculation + each other):
55
+ `core.types.ts` (IJournalDraft/IJournalLineDraft with explicit per-line Gegenkonto;
56
+ TBuKey as string union; TTaxScenario), `core.bukeys.ts` (full BU table from official
57
+ DATEV Steuerschlüssel docs v1 table + finance.plus logic both suspect, do not copy
58
+ blind), `core.taxscenario.ts` (confidence-scored cascade), `core.accountpolicy.ts`
59
+ (IAccountPolicy + SKR03/04 defaults incl. Geldtransit, FX gain/loss, rounding-diff),
60
+ `core.recipes.ts` (pure builders: vendor/customer invoice incl. reverse-charge +
61
+ intra-EU paired VAT, bank payment clearing with Skonto, internal transfer via
62
+ Geldtransit, suspense book/resolve, FX difference lines), `core.validate.ts`,
63
+ `core.datev.ts` (full Buchungsstapel row model, EXTF 700, buSchluessel on every row),
64
+ `core.hash.ts` (canonical serialization + SHA-256 chain).
65
+ - **Atomic posting:** smartdata 7.1.7 sessions (verified supported). Mongo MUST be a
66
+ replica set; `SkrApi.initialize()` probes and fails hard. `JournalPoster`
67
+ (skr.posting.ts): pre-flight withTransaction: period-lock re-check, gapless sequence
68
+ via $inc findOneAndUpdate, hash chain CAS on head. JournalEntry = single source of
69
+ truth (v1 Transaction explosion removed; collection frozen as legacy read model).
70
+ Balances recomputed via aggregation (skr.balances.ts); Account.updateBalance deleted
71
+ from posting path.
72
+ - **Festschreibung:** posted == immutable (corrections via Storno only). JournalEntry +=
73
+ sequenceNumber (gapless per skrType+fiscalYear), prevHash/entryHash, finalizedAt,
74
+ status posted|finalized, schemaVersion 2. beforeSave()/delete() throw on mutation of
75
+ hashed docs; reversedBy derived (not stored). LedgerPeriod doc + festschreibePeriod();
76
+ closePeriod() posts P&L-zero entries then festschreibt. verifyHashChain() in
77
+ skr.verify.ts. SecurityManager: keep CAdES-B; RFC-3161 stub loud NotImplementedError;
78
+ fix require('crypto') ESM bug in skr.export.ts.
79
+ - **Migration** (idempotent, offline, float fields kept): M001 cents backfill (abort on
80
+ drift > 0.5 cent) M002 unify legacy Transactions into synthesized JournalEntries →
81
+ M003 sequence + chain assignment + operator-confirmed festschreiben. JSON report.
82
+ - **Phases (status 2026-07-09):** (0) replica-set env (gitzone services ≥2.23.0),
83
+ EXTF-700/v13 layout (verified vs DATEV-importable reference; official
84
+ Steuerschlüssel doc 0904313 portal-gated manual import check per RC remains)
85
+ (1) calculation v1.1.1 released (2) stateless core ✓ → (3) persistence
86
+ hardening (4) facade/reports rewiring + security descope ✓ →
87
+ (5) migrations + docs + v2.0.0 release ✓. **M0 COMPLETE** except the standing
88
+ per-RC manual DATEV import validation.
89
+ - **Tests:** recipe goldens (both charts, exact cents), byte-exact EXTF files, property
90
+ tests (seeded PRNG), concurrency (N parallel posts gapless, chain verifies, exact
91
+ trial balance), locked-period race, immutability throws, txn-abort no-partials,
92
+ migration round-trip; existing 65 tests green minus documented divergences; manual
93
+ DATEV import check per RC.
94
+
95
+ ### M-A `@fin.cx/chartdata` (new pkg; parallel to M0)
96
+
97
+ Year-versioned full SKR03/04: account master, Automatikkonto functions + allowed BU keys,
98
+ UStVA-Kennzahl / HGB §266/§275 / E-Bilanz (de-gaap-ci) mappings. Pure data + lookup API;
99
+ `getMappingCoverage()` fails loudly. Pipeline in unpublished tools/ (public sources,
100
+ provenance per record). A1 chart+Automatik+Kennzahlen → A2 HGB → A3 E-Bilanz taxonomy
101
+ (esteuer.de). Own-books account coverage first. Verify: schema checks, cross-diff vs
102
+ Kivitendo/Odoo l10n_de (reviewed, not copied), SKR PDF spot checks, ERiC as E-Bilanz
103
+ oracle. Legal review before public MIT release.
104
+
105
+ ### M-B Subledgers + reconciliation
106
+
107
+ B1 `@fin.cx/camt` (CAMT.052/053/054; MT940 = legacy) + `@fin.cx/bankrec` (canonical
108
+ decimal bank txn with SEPA refs, adapters, balance-chain continuity, confidence-scored
109
+ matching, auto-post above threshold, review queue below). B2 OPOS inside skr (ts/opos/:
110
+ masters, open items, clearItems with Skonto+VAT correction, aging, dunning states;
111
+ invariant: subledger == control account). B3 `@fin.cx/assets` (AfA schedules from BMF
112
+ tables, GWG/degressive as year-keyed policy, Anlagespiegel D1). B1 before live UStVA;
113
+ B2/B3 may trail.
114
+
115
+ ### M-C `@fin.cx/elster` (ERiC via Rust bridge) — first-win lane
116
+
117
+ Thin transport: validate / submitTest (Testmerker) / submitLive / confirmation PDF.
118
+ Rust binary dlopens ERiC from operator-supplied ERIC_HOME (ERiC never enters npm/repo;
119
+ version-compat matrix + checksum gate). Kennzahl computation in `@fin.cx/tax` (VAT module
120
+ ships early). C1 bridge → C2 UStVA 3-month parallel-run (3 consecutive zero/explained-diff
121
+ months required) C2' live + E1 → C3 DFV/ZM/UStJE.
122
+
123
+ ### M-D Year-end (`@fin.cx/jahresabschluss` + `@fin.cx/tax`, Q1–Q2 2027)
124
+
125
+ D1 §266/§275 Gliederung + §267 size classes + Anhang skeleton + Anlagespiegel. D3 tax
126
+ engine (§4(5) EStG, §8b KStG, GewSt §8/§9 add-backs, loss carryforwards, KSt 15%+Soli,
127
+ GewSt Hebesatz Bremen 460%; provisions posted back to skr). D2 E-Bilanz XBRL writer
128
+ (ERiC validates locally no heavyweight XBRL lib) via elster. D4 Offenlegung generator +
129
+ checklist (semi-manual upload). Verify: "re-file the past" vs StB-filed prior year +
130
+ Bescheide; tie-outs; paid StB review of first Abschluss.
131
+
132
+ ### M-E Operational readiness (thin, inside skr)
133
+
134
+ E1 Verfahrensdoku generator (ships WITH first live UStVA — GoBD requires from go-live).
135
+ E2 GDPdU/GoBD Z3 Datenträgerüberlassung (Beschreibungsstandard index.xml + IDEA CSVs, on
136
+ BagIt export). E3 retention (10y books, 8y Belege post-2025).
137
+
138
+ ## Waves
139
+
140
+ 1. **W0 (now):** registrations; A1 pipeline; M0 start. ✓ calculation v1.1.0 released.
141
+ 2. **W1 (Jul–Sep 2026):** M0 lands; C1; tax VAT module; A1; B1 MVP; parallel-run from
142
+ 09/2026.
143
+ 3. **W2 (Q4 2026):** live UStVA + E1 ⇒ monthly StB dependency removed. C3 DFV. B2/B3/A2/A3.
144
+ 4. **W3 (Q1–Q2 2027):** D1→D3→D2→D4 for FY2026; StB review ⇒ fully solo from FY2027.
145
+ 5. **Continuous:** E2/E3; annual maintenance ~4–8 wks/yr (ERiC Nov release = hard
146
+ calendar item; taxonomy bump; form-year schemas; year-keyed tax parameters).
147
+
148
+ ## Top risks
149
+
150
+ 1. Incorrect live filing → parallel-run gate, re-file-the-past regression, ERiC+Testmerker
151
+ CI, human sign-off, StB review yr 1.
152
+ 2. ERiC licensing/platform (non-redistributable; ARM64 TBD) → ERIC_HOME + compat matrix;
153
+ x86_64 first.
154
+ 3. DATEV database rights on chart data → multi-source, provenance, legal review.
155
+ 4. Completeness failures → balance-chain continuity as monthly-close gate; OPOS
156
+ invariants.
157
+ 5. Regulatory churn → year-keyed data concentrated in chartdata+elster; DATEV export as
158
+ permanent escape hatch.
159
+
160
+ ## Open questions (user)
161
+
162
+ 1. Location of `fin-accountingbackend` repo (not on this machine; finance.plus used as
163
+ reference).
164
+ 2. ELSTER Organisationszertifikat present? Dauerfristverlängerung in place?
165
+ 3. **Ist- oder Soll-Versteuerung (§20 UStG)?** Blocks Wave-1 VAT engine design.
166
+ 4. Intra-EU B2B supplies (ZM needed)?
167
+ 5. elster deployment host architecture (ERiC aarch64 TBD)?
168
+ 6. chartdata public MIT immediately or after legal review?
169
+ 7. Beleg archival: doclake vs skr export bundles?
170
+ 8. StB cooperation for parallel-run (filed Kennzahlen + prior-year working papers)?
171
+ 9. Festschreibung: posted==immutable OK, or correction window until UStVA submission?
172
+ 10. RFC-3161 descope in M0 OK (loud failure instead of fake stub)?
173
+ 11. One company per DB confirmed (sequences keyed skrType+fiscalYear)?
174
+
175
+ ## Program gates
176
+
177
+ - **Gate 1 (before live UStVA):** 3 zero/explained-diff parallel months + B1 continuity
178
+ green + E1 published.
179
+ - **Gate 2 (before FY2026 self-filing):** re-file-the-past matches StB filings +
180
+ Bescheide; ERiC-valid E-Bilanz; StB review sign-off.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/skr',
6
- version: '1.3.0',
6
+ version: '2.0.0',
7
7
  description: 'SKR03 and SKR04 German accounting standards for double-entry bookkeeping'
8
8
  }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Account policy: which accounts a booking recipe uses for a given SKR chart.
3
+ * Defaults reflect the DATEV standard charts; entries marked PROVISIONAL are
4
+ * pattern-derived and get verified against the full chart data in M-A
5
+ * (@fin.cx/chartdata). Everything is overridable per call.
6
+ */
7
+ import type { TSKRType } from './core.types.js';
8
+
9
+ export interface IAccountPolicy {
10
+ skrType: TSKRType;
11
+ bank: string;
12
+ cash: string;
13
+ /** Sammelkonten — direct postings are blocked; use personal accounts. */
14
+ debtorsControl: string;
15
+ creditorsControl: string;
16
+ /** Suspense for unclear payments (Durchlaufende Posten). */
17
+ clearing: string;
18
+ /** Interim account for bank-to-bank transfers. */
19
+ geldtransit: string;
20
+ vat: {
21
+ outputStandard: string;
22
+ outputReduced: string;
23
+ inputStandard: string;
24
+ inputReduced: string;
25
+ intraEuAcqInput: string;
26
+ intraEuAcqOutput: string;
27
+ reverseChargeInput: string;
28
+ reverseChargeOutput: string;
29
+ };
30
+ revenue: {
31
+ domesticStandard: string;
32
+ domesticReduced: string;
33
+ intraEuSupply: string;
34
+ export: string;
35
+ reverseCharge: string;
36
+ };
37
+ expenseDefault: string;
38
+ skonto: {
39
+ /** erhaltene Skonti (purchases) — Automatikkonten with VSt correction */
40
+ receivedStandard: string;
41
+ receivedReduced: string;
42
+ /** gewährte Skonti (sales) — Automatikkonten with USt correction */
43
+ grantedStandard: string;
44
+ grantedReduced: string;
45
+ };
46
+ fx: { gain: string; loss: string };
47
+ /** Small payment-difference write-offs (PROVISIONAL: generic sonstige Erträge/Aufwendungen). */
48
+ roundingDiff: { gain: string; loss: string };
49
+ debtorRange: [number, number];
50
+ creditorRange: [number, number];
51
+ /**
52
+ * Accounts with built-in DATEV tax automatism. Lines on these accounts must
53
+ * carry no BU key ('' — automatism applies) or key 40 (automatism cancelled).
54
+ */
55
+ automatikkonten: string[];
56
+ }
57
+
58
+ export const SKR03_DEFAULT_POLICY: IAccountPolicy = {
59
+ skrType: 'SKR03',
60
+ bank: '1200',
61
+ cash: '1000',
62
+ debtorsControl: '1400',
63
+ creditorsControl: '1600',
64
+ clearing: '1590',
65
+ geldtransit: '1360',
66
+ vat: {
67
+ outputStandard: '1776',
68
+ outputReduced: '1771',
69
+ inputStandard: '1576',
70
+ inputReduced: '1571',
71
+ intraEuAcqInput: '1574',
72
+ intraEuAcqOutput: '1784',
73
+ reverseChargeInput: '1577',
74
+ reverseChargeOutput: '1787',
75
+ },
76
+ revenue: {
77
+ domesticStandard: '8400',
78
+ domesticReduced: '8300',
79
+ intraEuSupply: '8125',
80
+ export: '8120',
81
+ reverseCharge: '8337',
82
+ },
83
+ expenseDefault: '4980',
84
+ skonto: {
85
+ receivedStandard: '3736',
86
+ receivedReduced: '3731', // PROVISIONAL
87
+ grantedStandard: '8736',
88
+ grantedReduced: '8731', // PROVISIONAL
89
+ },
90
+ fx: { gain: '2660', loss: '2150' },
91
+ roundingDiff: { gain: '2700', loss: '2300' }, // PROVISIONAL
92
+ debtorRange: [10000, 69999],
93
+ creditorRange: [70000, 99999],
94
+ automatikkonten: ['8400', '8300', '8125', '8120', '3400', '3300', '3736', '3731', '8736', '8731'],
95
+ };
96
+
97
+ export const SKR04_DEFAULT_POLICY: IAccountPolicy = {
98
+ skrType: 'SKR04',
99
+ bank: '1800',
100
+ cash: '1600',
101
+ debtorsControl: '1200',
102
+ creditorsControl: '3300',
103
+ clearing: '3290',
104
+ geldtransit: '1460',
105
+ vat: {
106
+ outputStandard: '3806',
107
+ outputReduced: '3801',
108
+ inputStandard: '1406',
109
+ inputReduced: '1401',
110
+ intraEuAcqInput: '1404',
111
+ intraEuAcqOutput: '3804',
112
+ reverseChargeInput: '1407',
113
+ reverseChargeOutput: '3837',
114
+ },
115
+ revenue: {
116
+ domesticStandard: '4400',
117
+ domesticReduced: '4300',
118
+ intraEuSupply: '4125',
119
+ export: '4120',
120
+ reverseCharge: '4337',
121
+ },
122
+ expenseDefault: '6980',
123
+ skonto: {
124
+ receivedStandard: '5736',
125
+ receivedReduced: '5731', // PROVISIONAL
126
+ grantedStandard: '4736',
127
+ grantedReduced: '4731', // PROVISIONAL
128
+ },
129
+ fx: { gain: '4840', loss: '6880' },
130
+ roundingDiff: { gain: '4830', loss: '6300' }, // PROVISIONAL
131
+ debtorRange: [10000, 69999],
132
+ creditorRange: [70000, 99999],
133
+ automatikkonten: ['4400', '4300', '4125', '4120', '5400', '5300', '5736', '5731', '4736', '4731'],
134
+ };
135
+
136
+ export function getDefaultPolicy(skrType: TSKRType): IAccountPolicy {
137
+ return skrType === 'SKR03' ? SKR03_DEFAULT_POLICY : SKR04_DEFAULT_POLICY;
138
+ }
139
+
140
+ export function isAutomatikAccount(policy: IAccountPolicy, accountNumber: string): boolean {
141
+ return policy.automatikkonten.includes(accountNumber);
142
+ }
143
+
144
+ export function isDebtorAccount(policy: IAccountPolicy, accountNumber: string): boolean {
145
+ const parsed = Number.parseInt(accountNumber, 10);
146
+ return Number.isInteger(parsed) && parsed >= policy.debtorRange[0] && parsed <= policy.debtorRange[1];
147
+ }
148
+
149
+ export function isCreditorAccount(policy: IAccountPolicy, accountNumber: string): boolean {
150
+ const parsed = Number.parseInt(accountNumber, 10);
151
+ return (
152
+ Number.isInteger(parsed) && parsed >= policy.creditorRange[0] && parsed <= policy.creditorRange[1]
153
+ );
154
+ }