@accounter/server 0.0.9-alpha-20251231083050-a0e737863ca2a9fa68506d15357e55d9287972cb → 0.0.9-alpha-20251231163357-33d4c33fec5e21dad2e04d1f293f6248d2550588
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.
- package/CHANGELOG.md +27 -5
- package/README.md +66 -3
- package/dist/server/scripts/seed-admin-context.js +20 -25
- package/dist/server/scripts/seed-admin-context.js.map +1 -1
- package/dist/server/src/__tests__/db-bootstrap.test.js +7 -2
- package/dist/server/src/__tests__/db-bootstrap.test.js.map +1 -1
- package/dist/server/src/__tests__/factories/business.d.ts +1 -1
- package/dist/server/src/__tests__/factories/financial-account.d.ts +1 -1
- package/dist/server/src/__tests__/factories/index.test.js +1 -0
- package/dist/server/src/__tests__/factories/index.test.js.map +1 -1
- package/dist/server/src/__tests__/factories/tax-category.d.ts +1 -1
- package/dist/server/src/__tests__/factories/tax-category.js +1 -1
- package/dist/server/src/__tests__/factories/tax-category.js.map +1 -1
- package/dist/server/src/__tests__/factories/tax-category.test.js +8 -6
- package/dist/server/src/__tests__/factories/tax-category.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/fixture-loader.d.ts +1 -1
- package/dist/server/src/__tests__/helpers/fixture-loader.js +25 -52
- package/dist/server/src/__tests__/helpers/fixture-loader.js.map +1 -1
- package/dist/server/src/__tests__/helpers/migration-verification.d.ts +1 -1
- package/dist/server/src/__tests__/helpers/migration-verification.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js +4 -4
- package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js.map +1 -1
- package/dist/server/src/__tests__/helpers/seed-helpers.d.ts +9 -9
- package/dist/server/src/__tests__/helpers/seed-helpers.js +57 -54
- package/dist/server/src/__tests__/helpers/seed-helpers.js.map +1 -1
- package/dist/server/src/__tests__/seed-admin-context.integration.test.js +2 -1
- package/dist/server/src/__tests__/seed-admin-context.integration.test.js.map +1 -1
- package/dist/server/src/demo-fixtures/__tests__/deterministic-uuid.test.js +3 -2
- package/dist/server/src/demo-fixtures/__tests__/deterministic-uuid.test.js.map +1 -1
- package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.d.ts +1 -0
- package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.js +69 -0
- package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.js.map +1 -0
- package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.d.ts +1 -0
- package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.js +26 -0
- package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.js.map +1 -0
- package/dist/server/src/demo-fixtures/helpers/admin-context.d.ts +10 -0
- package/dist/server/src/demo-fixtures/helpers/admin-context.js +40 -0
- package/dist/server/src/demo-fixtures/helpers/admin-context.js.map +1 -0
- package/dist/server/src/demo-fixtures/helpers/placeholder.d.ts +45 -0
- package/dist/server/src/demo-fixtures/helpers/placeholder.js +50 -0
- package/dist/server/src/demo-fixtures/helpers/placeholder.js.map +1 -0
- package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.d.ts +21 -0
- package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.js +26 -0
- package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.js.map +1 -0
- package/dist/server/src/demo-fixtures/helpers/seed-vat.d.ts +20 -0
- package/dist/server/src/demo-fixtures/helpers/seed-vat.js +30 -0
- package/dist/server/src/demo-fixtures/helpers/seed-vat.js.map +1 -0
- package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.d.ts +9 -0
- package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.js +86 -0
- package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.js.map +1 -0
- package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.d.ts +12 -0
- package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.js +375 -0
- package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.js.map +1 -0
- package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.d.ts +10 -0
- package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.js +113 -0
- package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.js.map +1 -0
- package/dist/server/src/demo-fixtures/use-cases/index.d.ts +41 -0
- package/dist/server/src/demo-fixtures/use-cases/index.js +50 -0
- package/dist/server/src/demo-fixtures/use-cases/index.js.map +1 -0
- package/dist/server/src/demo-fixtures/validate-demo-data.d.ts +1 -0
- package/dist/server/src/demo-fixtures/validate-demo-data.js +117 -0
- package/dist/server/src/demo-fixtures/validate-demo-data.js.map +1 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.d.ts +349 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.js +602 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.js.map +1 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.test.d.ts +1 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.test.js +247 -0
- package/dist/server/src/demo-fixtures/validators/ledger-validators.test.js.map +1 -0
- package/dist/server/src/demo-fixtures/validators/types.d.ts +69 -0
- package/dist/server/src/demo-fixtures/validators/types.js +8 -0
- package/dist/server/src/demo-fixtures/validators/types.js.map +1 -0
- package/dist/server/src/fixtures/fixture-spec.d.ts +146 -0
- package/dist/server/src/fixtures/fixture-spec.js +2 -0
- package/dist/server/src/fixtures/fixture-spec.js.map +1 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js +4 -0
- package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js.map +1 -1
- package/dist/server/src/modules/deel/resolvers/deel.resolvers.js +0 -3
- package/dist/server/src/modules/deel/resolvers/deel.resolvers.js.map +1 -1
- package/dist/server/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.js +4 -3
- package/dist/server/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.js.map +1 -1
- package/dist/server/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.js +5 -3
- package/dist/server/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.js.map +1 -1
- package/dist/server/src/shared/constants.d.ts +1 -0
- package/dist/server/src/shared/constants.js +1 -0
- package/dist/server/src/shared/constants.js.map +1 -1
- package/dist/server/src/shared/helpers/misc.js +2 -2
- package/dist/server/src/shared/helpers/misc.js.map +1 -1
- package/docs/demo-staging-guide.md +611 -0
- package/package.json +6 -3
- package/scripts/seed-admin-context.ts +22 -33
- package/src/__tests__/db-bootstrap.test.ts +9 -2
- package/src/__tests__/factories/business.ts +1 -1
- package/src/__tests__/factories/financial-account.ts +1 -1
- package/src/__tests__/factories/index.test.ts +1 -0
- package/src/__tests__/factories/tax-category.test.ts +8 -6
- package/src/__tests__/factories/tax-category.ts +2 -2
- package/src/__tests__/helpers/fixture-loader.ts +26 -61
- package/src/__tests__/helpers/migration-verification.ts +2 -2
- package/src/__tests__/helpers/seed-helpers.business.test.ts +4 -4
- package/src/__tests__/helpers/seed-helpers.ts +66 -75
- package/src/__tests__/seed-admin-context.integration.test.ts +2 -1
- package/src/demo-fixtures/__tests__/deterministic-uuid.test.ts +3 -2
- package/src/demo-fixtures/__tests__/seed-and-validate.test.ts +96 -0
- package/src/demo-fixtures/__tests__/use-case-registry.test.ts +27 -0
- package/src/demo-fixtures/helpers/admin-context.ts +59 -0
- package/src/demo-fixtures/helpers/placeholder.ts +50 -0
- package/src/demo-fixtures/helpers/seed-exchange-rates.ts +29 -0
- package/src/demo-fixtures/helpers/seed-vat.ts +35 -0
- package/src/demo-fixtures/use-cases/equity/shareholder-dividend.ts +88 -0
- package/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.ts +377 -0
- package/src/demo-fixtures/use-cases/income/client-payment-with-refund.ts +115 -0
- package/src/demo-fixtures/use-cases/index.ts +52 -0
- package/src/demo-fixtures/validate-demo-data.ts +153 -0
- package/src/demo-fixtures/validators/README.md +190 -0
- package/src/demo-fixtures/validators/ledger-validators.test.ts +298 -0
- package/src/demo-fixtures/validators/ledger-validators.ts +711 -0
- package/src/demo-fixtures/validators/types.ts +83 -0
- package/src/fixtures/fixture-spec.ts +158 -0
- package/src/modules/charges-matcher/__tests__/single-match-integration.test.ts +6 -0
- package/src/modules/deel/resolvers/deel.resolvers.ts +0 -3
- package/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.ts +4 -3
- package/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.ts +6 -3
- package/src/shared/constants.ts +2 -0
- package/src/shared/helpers/misc.ts +2 -3
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import type { UseCaseSpec } from '../../../fixtures/fixture-spec.js';
|
|
2
|
+
import { CountryCode, Currency } from '../../../shared/enums.js';
|
|
3
|
+
import { makeUUID } from '../../helpers/deterministic-uuid.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Monthly Expense Use-Case: Foreign Currency Transaction
|
|
7
|
+
*
|
|
8
|
+
* Demonstrates a US-based supplier invoice paid via bank transfer with
|
|
9
|
+
* exchange rate conversion from USD to ILS. This use-case validates:
|
|
10
|
+
* - Foreign currency transaction handling
|
|
11
|
+
* - Exchange rate application
|
|
12
|
+
* - Cross-border payment processing
|
|
13
|
+
* - Ledger generation with currency conversion
|
|
14
|
+
*/
|
|
15
|
+
export const monthlyExpenseForeignCurrency: UseCaseSpec = {
|
|
16
|
+
id: 'monthly-expense-foreign-currency',
|
|
17
|
+
name: 'Monthly Expense (Foreign Currency)',
|
|
18
|
+
description:
|
|
19
|
+
'US-based supplier invoice paid via bank transfer with exchange rate conversion from USD to ILS. Validates foreign currency handling and ledger generation.',
|
|
20
|
+
category: 'expenses',
|
|
21
|
+
fixtures: {
|
|
22
|
+
businesses: [
|
|
23
|
+
{
|
|
24
|
+
id: makeUUID('business', 'us-supplier-acme-llc'),
|
|
25
|
+
name: 'Acme Consulting LLC',
|
|
26
|
+
country: CountryCode['United States of America (the)'],
|
|
27
|
+
canSettleWithReceipt: false,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
taxCategories: [
|
|
31
|
+
{
|
|
32
|
+
id: makeUUID('tax-category', 'consulting-expenses'),
|
|
33
|
+
name: 'Consulting Expenses',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
financialAccounts: [
|
|
37
|
+
{
|
|
38
|
+
id: makeUUID('financial-account', 'bank-usd-account'),
|
|
39
|
+
accountNumber: '123-456-7890',
|
|
40
|
+
type: 'BANK_ACCOUNT',
|
|
41
|
+
currency: Currency.Usd,
|
|
42
|
+
taxCategoryMappings: [
|
|
43
|
+
{
|
|
44
|
+
taxCategoryId: makeUUID('tax-category', 'consulting-expenses'),
|
|
45
|
+
currency: Currency.Usd,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
charges: [
|
|
51
|
+
{
|
|
52
|
+
id: makeUUID('charge', 'consulting-invoice-2024-01'),
|
|
53
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
54
|
+
userDescription: 'January consulting services',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: makeUUID('charge', 'consulting-invoice-2024-02'),
|
|
58
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
59
|
+
userDescription: 'February consulting services',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: makeUUID('charge', 'consulting-invoice-2024-03'),
|
|
63
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
64
|
+
userDescription: 'March consulting services',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: makeUUID('charge', 'consulting-invoice-2024-04'),
|
|
68
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
69
|
+
userDescription: 'April consulting services',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: makeUUID('charge', 'consulting-invoice-2024-05'),
|
|
73
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
74
|
+
userDescription: 'May consulting services',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: makeUUID('charge', 'consulting-invoice-2024-06'),
|
|
78
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
79
|
+
userDescription: 'June consulting services',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: makeUUID('charge', 'consulting-invoice-2024-07'),
|
|
83
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
84
|
+
userDescription: 'July consulting services',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: makeUUID('charge', 'consulting-invoice-2024-08'),
|
|
88
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
89
|
+
userDescription: 'August consulting services',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: makeUUID('charge', 'consulting-invoice-2024-09'),
|
|
93
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
94
|
+
userDescription: 'September consulting services',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: makeUUID('charge', 'consulting-invoice-2024-10'),
|
|
98
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
99
|
+
userDescription: 'October consulting services',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: makeUUID('charge', 'consulting-invoice-2024-11'),
|
|
103
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
104
|
+
userDescription: 'November consulting services',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: makeUUID('charge', 'consulting-invoice-2024-12'),
|
|
108
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
109
|
+
userDescription: 'December consulting services',
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
transactions: [
|
|
113
|
+
{
|
|
114
|
+
id: makeUUID('transaction', 'consulting-payment-usd-01'),
|
|
115
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-01'),
|
|
116
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
117
|
+
amount: '-500.00',
|
|
118
|
+
currency: Currency.Usd,
|
|
119
|
+
eventDate: '2024-01-15',
|
|
120
|
+
debitDate: '2024-01-15',
|
|
121
|
+
accountNumber: '123-456-7890',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: makeUUID('transaction', 'consulting-payment-usd-02'),
|
|
125
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-02'),
|
|
126
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
127
|
+
amount: '-500.00',
|
|
128
|
+
currency: Currency.Usd,
|
|
129
|
+
eventDate: '2024-02-15',
|
|
130
|
+
debitDate: '2024-02-15',
|
|
131
|
+
accountNumber: '123-456-7890',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: makeUUID('transaction', 'consulting-payment-usd-03'),
|
|
135
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-03'),
|
|
136
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
137
|
+
amount: '-500.00',
|
|
138
|
+
currency: Currency.Usd,
|
|
139
|
+
eventDate: '2024-03-15',
|
|
140
|
+
debitDate: '2024-03-15',
|
|
141
|
+
accountNumber: '123-456-7890',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: makeUUID('transaction', 'consulting-payment-usd-04'),
|
|
145
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-04'),
|
|
146
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
147
|
+
amount: '-500.00',
|
|
148
|
+
currency: Currency.Usd,
|
|
149
|
+
eventDate: '2024-04-15',
|
|
150
|
+
debitDate: '2024-04-15',
|
|
151
|
+
accountNumber: '123-456-7890',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: makeUUID('transaction', 'consulting-payment-usd-05'),
|
|
155
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-05'),
|
|
156
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
157
|
+
amount: '-500.00',
|
|
158
|
+
currency: Currency.Usd,
|
|
159
|
+
eventDate: '2024-05-15',
|
|
160
|
+
debitDate: '2024-05-15',
|
|
161
|
+
accountNumber: '123-456-7890',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: makeUUID('transaction', 'consulting-payment-usd-06'),
|
|
165
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-06'),
|
|
166
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
167
|
+
amount: '-500.00',
|
|
168
|
+
currency: Currency.Usd,
|
|
169
|
+
eventDate: '2024-06-15',
|
|
170
|
+
debitDate: '2024-06-15',
|
|
171
|
+
accountNumber: '123-456-7890',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: makeUUID('transaction', 'consulting-payment-usd-07'),
|
|
175
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-07'),
|
|
176
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
177
|
+
amount: '-500.00',
|
|
178
|
+
currency: Currency.Usd,
|
|
179
|
+
eventDate: '2024-07-15',
|
|
180
|
+
debitDate: '2024-07-15',
|
|
181
|
+
accountNumber: '123-456-7890',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: makeUUID('transaction', 'consulting-payment-usd-08'),
|
|
185
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-08'),
|
|
186
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
187
|
+
amount: '-500.00',
|
|
188
|
+
currency: Currency.Usd,
|
|
189
|
+
eventDate: '2024-08-15',
|
|
190
|
+
debitDate: '2024-08-15',
|
|
191
|
+
accountNumber: '123-456-7890',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: makeUUID('transaction', 'consulting-payment-usd-09'),
|
|
195
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-09'),
|
|
196
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
197
|
+
amount: '-500.00',
|
|
198
|
+
currency: Currency.Usd,
|
|
199
|
+
eventDate: '2024-09-15',
|
|
200
|
+
debitDate: '2024-09-15',
|
|
201
|
+
accountNumber: '123-456-7890',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: makeUUID('transaction', 'consulting-payment-usd-10'),
|
|
205
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-10'),
|
|
206
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
207
|
+
amount: '-500.00',
|
|
208
|
+
currency: Currency.Usd,
|
|
209
|
+
eventDate: '2024-10-15',
|
|
210
|
+
debitDate: '2024-10-15',
|
|
211
|
+
accountNumber: '123-456-7890',
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
id: makeUUID('transaction', 'consulting-payment-usd-11'),
|
|
215
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-11'),
|
|
216
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
217
|
+
amount: '-500.00',
|
|
218
|
+
currency: Currency.Usd,
|
|
219
|
+
eventDate: '2024-11-15',
|
|
220
|
+
debitDate: '2024-11-15',
|
|
221
|
+
accountNumber: '123-456-7890',
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: makeUUID('transaction', 'consulting-payment-usd-12'),
|
|
225
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-12'),
|
|
226
|
+
businessId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
227
|
+
amount: '-500.00',
|
|
228
|
+
currency: Currency.Usd,
|
|
229
|
+
eventDate: '2024-12-15',
|
|
230
|
+
debitDate: '2024-12-15',
|
|
231
|
+
accountNumber: '123-456-7890',
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
documents: [
|
|
235
|
+
{
|
|
236
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-01-15'),
|
|
237
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-01'),
|
|
238
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
239
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
240
|
+
serialNumber: 'INV-2024-01-15',
|
|
241
|
+
type: 'INVOICE',
|
|
242
|
+
date: '2024-01-01',
|
|
243
|
+
totalAmount: '500.00',
|
|
244
|
+
currencyCode: Currency.Usd,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-02-15'),
|
|
248
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-02'),
|
|
249
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
250
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
251
|
+
serialNumber: 'INV-2024-02-15',
|
|
252
|
+
type: 'INVOICE',
|
|
253
|
+
date: '2024-02-01',
|
|
254
|
+
totalAmount: '500.00',
|
|
255
|
+
currencyCode: Currency.Usd,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-03-15'),
|
|
259
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-03'),
|
|
260
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
261
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
262
|
+
serialNumber: 'INV-2024-03-15',
|
|
263
|
+
type: 'INVOICE',
|
|
264
|
+
date: '2024-03-01',
|
|
265
|
+
totalAmount: '500.00',
|
|
266
|
+
currencyCode: Currency.Usd,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-04-15'),
|
|
270
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-04'),
|
|
271
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
272
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
273
|
+
serialNumber: 'INV-2024-04-15',
|
|
274
|
+
type: 'INVOICE',
|
|
275
|
+
date: '2024-04-01',
|
|
276
|
+
totalAmount: '500.00',
|
|
277
|
+
currencyCode: Currency.Usd,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-05-15'),
|
|
281
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-05'),
|
|
282
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
283
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
284
|
+
serialNumber: 'INV-2024-05-15',
|
|
285
|
+
type: 'INVOICE',
|
|
286
|
+
date: '2024-05-01',
|
|
287
|
+
totalAmount: '500.00',
|
|
288
|
+
currencyCode: Currency.Usd,
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-06-15'),
|
|
292
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-06'),
|
|
293
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
294
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
295
|
+
serialNumber: 'INV-2024-06-15',
|
|
296
|
+
type: 'INVOICE',
|
|
297
|
+
date: '2024-06-01',
|
|
298
|
+
totalAmount: '500.00',
|
|
299
|
+
currencyCode: Currency.Usd,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-07-15'),
|
|
303
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-07'),
|
|
304
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
305
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
306
|
+
serialNumber: 'INV-2024-07-15',
|
|
307
|
+
type: 'INVOICE',
|
|
308
|
+
date: '2024-07-01',
|
|
309
|
+
totalAmount: '500.00',
|
|
310
|
+
currencyCode: Currency.Usd,
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-08-15'),
|
|
314
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-08'),
|
|
315
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
316
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
317
|
+
serialNumber: 'INV-2024-08-15',
|
|
318
|
+
type: 'INVOICE',
|
|
319
|
+
date: '2024-08-01',
|
|
320
|
+
totalAmount: '500.00',
|
|
321
|
+
currencyCode: Currency.Usd,
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-09-15'),
|
|
325
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-09'),
|
|
326
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
327
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
328
|
+
serialNumber: 'INV-2024-09-15',
|
|
329
|
+
type: 'INVOICE',
|
|
330
|
+
date: '2024-09-01',
|
|
331
|
+
totalAmount: '500.00',
|
|
332
|
+
currencyCode: Currency.Usd,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-10-15'),
|
|
336
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-10'),
|
|
337
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
338
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
339
|
+
serialNumber: 'INV-2024-10-15',
|
|
340
|
+
type: 'INVOICE',
|
|
341
|
+
date: '2024-10-01',
|
|
342
|
+
totalAmount: '500.00',
|
|
343
|
+
currencyCode: Currency.Usd,
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-11-15'),
|
|
347
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-11'),
|
|
348
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
349
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
350
|
+
serialNumber: 'INV-2024-11-15',
|
|
351
|
+
type: 'INVOICE',
|
|
352
|
+
date: '2024-11-01',
|
|
353
|
+
totalAmount: '500.00',
|
|
354
|
+
currencyCode: Currency.Usd,
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
id: makeUUID('document', 'consulting-invoice-inv-2024-12-15'),
|
|
358
|
+
chargeId: makeUUID('charge', 'consulting-invoice-2024-12'),
|
|
359
|
+
creditorId: makeUUID('business', 'us-supplier-acme-llc'),
|
|
360
|
+
debtorId: '{{ADMIN_BUSINESS_ID}}',
|
|
361
|
+
serialNumber: 'INV-2024-12-15',
|
|
362
|
+
type: 'INVOICE',
|
|
363
|
+
date: '2024-12-01',
|
|
364
|
+
totalAmount: '500.00',
|
|
365
|
+
currencyCode: Currency.Usd,
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
},
|
|
369
|
+
metadata: {
|
|
370
|
+
author: 'demo-team',
|
|
371
|
+
createdAt: '2024-01-01',
|
|
372
|
+
updatedAt: '2024-01-01',
|
|
373
|
+
},
|
|
374
|
+
expectations: {
|
|
375
|
+
ledgerRecordCount: 24,
|
|
376
|
+
},
|
|
377
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { UseCaseSpec } from '../../../fixtures/fixture-spec.js';
|
|
2
|
+
import { CountryCode, Currency } from '../../../shared/enums.js';
|
|
3
|
+
import { makeUUID } from '../../helpers/deterministic-uuid.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Client Payment with Refund Cycle
|
|
7
|
+
*
|
|
8
|
+
* Models an income scenario where a client pays an invoice
|
|
9
|
+
* and later receives a partial refund via a credit invoice.
|
|
10
|
+
* Sign convention follows demo rules: negative amount = income,
|
|
11
|
+
* positive amount = reversal/refund.
|
|
12
|
+
*/
|
|
13
|
+
export const clientPaymentWithRefund: UseCaseSpec = {
|
|
14
|
+
id: 'client-payment-with-refund',
|
|
15
|
+
name: 'Client Payment with Refund',
|
|
16
|
+
description:
|
|
17
|
+
'Client invoice paid (income) followed by a partial refund via credit invoice. Uses ILS bank account.',
|
|
18
|
+
category: 'income',
|
|
19
|
+
fixtures: {
|
|
20
|
+
businesses: [
|
|
21
|
+
{
|
|
22
|
+
id: makeUUID('business', 'acme-retail-client'),
|
|
23
|
+
name: 'Acme Retail Client',
|
|
24
|
+
country: CountryCode['Israel'],
|
|
25
|
+
canSettleWithReceipt: false,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
taxCategories: [
|
|
29
|
+
{
|
|
30
|
+
id: makeUUID('tax-category', 'service-income'),
|
|
31
|
+
name: 'Service Income',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
financialAccounts: [
|
|
35
|
+
{
|
|
36
|
+
id: makeUUID('financial-account', 'bank-ils-account-income'),
|
|
37
|
+
accountNumber: '22-333-4444',
|
|
38
|
+
type: 'BANK_ACCOUNT',
|
|
39
|
+
currency: Currency.Ils,
|
|
40
|
+
taxCategoryMappings: [
|
|
41
|
+
{
|
|
42
|
+
taxCategoryId: makeUUID('tax-category', 'service-income'),
|
|
43
|
+
currency: Currency.Ils,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
charges: [
|
|
49
|
+
{
|
|
50
|
+
id: makeUUID('charge', 'client-invoice-2024-11'),
|
|
51
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
52
|
+
userDescription: 'Client invoice for November services',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: makeUUID('charge', 'client-refund-credit-2024-11'),
|
|
56
|
+
ownerId: '{{ADMIN_BUSINESS_ID}}',
|
|
57
|
+
userDescription: 'Refund credit for November services',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
transactions: [
|
|
61
|
+
{
|
|
62
|
+
id: makeUUID('transaction', 'client-payment-2024-11-15'),
|
|
63
|
+
chargeId: makeUUID('charge', 'client-invoice-2024-11'),
|
|
64
|
+
businessId: makeUUID('business', 'acme-retail-client'),
|
|
65
|
+
amount: '-2000.00',
|
|
66
|
+
currency: Currency.Ils,
|
|
67
|
+
eventDate: '2024-11-15',
|
|
68
|
+
debitDate: '2024-11-15',
|
|
69
|
+
accountNumber: '22-333-4444',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: makeUUID('transaction', 'client-refund-2024-11-20'),
|
|
73
|
+
chargeId: makeUUID('charge', 'client-refund-credit-2024-11'),
|
|
74
|
+
businessId: makeUUID('business', 'acme-retail-client'),
|
|
75
|
+
amount: '500.00',
|
|
76
|
+
currency: Currency.Ils,
|
|
77
|
+
eventDate: '2024-11-20',
|
|
78
|
+
debitDate: '2024-11-20',
|
|
79
|
+
accountNumber: '22-333-4444',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
documents: [
|
|
83
|
+
{
|
|
84
|
+
id: makeUUID('document', 'client-invoice-inv-2024-11-01'),
|
|
85
|
+
chargeId: makeUUID('charge', 'client-invoice-2024-11'),
|
|
86
|
+
creditorId: '{{ADMIN_BUSINESS_ID}}',
|
|
87
|
+
debtorId: makeUUID('business', 'acme-retail-client'),
|
|
88
|
+
serialNumber: 'INV-2024-11-01',
|
|
89
|
+
type: 'INVOICE',
|
|
90
|
+
date: '2024-11-01',
|
|
91
|
+
totalAmount: '2000.00',
|
|
92
|
+
currencyCode: Currency.Ils,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: makeUUID('document', 'client-credit-invoice-2024-11-20'),
|
|
96
|
+
chargeId: makeUUID('charge', 'client-refund-credit-2024-11'),
|
|
97
|
+
creditorId: '{{ADMIN_BUSINESS_ID}}',
|
|
98
|
+
debtorId: makeUUID('business', 'acme-retail-client'),
|
|
99
|
+
serialNumber: 'CR-2024-11-20',
|
|
100
|
+
type: 'CREDIT_INVOICE',
|
|
101
|
+
date: '2024-11-20',
|
|
102
|
+
totalAmount: '500.00',
|
|
103
|
+
currencyCode: Currency.Ils,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
metadata: {
|
|
108
|
+
author: 'demo-team',
|
|
109
|
+
createdAt: '2024-11-24',
|
|
110
|
+
updatedAt: '2024-11-24',
|
|
111
|
+
},
|
|
112
|
+
expectations: {
|
|
113
|
+
ledgerRecordCount: 4,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { UseCaseSpec } from '../../fixtures/fixture-spec.js';
|
|
2
|
+
import { shareholderDividend } from './equity/shareholder-dividend.js';
|
|
3
|
+
import { monthlyExpenseForeignCurrency } from './expenses/monthly-expense-foreign-currency.js';
|
|
4
|
+
import { clientPaymentWithRefund } from './income/client-payment-with-refund.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Central registry of all demo use-cases organized by category.
|
|
8
|
+
*
|
|
9
|
+
* Each category contains an array of use-case specifications that will be
|
|
10
|
+
* seeded into the staging environment. Use-cases are processed in the order
|
|
11
|
+
* they appear in each category array.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Adding a new use-case:
|
|
16
|
+
* import { monthlyExpense } from './expenses/monthly-expense.js';
|
|
17
|
+
*
|
|
18
|
+
* export const USE_CASE_REGISTRY: Record<string, UseCaseSpec[]> = {
|
|
19
|
+
* expenses: [monthlyExpense],
|
|
20
|
+
* income: [],
|
|
21
|
+
* equity: [],
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const USE_CASE_REGISTRY: Record<string, UseCaseSpec[]> = {
|
|
26
|
+
expenses: [monthlyExpenseForeignCurrency],
|
|
27
|
+
equity: [shareholderDividend],
|
|
28
|
+
income: [clientPaymentWithRefund],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get all registered use-cases across all categories.
|
|
33
|
+
*
|
|
34
|
+
* This function flattens the registry into a single array, maintaining
|
|
35
|
+
* the order: expenses first, then income, then equity (based on object
|
|
36
|
+
* key insertion order).
|
|
37
|
+
*
|
|
38
|
+
* @returns Array of all use-case specifications
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const allUseCases = getAllUseCases();
|
|
43
|
+
* console.log(`Total use-cases: ${allUseCases.length}`);
|
|
44
|
+
*
|
|
45
|
+
* allUseCases.forEach(useCase => {
|
|
46
|
+
* console.log(`${useCase.category}: ${useCase.name}`);
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function getAllUseCases(): UseCaseSpec[] {
|
|
51
|
+
return Object.values(USE_CASE_REGISTRY).flat();
|
|
52
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demo Data Validation Script
|
|
3
|
+
*
|
|
4
|
+
* Validates the integrity of seeded demo data with comprehensive ledger validation.
|
|
5
|
+
*
|
|
6
|
+
* Validation Checks:
|
|
7
|
+
* - Admin business entity exists
|
|
8
|
+
* - Charge count matches expected
|
|
9
|
+
* - Ledger records for each use-case:
|
|
10
|
+
* - Per-record internal balance (FR1)
|
|
11
|
+
* - Aggregate balance (FR2)
|
|
12
|
+
* - Entity-level balance (FR3)
|
|
13
|
+
* - No orphaned amounts (FR4)
|
|
14
|
+
* - Positive amounts only (FR5)
|
|
15
|
+
* - Foreign currency consistency (FR6)
|
|
16
|
+
* - Valid dates (FR7)
|
|
17
|
+
* - Record count matches (FR8)
|
|
18
|
+
*
|
|
19
|
+
* Exit codes:
|
|
20
|
+
* - 0: All validations passed
|
|
21
|
+
* - 1: Validation errors found or database connection failed
|
|
22
|
+
*/
|
|
23
|
+
import { config } from 'dotenv';
|
|
24
|
+
import pg from 'pg';
|
|
25
|
+
import { getAllUseCases } from './use-cases/index.js';
|
|
26
|
+
import { validateLedgerRecords } from './validators/ledger-validators.js';
|
|
27
|
+
import type { LedgerRecord, ValidationContext } from './validators/types.js';
|
|
28
|
+
|
|
29
|
+
config({
|
|
30
|
+
path: '../../.env',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const DEFAULT_CURRENCY = 'ILS';
|
|
34
|
+
const BALANCE_TOLERANCE = 0.005;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Main validation function - connects to DB and runs all checks
|
|
38
|
+
*/
|
|
39
|
+
async function validateDemoData() {
|
|
40
|
+
const client = new pg.Client({
|
|
41
|
+
user: process.env.POSTGRES_USER,
|
|
42
|
+
password: process.env.POSTGRES_PASSWORD,
|
|
43
|
+
host: process.env.POSTGRES_HOST,
|
|
44
|
+
port: parseInt(process.env.POSTGRES_PORT || '5432'),
|
|
45
|
+
database: process.env.POSTGRES_DB,
|
|
46
|
+
ssl: process.env.POSTGRES_SSL === '1',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const errors: string[] = [];
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
await client.connect();
|
|
53
|
+
|
|
54
|
+
// 1. Admin business exists
|
|
55
|
+
const adminCheck = await client.query(
|
|
56
|
+
`SELECT id FROM accounter_schema.financial_entities WHERE type = 'business' AND name = 'Accounter Admin Business'`,
|
|
57
|
+
);
|
|
58
|
+
if (adminCheck.rows.length === 0) {
|
|
59
|
+
errors.push('Admin business entity missing');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 2. Use-case charge count reconciliation
|
|
63
|
+
const useCases = getAllUseCases();
|
|
64
|
+
const expectedChargeCount = useCases.reduce((sum, uc) => sum + uc.fixtures.charges.length, 0);
|
|
65
|
+
const actualChargeCount = await client.query(`SELECT COUNT(*) FROM accounter_schema.charges`);
|
|
66
|
+
if (parseInt(actualChargeCount.rows[0].count) !== expectedChargeCount) {
|
|
67
|
+
errors.push(
|
|
68
|
+
`Charge count mismatch: expected ${expectedChargeCount}, got ${actualChargeCount.rows[0].count}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 3. Comprehensive ledger validation for all use-cases with expectations (FR9)
|
|
73
|
+
const useCasesWithExpectations = useCases.filter(uc => uc.expectations);
|
|
74
|
+
|
|
75
|
+
console.log(
|
|
76
|
+
`\nValidating ledger records for ${useCasesWithExpectations.length} use-case(s)...`,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
let ledgerRecordsExist = false;
|
|
80
|
+
|
|
81
|
+
for (const useCase of useCasesWithExpectations) {
|
|
82
|
+
// Get all charges for this use-case
|
|
83
|
+
const chargeIds = useCase.fixtures.charges.map(c => c.id);
|
|
84
|
+
|
|
85
|
+
// Fetch all ledger records for these charges
|
|
86
|
+
const ledgerRecords = await client.query<LedgerRecord>(
|
|
87
|
+
`SELECT * FROM accounter_schema.ledger_records WHERE charge_id = ANY($1) ORDER BY created_at`,
|
|
88
|
+
[chargeIds],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
if (ledgerRecords.rows.length === 0) {
|
|
92
|
+
// Ledger generation is separate from seeding - this is expected
|
|
93
|
+
console.log(` ⚠ ${useCase.id}: no ledger records (ledger generation not run)`);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
ledgerRecordsExist = true;
|
|
98
|
+
|
|
99
|
+
// Create validation context
|
|
100
|
+
const context: ValidationContext = {
|
|
101
|
+
useCaseId: useCase.id,
|
|
102
|
+
defaultCurrency: DEFAULT_CURRENCY,
|
|
103
|
+
tolerance: BALANCE_TOLERANCE,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Run comprehensive validation
|
|
107
|
+
const validationErrors = validateLedgerRecords(
|
|
108
|
+
ledgerRecords.rows,
|
|
109
|
+
useCase.expectations!.ledgerRecordCount,
|
|
110
|
+
context,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
errors.push(...validationErrors);
|
|
114
|
+
|
|
115
|
+
// Log progress
|
|
116
|
+
if (validationErrors.length === 0) {
|
|
117
|
+
console.log(` ✓ ${useCase.id} (${ledgerRecords.rows.length} records)`);
|
|
118
|
+
} else {
|
|
119
|
+
console.log(` ✗ ${useCase.id} (${validationErrors.length} error(s))`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!ledgerRecordsExist) {
|
|
124
|
+
console.log(
|
|
125
|
+
' ℹ️ Ledger records not found. Run ledger generation to create and validate ledger entries.',
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 4. VAT row present (percentage stored as decimal 0.17 for 17%)
|
|
130
|
+
const vatCheck = await client.query(
|
|
131
|
+
`SELECT 1 FROM accounter_schema.vat_value WHERE percentage = 0.17`,
|
|
132
|
+
);
|
|
133
|
+
if (vatCheck.rows.length === 0) {
|
|
134
|
+
errors.push('VAT default (17%) missing');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Report errors or success
|
|
138
|
+
if (errors.length > 0) {
|
|
139
|
+
console.error('❌ Validation failed:');
|
|
140
|
+
for (const err of errors) console.error(` - ${err}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log('✅ Demo data validation passed');
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('❌ Validation error:', error);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
} finally {
|
|
149
|
+
await client.end();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
validateDemoData();
|