@accounter/server 0.0.9-alpha-20251231123714-6cdd9de71b4672d74ece5d34c438d162987b2c93 → 0.0.9-alpha-20251231171312-67d2850c6eacafb65d42d987f3d49dca3c0f8bdd

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 (124) hide show
  1. package/CHANGELOG.md +27 -5
  2. package/README.md +66 -3
  3. package/dist/green-invoice-graphql/src/mesh-artifacts/index.d.ts +1 -1
  4. package/dist/green-invoice-graphql/src/mesh-artifacts/index.js +2 -2
  5. package/dist/green-invoice-graphql/src/mesh-artifacts/index.js.map +1 -1
  6. package/dist/server/scripts/seed-admin-context.js +20 -25
  7. package/dist/server/scripts/seed-admin-context.js.map +1 -1
  8. package/dist/server/src/__tests__/db-bootstrap.test.js +7 -2
  9. package/dist/server/src/__tests__/db-bootstrap.test.js.map +1 -1
  10. package/dist/server/src/__tests__/factories/business.d.ts +1 -1
  11. package/dist/server/src/__tests__/factories/financial-account.d.ts +1 -1
  12. package/dist/server/src/__tests__/factories/index.test.js +1 -0
  13. package/dist/server/src/__tests__/factories/index.test.js.map +1 -1
  14. package/dist/server/src/__tests__/factories/tax-category.d.ts +1 -1
  15. package/dist/server/src/__tests__/factories/tax-category.js +1 -1
  16. package/dist/server/src/__tests__/factories/tax-category.js.map +1 -1
  17. package/dist/server/src/__tests__/factories/tax-category.test.js +8 -6
  18. package/dist/server/src/__tests__/factories/tax-category.test.js.map +1 -1
  19. package/dist/server/src/__tests__/helpers/fixture-loader.d.ts +1 -1
  20. package/dist/server/src/__tests__/helpers/fixture-loader.js +25 -52
  21. package/dist/server/src/__tests__/helpers/fixture-loader.js.map +1 -1
  22. package/dist/server/src/__tests__/helpers/migration-verification.d.ts +1 -1
  23. package/dist/server/src/__tests__/helpers/migration-verification.js.map +1 -1
  24. package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js +4 -4
  25. package/dist/server/src/__tests__/helpers/seed-helpers.business.test.js.map +1 -1
  26. package/dist/server/src/__tests__/helpers/seed-helpers.d.ts +9 -9
  27. package/dist/server/src/__tests__/helpers/seed-helpers.js +57 -54
  28. package/dist/server/src/__tests__/helpers/seed-helpers.js.map +1 -1
  29. package/dist/server/src/__tests__/seed-admin-context.integration.test.js +2 -1
  30. package/dist/server/src/__tests__/seed-admin-context.integration.test.js.map +1 -1
  31. package/dist/server/src/demo-fixtures/__tests__/deterministic-uuid.test.js +3 -2
  32. package/dist/server/src/demo-fixtures/__tests__/deterministic-uuid.test.js.map +1 -1
  33. package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.d.ts +1 -0
  34. package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.js +69 -0
  35. package/dist/server/src/demo-fixtures/__tests__/seed-and-validate.test.js.map +1 -0
  36. package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.d.ts +1 -0
  37. package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.js +26 -0
  38. package/dist/server/src/demo-fixtures/__tests__/use-case-registry.test.js.map +1 -0
  39. package/dist/server/src/demo-fixtures/helpers/admin-context.d.ts +10 -0
  40. package/dist/server/src/demo-fixtures/helpers/admin-context.js +40 -0
  41. package/dist/server/src/demo-fixtures/helpers/admin-context.js.map +1 -0
  42. package/dist/server/src/demo-fixtures/helpers/placeholder.d.ts +45 -0
  43. package/dist/server/src/demo-fixtures/helpers/placeholder.js +50 -0
  44. package/dist/server/src/demo-fixtures/helpers/placeholder.js.map +1 -0
  45. package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.d.ts +21 -0
  46. package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.js +26 -0
  47. package/dist/server/src/demo-fixtures/helpers/seed-exchange-rates.js.map +1 -0
  48. package/dist/server/src/demo-fixtures/helpers/seed-vat.d.ts +20 -0
  49. package/dist/server/src/demo-fixtures/helpers/seed-vat.js +30 -0
  50. package/dist/server/src/demo-fixtures/helpers/seed-vat.js.map +1 -0
  51. package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.d.ts +9 -0
  52. package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.js +86 -0
  53. package/dist/server/src/demo-fixtures/use-cases/equity/shareholder-dividend.js.map +1 -0
  54. package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.d.ts +12 -0
  55. package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.js +375 -0
  56. package/dist/server/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.js.map +1 -0
  57. package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.d.ts +10 -0
  58. package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.js +113 -0
  59. package/dist/server/src/demo-fixtures/use-cases/income/client-payment-with-refund.js.map +1 -0
  60. package/dist/server/src/demo-fixtures/use-cases/index.d.ts +41 -0
  61. package/dist/server/src/demo-fixtures/use-cases/index.js +50 -0
  62. package/dist/server/src/demo-fixtures/use-cases/index.js.map +1 -0
  63. package/dist/server/src/demo-fixtures/validate-demo-data.d.ts +1 -0
  64. package/dist/server/src/demo-fixtures/validate-demo-data.js +117 -0
  65. package/dist/server/src/demo-fixtures/validate-demo-data.js.map +1 -0
  66. package/dist/server/src/demo-fixtures/validators/ledger-validators.d.ts +349 -0
  67. package/dist/server/src/demo-fixtures/validators/ledger-validators.js +602 -0
  68. package/dist/server/src/demo-fixtures/validators/ledger-validators.js.map +1 -0
  69. package/dist/server/src/demo-fixtures/validators/ledger-validators.test.d.ts +1 -0
  70. package/dist/server/src/demo-fixtures/validators/ledger-validators.test.js +247 -0
  71. package/dist/server/src/demo-fixtures/validators/ledger-validators.test.js.map +1 -0
  72. package/dist/server/src/demo-fixtures/validators/types.d.ts +69 -0
  73. package/dist/server/src/demo-fixtures/validators/types.js +8 -0
  74. package/dist/server/src/demo-fixtures/validators/types.js.map +1 -0
  75. package/dist/server/src/fixtures/fixture-spec.d.ts +146 -0
  76. package/dist/server/src/fixtures/fixture-spec.js +2 -0
  77. package/dist/server/src/fixtures/fixture-spec.js.map +1 -0
  78. package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js +4 -0
  79. package/dist/server/src/modules/charges-matcher/__tests__/single-match-integration.test.js.map +1 -1
  80. package/dist/server/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.js +4 -3
  81. package/dist/server/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.js.map +1 -1
  82. package/dist/server/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.js +5 -3
  83. package/dist/server/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.js.map +1 -1
  84. package/dist/server/src/shared/constants.d.ts +1 -0
  85. package/dist/server/src/shared/constants.js +1 -0
  86. package/dist/server/src/shared/constants.js.map +1 -1
  87. package/dist/server/src/shared/helpers/misc.js +2 -2
  88. package/dist/server/src/shared/helpers/misc.js.map +1 -1
  89. package/docs/demo-staging-guide.md +611 -0
  90. package/package.json +5 -2
  91. package/scripts/seed-admin-context.ts +22 -33
  92. package/src/__tests__/db-bootstrap.test.ts +9 -2
  93. package/src/__tests__/factories/business.ts +1 -1
  94. package/src/__tests__/factories/financial-account.ts +1 -1
  95. package/src/__tests__/factories/index.test.ts +1 -0
  96. package/src/__tests__/factories/tax-category.test.ts +8 -6
  97. package/src/__tests__/factories/tax-category.ts +2 -2
  98. package/src/__tests__/helpers/fixture-loader.ts +26 -61
  99. package/src/__tests__/helpers/migration-verification.ts +2 -2
  100. package/src/__tests__/helpers/seed-helpers.business.test.ts +4 -4
  101. package/src/__tests__/helpers/seed-helpers.ts +66 -75
  102. package/src/__tests__/seed-admin-context.integration.test.ts +2 -1
  103. package/src/demo-fixtures/__tests__/deterministic-uuid.test.ts +3 -2
  104. package/src/demo-fixtures/__tests__/seed-and-validate.test.ts +96 -0
  105. package/src/demo-fixtures/__tests__/use-case-registry.test.ts +27 -0
  106. package/src/demo-fixtures/helpers/admin-context.ts +59 -0
  107. package/src/demo-fixtures/helpers/placeholder.ts +50 -0
  108. package/src/demo-fixtures/helpers/seed-exchange-rates.ts +29 -0
  109. package/src/demo-fixtures/helpers/seed-vat.ts +35 -0
  110. package/src/demo-fixtures/use-cases/equity/shareholder-dividend.ts +88 -0
  111. package/src/demo-fixtures/use-cases/expenses/monthly-expense-foreign-currency.ts +377 -0
  112. package/src/demo-fixtures/use-cases/income/client-payment-with-refund.ts +115 -0
  113. package/src/demo-fixtures/use-cases/index.ts +52 -0
  114. package/src/demo-fixtures/validate-demo-data.ts +153 -0
  115. package/src/demo-fixtures/validators/README.md +190 -0
  116. package/src/demo-fixtures/validators/ledger-validators.test.ts +298 -0
  117. package/src/demo-fixtures/validators/ledger-validators.ts +711 -0
  118. package/src/demo-fixtures/validators/types.ts +83 -0
  119. package/src/fixtures/fixture-spec.ts +158 -0
  120. package/src/modules/charges-matcher/__tests__/single-match-integration.test.ts +6 -0
  121. package/src/modules/ledger/__tests__/ledger-scenario-a.integration.test.ts +4 -3
  122. package/src/modules/ledger/__tests__/ledger-scenario-b.integration.test.ts +6 -3
  123. package/src/shared/constants.ts +2 -0
  124. package/src/shared/helpers/misc.ts +2 -3
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { makeUUID } from '../helpers/deterministic-uuid.js';
3
+ import { UUID5_REGEX } from 'shared/constants.js';
3
4
 
4
5
  describe('deterministic-uuid', () => {
5
6
  describe('makeUUID', () => {
@@ -8,7 +9,7 @@ describe('deterministic-uuid', () => {
8
9
  const uuid2 = makeUUID('business', 'acme-consulting-llc');
9
10
 
10
11
  expect(uuid1).toBe(uuid2);
11
- expect(uuid1).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
12
+ expect(uuid1).toMatch(UUID5_REGEX);
12
13
  });
13
14
 
14
15
  it('generates different UUIDs for different names', () => {
@@ -41,7 +42,7 @@ describe('deterministic-uuid', () => {
41
42
 
42
43
  // UUID v5 format: xxxxxxxx-xxxx-5xxx-yxxx-xxxxxxxxxxxx
43
44
  // where y is one of [8, 9, a, b]
44
- expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
45
+ expect(uuid).toMatch(UUID5_REGEX);
45
46
  });
46
47
 
47
48
  it('handles kebab-case names correctly', () => {
@@ -0,0 +1,96 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { spawn } from 'child_process';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, resolve } from 'path';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+
9
+ /**
10
+ * Integration test: Seed demo data and validate
11
+ *
12
+ * This test runs the full seed + validate pipeline to ensure:
13
+ * 1. Seed script completes successfully (exit code 0)
14
+ * 2. Validation script passes all checks (exit code 0)
15
+ * 3. End-to-end data integrity from seed to validation
16
+ *
17
+ * Prerequisites:
18
+ * - Database connection available
19
+ * - ALLOW_DEMO_SEED=1 environment variable set
20
+ * - Migrations applied
21
+ *
22
+ * Note: This is a slow test (~10-30 seconds) and should be run separately
23
+ * or marked as integration test in CI/CD pipelines.
24
+ */
25
+ describe('Seed and Validate Integration', () => {
26
+ // Increase timeout for this integration test (30 seconds)
27
+ it(
28
+ 'seeds demo data and passes validation',
29
+ async () => {
30
+ // Check for stale migrations before running the test
31
+ if (process.env.SKIP_DEMO_SEED_STALE_MIGRATIONS === '1') {
32
+ throw new Error(
33
+ 'Demo-seed test failed: migrations are stale. Run: yarn workspace @accounter/migrations migration:run',
34
+ );
35
+ }
36
+
37
+ const workspaceRoot = resolve(__dirname, '../../../../../');
38
+ const seedScriptPath = resolve(workspaceRoot, 'scripts/seed-demo-data.ts');
39
+ const validateScriptPath = resolve(
40
+ workspaceRoot,
41
+ 'packages/server/src/demo-fixtures/validate-demo-data.ts',
42
+ );
43
+ const registerEsmPath = resolve(workspaceRoot, 'scripts/register-esm.js');
44
+
45
+ // Step 1: Run seed script
46
+ const seedExitCode = await new Promise<number>((resolve, reject) => {
47
+ const seedProcess = spawn(
48
+ 'node',
49
+ ['--import', registerEsmPath, seedScriptPath],
50
+ {
51
+ cwd: workspaceRoot,
52
+ env: {
53
+ ...process.env,
54
+ ALLOW_DEMO_SEED: '1',
55
+ },
56
+ stdio: 'inherit', // Show output for debugging
57
+ },
58
+ );
59
+
60
+ seedProcess.on('close', code => {
61
+ resolve(code ?? 1);
62
+ });
63
+
64
+ seedProcess.on('error', err => {
65
+ reject(err);
66
+ });
67
+ });
68
+
69
+ expect(seedExitCode).toBe(0);
70
+
71
+ // Step 2: Run validation script
72
+ const validateExitCode = await new Promise<number>((resolve, reject) => {
73
+ const validateProcess = spawn(
74
+ 'node',
75
+ ['--import', registerEsmPath, validateScriptPath],
76
+ {
77
+ cwd: workspaceRoot,
78
+ env: process.env,
79
+ stdio: 'inherit',
80
+ },
81
+ );
82
+
83
+ validateProcess.on('close', code => {
84
+ resolve(code ?? 1);
85
+ });
86
+
87
+ validateProcess.on('error', err => {
88
+ reject(err);
89
+ });
90
+ });
91
+
92
+ expect(validateExitCode).toBe(0);
93
+ },
94
+ 30000,
95
+ ); // 30 second timeout
96
+ });
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getAllUseCases } from '../use-cases/index.js';
3
+
4
+ describe('Use-Case Registry', () => {
5
+ it('has no duplicate IDs across all categories', () => {
6
+ const allUseCases = getAllUseCases();
7
+ const ids = allUseCases.map(uc => uc.id);
8
+ const unique = new Set(ids);
9
+ expect(unique.size).toBe(ids.length);
10
+ });
11
+
12
+ it('all use-cases have required fields', () => {
13
+ const allUseCases = getAllUseCases();
14
+ allUseCases.forEach(uc => {
15
+ expect(uc.id).toBeTruthy();
16
+ expect(uc.name).toBeTruthy();
17
+ expect(uc.category).toBeTruthy();
18
+ expect(uc.fixtures).toBeDefined();
19
+ expect(Array.isArray(uc.fixtures.businesses)).toBe(true);
20
+ expect(Array.isArray(uc.fixtures.taxCategories)).toBe(true);
21
+ expect(Array.isArray(uc.fixtures.financialAccounts)).toBe(true);
22
+ expect(Array.isArray(uc.fixtures.charges)).toBe(true);
23
+ expect(Array.isArray(uc.fixtures.transactions)).toBe(true);
24
+ expect(Array.isArray(uc.fixtures.documents)).toBe(true);
25
+ });
26
+ });
27
+ });
@@ -0,0 +1,59 @@
1
+ import type { Client } from 'pg';
2
+ import { makeUUID } from './deterministic-uuid.js';
3
+
4
+ /**
5
+ * Create (or fetch) the Accounter Admin Business financial entity and return its id.
6
+ *
7
+ * Simplified logic:
8
+ * - Looks up existing row by id or by (type='business' AND name='Accounter Admin Business').
9
+ * - If not found, inserts a self-owned business entity with a deterministic id.
10
+ * - Returns the id of the Accounter Admin Business entity.
11
+ */
12
+ export async function createAdminBusinessContext(client: Client): Promise<string> {
13
+ const deterministicId = makeUUID('business', 'admin-business');
14
+
15
+ // 1) Try find by deterministic id or by semantic key (type+name)
16
+ const findResult = await client.query<{ id: string }>(
17
+ `SELECT id
18
+ FROM accounter_schema.financial_entities
19
+ WHERE id = $1 OR (type = 'business' AND name = 'Accounter Admin Business')
20
+ LIMIT 1`,
21
+ [deterministicId],
22
+ );
23
+
24
+ if (findResult.rows.length > 0) {
25
+ return findResult.rows[0].id;
26
+ }
27
+
28
+ // 2) Handle circular FK: financial_entities.owner_id → businesses.id ← businesses.id → financial_entities.id
29
+ // Resolution strategy:
30
+ // a) Insert financial_entity with NULL owner_id (breaks circular dependency temporarily)
31
+ // b) Insert business row (now has valid financial_entity reference)
32
+ // c) Update financial_entity to set owner_id = self (closes the circle)
33
+ //
34
+ // This 3-step process is necessary because PostgreSQL doesn't support DEFERRABLE
35
+ // constraints on our foreign keys, and we need both tables to reference each other.
36
+ const adminId = deterministicId;
37
+ await client.query(
38
+ `INSERT INTO accounter_schema.financial_entities (id, type, name, owner_id)
39
+ VALUES ($1, 'business', 'Accounter Admin Business', NULL)`,
40
+ [adminId],
41
+ );
42
+
43
+ // 3) Insert business row (references financial_entity)
44
+ await client.query(
45
+ `INSERT INTO accounter_schema.businesses (id)
46
+ VALUES ($1)`,
47
+ [adminId],
48
+ );
49
+
50
+ // 4) Update financial_entity to set owner_id (self-reference)
51
+ await client.query(
52
+ `UPDATE accounter_schema.financial_entities
53
+ SET owner_id = $1
54
+ WHERE id = $1`,
55
+ [adminId],
56
+ );
57
+
58
+ return adminId;
59
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Placeholder strings used in demo fixtures for runtime replacement.
3
+ */
4
+ export const PLACEHOLDERS = {
5
+ ADMIN_BUSINESS_ID: '{{ADMIN_BUSINESS_ID}}',
6
+ } as const;
7
+
8
+ /**
9
+ * Resolve admin business ID placeholders in fixture objects.
10
+ *
11
+ * This function performs a deep replacement of all `{{ADMIN_BUSINESS_ID}}` placeholder
12
+ * strings within a fixture object by serializing to JSON, replacing all occurrences,
13
+ * and deserializing back to the original type.
14
+ *
15
+ * @param fixture - Fixture object containing placeholders (any type)
16
+ * @param adminBusinessId - The actual admin business UUID to replace placeholders with
17
+ * @returns New fixture object with all placeholders replaced
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const fixture = {
22
+ * id: 'charge-123',
23
+ * ownerId: '{{ADMIN_BUSINESS_ID}}',
24
+ * nested: {
25
+ * businessId: '{{ADMIN_BUSINESS_ID}}'
26
+ * }
27
+ * };
28
+ *
29
+ * const resolved = resolveAdminPlaceholders(fixture, 'actual-uuid-123');
30
+ * // {
31
+ * // id: 'charge-123',
32
+ * // ownerId: 'actual-uuid-123',
33
+ * // nested: { businessId: 'actual-uuid-123' }
34
+ * // }
35
+ * ```
36
+ *
37
+ * @remarks
38
+ * **Performance Note:**
39
+ * Uses JSON serialization for deep replacement. For very large fixture objects,
40
+ * consider a more optimized approach if performance becomes an issue.
41
+ *
42
+ * **Type Safety:**
43
+ * Returns the same type as input, but type information is lost during JSON
44
+ * serialization (e.g., Date objects become strings). Use with plain object fixtures.
45
+ */
46
+ export function resolveAdminPlaceholders<T>(fixture: T, adminBusinessId: string): T {
47
+ const json = JSON.stringify(fixture);
48
+ const resolved = json.replace(/\{\{ADMIN_BUSINESS_ID\}\}/g, adminBusinessId);
49
+ return JSON.parse(resolved) as T;
50
+ }
@@ -0,0 +1,29 @@
1
+ import type { Client } from 'pg';
2
+
3
+ /**
4
+ * Seed FIAT exchange rates for demo data.
5
+ *
6
+ * Inserts or updates exchange rates for common currencies to ILS.
7
+ * Uses ON CONFLICT to ensure idempotent seeding.
8
+ *
9
+ * **Schema Note**: The exchange_rates table stores rates as individual columns
10
+ * (usd, eur, gbp, etc.) for a given exchange_date, NOT as normalized rows.
11
+ * This denormalized structure optimizes read performance for multi-currency queries.
12
+ *
13
+ * Example row:
14
+ * | exchange_date | usd | eur | gbp |
15
+ * | 2024-11-26 | 3.5 | 4.0 | 4.5 |
16
+ *
17
+ * Rates seeded:
18
+ * - USD: 3.5 ILS
19
+ * - EUR: 4.0 ILS
20
+ * - GBP: 4.5 ILS
21
+ */
22
+ export async function seedExchangeRates(client: Client): Promise<void> {
23
+ await client.query(
24
+ `INSERT INTO accounter_schema.exchange_rates (exchange_date, usd, eur, gbp)
25
+ VALUES (CURRENT_DATE, 3.5, 4.0, 4.5)
26
+ ON CONFLICT (exchange_date)
27
+ DO UPDATE SET usd = EXCLUDED.usd, eur = EXCLUDED.eur, gbp = EXCLUDED.gbp`,
28
+ );
29
+ }
@@ -0,0 +1,35 @@
1
+ import type { Client } from 'pg';
2
+
3
+ /**
4
+ * Seed VAT percentage history for demo data.
5
+ *
6
+ * Inserts historical VAT rates with effective dates. Israel's VAT has changed
7
+ * over time, so we maintain a history table to support accurate calculations
8
+ * for documents from different time periods.
9
+ *
10
+ * **Schema Note**: Percentage stored as decimal (0.17 = 17%), not integer.
11
+ * Column name is 'date', not 'effective_date' or 'effectiveDate'.
12
+ *
13
+ * Current rates:
14
+ * - 17% effective from 2015-01-01
15
+ * - 18% effective from 2025-01-01
16
+ *
17
+ * Uses ON CONFLICT to ensure idempotency across multiple seed runs.
18
+ *
19
+ * @param client - PostgreSQL client instance
20
+ */
21
+ export async function seedVATDefault(client: Client): Promise<void> {
22
+ const vatRates = [
23
+ { percentage: 0.17, date: '2015-01-01' },
24
+ { percentage: 0.18, date: '2025-01-01' },
25
+ ];
26
+
27
+ for (const { percentage, date } of vatRates) {
28
+ await client.query(
29
+ `INSERT INTO accounter_schema.vat_value (percentage, date)
30
+ VALUES ($1, $2)
31
+ ON CONFLICT (date) DO NOTHING`,
32
+ [percentage, date],
33
+ );
34
+ }
35
+ }
@@ -0,0 +1,88 @@
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
+ * Shareholder Dividend (Q4 2024)
7
+ *
8
+ * Models a dividend payout in ILS with a single transaction
9
+ * and optional statement document. Designed as a simple
10
+ * equity scenario with minimal entities.
11
+ */
12
+ export const shareholderDividend: UseCaseSpec = {
13
+ id: 'shareholder-dividend',
14
+ name: 'Shareholder Dividend (Q4 2024)',
15
+ description:
16
+ 'Dividend payout from ILS bank account with withholding tax counterparty. Includes optional statement document.',
17
+ category: 'equity',
18
+ fixtures: {
19
+ businesses: [
20
+ {
21
+ id: makeUUID('business', 'dividends-withholding-tax'),
22
+ name: 'Dividends Withholding Tax',
23
+ country: CountryCode['Israel'],
24
+ canSettleWithReceipt: false,
25
+ },
26
+ ],
27
+ taxCategories: [
28
+ {
29
+ id: makeUUID('tax-category', 'dividend'),
30
+ name: 'Dividend',
31
+ },
32
+ ],
33
+ financialAccounts: [
34
+ {
35
+ id: makeUUID('financial-account', 'bank-ils-account'),
36
+ accountNumber: '11-222-3333',
37
+ type: 'BANK_ACCOUNT',
38
+ currency: Currency.Ils,
39
+ taxCategoryMappings: [
40
+ {
41
+ taxCategoryId: makeUUID('tax-category', 'dividend'),
42
+ currency: Currency.Ils,
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ charges: [
48
+ {
49
+ id: makeUUID('charge', 'dividend-distribution-2024-q4'),
50
+ ownerId: '{{ADMIN_BUSINESS_ID}}',
51
+ userDescription: 'Dividend distribution for Q4 2024',
52
+ },
53
+ ],
54
+ transactions: [
55
+ {
56
+ id: makeUUID('transaction', 'dividend-payout-2024-q4'),
57
+ chargeId: makeUUID('charge', 'dividend-distribution-2024-q4'),
58
+ businessId: makeUUID('business', 'dividends-withholding-tax'),
59
+ amount: '-10000.00',
60
+ currency: Currency.Ils,
61
+ eventDate: '2024-12-31',
62
+ debitDate: '2024-12-31',
63
+ accountNumber: '11-222-3333',
64
+ },
65
+ ],
66
+ documents: [
67
+ {
68
+ id: makeUUID('document', 'dividend-statement-2024-q4'),
69
+ chargeId: makeUUID('charge', 'dividend-distribution-2024-q4'),
70
+ creditorId: makeUUID('business', 'dividends-withholding-tax'),
71
+ debtorId: '{{ADMIN_BUSINESS_ID}}',
72
+ serialNumber: 'DIV-2024-Q4',
73
+ type: 'INVOICE',
74
+ date: '2024-12-31',
75
+ totalAmount: '10000.00',
76
+ currencyCode: Currency.Ils,
77
+ },
78
+ ],
79
+ },
80
+ metadata: {
81
+ author: 'demo-team',
82
+ createdAt: '2024-11-24',
83
+ updatedAt: '2024-11-24',
84
+ },
85
+ expectations: {
86
+ ledgerRecordCount: 2,
87
+ },
88
+ };