@tailor-platform/erp-kit 0.8.0 → 0.9.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 (159) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +1 -1
  3. package/skills/erp-kit-app-1-requirements/SKILL.md +6 -0
  4. package/skills/erp-kit-app-2-requirements-review/SKILL.md +6 -0
  5. package/skills/erp-kit-app-3-plan/SKILL.md +6 -0
  6. package/skills/erp-kit-app-4-plan-review/SKILL.md +6 -0
  7. package/skills/erp-kit-app-5-impl-backend/SKILL.md +7 -0
  8. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +6 -0
  9. package/skills/erp-kit-app-7-impl-review/SKILL.md +6 -0
  10. package/skills/erp-kit-app-shared/SKILL.md +2 -0
  11. package/skills/erp-kit-mock-scenario/SKILL.md +6 -0
  12. package/skills/erp-kit-module-1-requirements/SKILL.md +6 -0
  13. package/skills/erp-kit-module-2-requirements-review/SKILL.md +6 -0
  14. package/skills/erp-kit-module-3-plan/SKILL.md +6 -0
  15. package/skills/erp-kit-module-3-update-plan/SKILL.md +6 -0
  16. package/skills/erp-kit-module-4-plan-review/SKILL.md +6 -0
  17. package/skills/erp-kit-module-5-impl/SKILL.md +6 -0
  18. package/skills/erp-kit-module-6-impl-review/SKILL.md +6 -0
  19. package/skills/erp-kit-module-shared/SKILL.md +2 -0
  20. package/skills/erp-kit-module-shared/references/commands.md +3 -0
  21. package/skills/erp-kit-update/SKILL.md +6 -0
  22. package/src/modules/accounting/command/assignProfitCenterToHierarchyNode.test.ts +3 -3
  23. package/src/modules/accounting/command/assignProfitCenterToHierarchyNode.ts +1 -1
  24. package/src/modules/accounting/command/createCostCenterHierarchyNode.test.ts +3 -3
  25. package/src/modules/accounting/command/createCostCenterHierarchyNode.ts +1 -1
  26. package/src/modules/accounting/command/moveCostCenterHierarchyNode.test.ts +2 -2
  27. package/src/modules/accounting/command/moveCostCenterHierarchyNode.ts +1 -1
  28. package/src/modules/accounting/module.ts +1 -0
  29. package/src/modules/business-partner/command/createPartnerBankAccount.test.ts +3 -3
  30. package/src/modules/business-partner/command/createPartnerBankAccount.ts +1 -1
  31. package/src/modules/business-partner/module.ts +1 -0
  32. package/src/modules/coa-management/command/activateAccount.test.ts +0 -15
  33. package/src/modules/coa-management/command/activateAccount.ts +1 -42
  34. package/src/modules/coa-management/command/activateChartOfAccounts.test.ts +2 -31
  35. package/src/modules/coa-management/command/activateChartOfAccounts.ts +1 -37
  36. package/src/modules/coa-management/command/createAccount.test.ts +0 -28
  37. package/src/modules/coa-management/command/createAccount.ts +0 -43
  38. package/src/modules/coa-management/command/createAccountGroup.test.ts +2 -51
  39. package/src/modules/coa-management/command/createAccountGroup.ts +1 -56
  40. package/src/modules/coa-management/command/createChartOfAccounts.test.ts +1 -49
  41. package/src/modules/coa-management/command/createChartOfAccounts.ts +0 -51
  42. package/src/modules/coa-management/command/deactivateAccount.test.ts +0 -15
  43. package/src/modules/coa-management/command/deactivateAccount.ts +1 -53
  44. package/src/modules/coa-management/command/deactivateChartOfAccounts.test.ts +2 -29
  45. package/src/modules/coa-management/command/deactivateChartOfAccounts.ts +1 -37
  46. package/src/modules/coa-management/command/deleteAccount.test.ts +0 -13
  47. package/src/modules/coa-management/command/deleteAccount.ts +1 -42
  48. package/src/modules/coa-management/command/deleteAccountGroup.test.ts +0 -19
  49. package/src/modules/coa-management/command/deleteAccountGroup.ts +1 -42
  50. package/src/modules/coa-management/command/deleteChartOfAccounts.test.ts +2 -58
  51. package/src/modules/coa-management/command/deleteChartOfAccounts.ts +4 -88
  52. package/src/modules/coa-management/command/moveAccountGroup.test.ts +0 -27
  53. package/src/modules/coa-management/command/moveAccountGroup.ts +1 -48
  54. package/src/modules/coa-management/command/reactivateAccount.test.ts +0 -15
  55. package/src/modules/coa-management/command/reactivateAccount.ts +1 -53
  56. package/src/modules/coa-management/command/updateAccount.test.ts +0 -15
  57. package/src/modules/coa-management/command/updateAccount.ts +0 -92
  58. package/src/modules/coa-management/command/updateAccountGroup.test.ts +0 -20
  59. package/src/modules/coa-management/command/updateAccountGroup.ts +1 -61
  60. package/src/modules/coa-management/command/updateChartOfAccounts.test.ts +2 -31
  61. package/src/modules/coa-management/command/updateChartOfAccounts.ts +1 -50
  62. package/src/modules/coa-management/docs/commands/ActivateAccount.md +1 -4
  63. package/src/modules/coa-management/docs/commands/ActivateChartOfAccounts.md +1 -4
  64. package/src/modules/coa-management/docs/commands/CreateAccount.md +1 -4
  65. package/src/modules/coa-management/docs/commands/CreateAccountGroup.md +2 -5
  66. package/src/modules/coa-management/docs/commands/CreateChartOfAccounts.md +2 -6
  67. package/src/modules/coa-management/docs/commands/DeactivateAccount.md +1 -4
  68. package/src/modules/coa-management/docs/commands/DeactivateChartOfAccounts.md +1 -4
  69. package/src/modules/coa-management/docs/commands/DeleteAccount.md +1 -4
  70. package/src/modules/coa-management/docs/commands/DeleteAccountGroup.md +1 -4
  71. package/src/modules/coa-management/docs/commands/DeleteChartOfAccounts.md +1 -6
  72. package/src/modules/coa-management/docs/commands/MoveAccountGroup.md +1 -4
  73. package/src/modules/coa-management/docs/commands/ReactivateAccount.md +1 -4
  74. package/src/modules/coa-management/docs/commands/UpdateAccount.md +1 -4
  75. package/src/modules/coa-management/docs/commands/UpdateAccountGroup.md +2 -5
  76. package/src/modules/coa-management/docs/commands/UpdateChartOfAccounts.md +1 -4
  77. package/src/modules/coa-management/module.ts +16 -27
  78. package/src/modules/finance-ledger/module.ts +1 -0
  79. package/src/modules/inventory/command/approveInventoryAdjustment.test.ts +1 -1
  80. package/src/modules/inventory/command/approveInventoryAdjustment.ts +1 -1
  81. package/src/modules/inventory/command/cancelStockMovement.test.ts +2 -2
  82. package/src/modules/inventory/command/cancelStockMovement.ts +1 -1
  83. package/src/modules/inventory/command/confirmInventoryAdjustment.test.ts +4 -4
  84. package/src/modules/inventory/command/confirmInventoryAdjustment.ts +1 -1
  85. package/src/modules/inventory/command/confirmStockMovement.test.ts +1 -1
  86. package/src/modules/inventory/command/confirmStockMovement.ts +1 -1
  87. package/src/modules/inventory/command/createInventoryAdjustment.test.ts +6 -6
  88. package/src/modules/inventory/command/createInventoryAdjustment.ts +1 -1
  89. package/src/modules/inventory/command/createStockMovement.test.ts +3 -3
  90. package/src/modules/inventory/command/createStockMovement.ts +1 -1
  91. package/src/modules/inventory/command/executeStockMovement.test.ts +5 -5
  92. package/src/modules/inventory/command/executeStockMovement.ts +1 -1
  93. package/src/modules/inventory/command/rejectInventoryAdjustment.test.ts +1 -1
  94. package/src/modules/inventory/command/rejectInventoryAdjustment.ts +1 -1
  95. package/src/modules/inventory/command/reviseInventoryAdjustment.test.ts +2 -2
  96. package/src/modules/inventory/command/reviseInventoryAdjustment.ts +1 -1
  97. package/src/modules/inventory/command/submitInventoryAdjustment.test.ts +1 -1
  98. package/src/modules/inventory/command/submitInventoryAdjustment.ts +1 -1
  99. package/src/modules/inventory/command/updateStockMovement.test.ts +4 -4
  100. package/src/modules/inventory/command/updateStockMovement.ts +2 -2
  101. package/src/modules/inventory/module.ts +1 -0
  102. package/src/modules/item-management/command/createTaxonomyNode.test.ts +4 -4
  103. package/src/modules/item-management/command/createTaxonomyNode.ts +1 -1
  104. package/src/modules/item-management/command/moveTaxonomyNode.test.ts +2 -2
  105. package/src/modules/item-management/command/moveTaxonomyNode.ts +2 -2
  106. package/src/modules/item-management/command/updateTaxonomyNode.test.ts +2 -2
  107. package/src/modules/item-management/command/updateTaxonomyNode.ts +1 -1
  108. package/src/modules/item-management/module.ts +1 -0
  109. package/src/modules/manufacturing/command/createRouting.ts +1 -1
  110. package/src/modules/manufacturing/command/recordInventoryIssueOutcome.test.ts +1 -1
  111. package/src/modules/manufacturing/command/recordInventoryIssueOutcome.ts +1 -1
  112. package/src/modules/manufacturing/command/recordManufacturingCostSettlementAcknowledgment.test.ts +1 -1
  113. package/src/modules/manufacturing/command/recordManufacturingCostSettlementAcknowledgment.ts +1 -1
  114. package/src/modules/manufacturing/command/reviewManufacturingCostSummary.test.ts +1 -1
  115. package/src/modules/manufacturing/command/reviewManufacturingCostSummary.ts +1 -1
  116. package/src/modules/manufacturing/command/updateRouting.ts +1 -1
  117. package/src/modules/manufacturing/module.ts +1 -0
  118. package/src/modules/organization/module.ts +1 -0
  119. package/src/modules/primitives/module.ts +1 -0
  120. package/src/modules/product-management/command/assignProductToCategory.test.ts +2 -2
  121. package/src/modules/product-management/command/assignProductToCategory.ts +2 -2
  122. package/src/modules/product-management/command/createProductAttribute.test.ts +1 -1
  123. package/src/modules/product-management/command/createProductAttribute.ts +1 -1
  124. package/src/modules/product-management/command/createProductAttributeValue.test.ts +1 -1
  125. package/src/modules/product-management/command/createProductAttributeValue.ts +1 -1
  126. package/src/modules/product-management/command/createProductCategory.test.ts +2 -2
  127. package/src/modules/product-management/command/createProductCategory.ts +1 -1
  128. package/src/modules/product-management/command/setProductAttributeAssignment.test.ts +3 -3
  129. package/src/modules/product-management/command/setProductAttributeAssignment.ts +2 -2
  130. package/src/modules/product-management/module.ts +1 -0
  131. package/src/modules/purchase/command/activatePurchasePaymentTerm.test.ts +4 -4
  132. package/src/modules/purchase/command/activatePurchasePaymentTerm.ts +2 -2
  133. package/src/modules/purchase/command/deactivatePurchasePaymentTerm.test.ts +4 -4
  134. package/src/modules/purchase/command/deactivatePurchasePaymentTerm.ts +2 -2
  135. package/src/modules/purchase/command/updatePurchasePaymentTerm.test.ts +2 -2
  136. package/src/modules/purchase/command/updatePurchasePaymentTerm.ts +1 -1
  137. package/src/modules/purchase/module.ts +1 -0
  138. package/src/modules/sales/command/createSalesOrder.ts +1 -1
  139. package/src/modules/sales/module.ts +1 -0
  140. package/templates/scaffold/app/backend/eslint.config.js +17 -0
  141. package/templates/scaffold/app/backend/package.json +1 -0
  142. package/templates/scaffold/app/backend/src/tests/stories/audit-log/user--view-audit-log-detail.test.ts +3 -3
  143. package/templates/scaffold/app/backend/src/tests/stories/role-management/user--assign-role-to-user.test.ts +4 -4
  144. package/templates/scaffold/app/backend/src/tests/stories/role-management/user--remove-role-from-user.test.ts +4 -4
  145. package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--toggle-user-status.test.ts +6 -6
  146. package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--update-own-profile.test.ts +13 -13
  147. package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--update-user-profile.test.ts +16 -17
  148. package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--view-user-detail.test.ts +3 -3
  149. package/templates/scaffold/app/backend/tailor.config.ts +15 -1
  150. package/templates/scaffold/app/backend/tsconfig.json +1 -1
  151. package/templates/scaffold/app/frontend/src/App.tsx +57 -16
  152. package/templates/scaffold/module/eslint.config.js +24 -0
  153. package/templates/scaffold/module/module.ts +1 -0
  154. package/templates/scaffold/module/package.json +3 -1
  155. package/templates/scaffold/module/vitest.config.ts +11 -0
  156. /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/[id]/components/audit-entry-detail.tsx +0 -0
  157. /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/[id]/page.tsx +0 -0
  158. /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/components/audit-entries-table.tsx +0 -0
  159. /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/page.tsx +0 -0
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from "vitest";
1
+ import { describe, expect, it } from "vitest";
2
2
  import { createMockDb } from "../../../testing/index";
3
3
  import type { Transaction } from "../generated/kysely-tailordb";
4
4
  import {
@@ -7,7 +7,7 @@ import {
7
7
  DuplicateActiveChartOfAccountsError,
8
8
  } from "../lib/errors.generated";
9
9
  import { baseDraftCoa, baseActiveCoa, baseArchivedCoa } from "../testing/fixtures";
10
- import { run, type AuditCommands } from "./activateChartOfAccounts";
10
+ import { run } from "./activateChartOfAccounts";
11
11
  import type { CommandContext } from "@tailor-platform/erp-kit/module";
12
12
 
13
13
  const ctx: CommandContext = {
@@ -81,33 +81,4 @@ describe("activateChartOfAccounts", () => {
81
81
  expect(result.value.chartOfAccounts.status).toBe("ACTIVE");
82
82
  }
83
83
  });
84
-
85
- it("emits audit event recording status transition from DRAFT to ACTIVE", async () => {
86
- const { db, spies } = createMockDb<Transaction>();
87
- const activatedCoa = { ...baseDraftCoa, status: "ACTIVE" };
88
- spies.select
89
- .mockReturnValueOnce(baseDraftCoa) // CoA lookup
90
- .mockReturnValueOnce(undefined); // no existing ACTIVE CoA
91
- spies.update.mockReturnValue(activatedCoa);
92
-
93
- const mockLogAuditEvent = vi.fn().mockResolvedValue({ ok: true, value: {} });
94
- const auditCommands: AuditCommands = { logAuditEvent: mockLogAuditEvent };
95
-
96
- const result = await run(db, { id: baseDraftCoa.id }, ctx, auditCommands);
97
-
98
- expect(result.ok).toBe(true);
99
- expect(mockLogAuditEvent).toHaveBeenCalledWith(
100
- db,
101
- expect.objectContaining({
102
- entityType: "ChartOfAccounts",
103
- entityId: baseDraftCoa.id,
104
- operationType: "UPDATE",
105
- companyId: baseDraftCoa.companyId,
106
- actorType: "USER",
107
- actorId: ctx.actorId,
108
- changes: [{ fieldName: "status", oldValue: "DRAFT", newValue: "ACTIVE" }],
109
- }),
110
- ctx,
111
- );
112
- });
113
84
  });
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import type { Transaction } from "../generated/kysely-tailordb";
3
2
  import {
4
3
  ChartOfAccountsNotFoundError,
@@ -12,23 +11,6 @@ export interface ActivateChartOfAccountsInput {
12
11
  from?: string[];
13
12
  }
14
13
 
15
- export interface AuditCommands {
16
- logAuditEvent: (
17
- db: Transaction,
18
- input: {
19
- eventId: string;
20
- actorType: string;
21
- actorId: string;
22
- entityType: string;
23
- entityId: string;
24
- operationType: string;
25
- companyId?: string;
26
- changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[];
27
- },
28
- ctx: CommandContext,
29
- ) => Promise<{ ok: true; value: unknown }>;
30
- }
31
-
32
14
  /**
33
15
  * Function: activateChartOfAccounts
34
16
  *
@@ -38,8 +20,7 @@ export interface AuditCommands {
38
20
  export async function run(
39
21
  db: Transaction,
40
22
  input: ActivateChartOfAccountsInput,
41
- ctx: CommandContext,
42
- auditCommands?: AuditCommands,
23
+ _ctx: CommandContext,
43
24
  ) {
44
25
  const { id, from = ["DRAFT"] } = input;
45
26
 
@@ -83,22 +64,5 @@ export async function run(
83
64
  .returningAll()
84
65
  .executeTakeFirst();
85
66
 
86
- if (auditCommands) {
87
- await auditCommands.logAuditEvent(
88
- db,
89
- {
90
- eventId: randomUUID(),
91
- actorType: "USER",
92
- actorId: ctx.actorId,
93
- entityType: "ChartOfAccounts",
94
- entityId: id,
95
- operationType: "UPDATE",
96
- companyId: existing.companyId,
97
- changes: [{ fieldName: "status", oldValue: existing.status, newValue: "ACTIVE" }],
98
- },
99
- ctx,
100
- );
101
- }
102
-
103
67
  return ok({ chartOfAccounts: chartOfAccounts! });
104
68
  }
@@ -710,34 +710,6 @@ describe("createAccount", () => {
710
710
  }
711
711
  });
712
712
 
713
- it("emits audit event recording acting user, timestamp, CoA reference, account code, and classification", async () => {
714
- const { db, spies } = createMockDb<Transaction>();
715
- const created = {
716
- ...baseDraftAccount,
717
- code: "1500",
718
- name: "Audit Account",
719
- };
720
- spies.select.mockReturnValueOnce(baseActiveCoa).mockReturnValueOnce(undefined);
721
- spies.insert.mockReturnValue(created);
722
-
723
- const result = await run(
724
- db,
725
- {
726
- chartOfAccountsId: baseActiveCoa.id,
727
- code: "1500",
728
- name: "Audit Account",
729
- accountType: "ASSET",
730
- },
731
- ctx,
732
- );
733
-
734
- // Audit event is emitted as part of successful creation
735
- expect(result.ok).toBe(true);
736
- if (result.ok) {
737
- expect(result.value.account).toBeDefined();
738
- }
739
- });
740
-
741
713
  it("passes custom fields through to insert", async () => {
742
714
  const { db, spies } = createMockDb<Transaction>();
743
715
  const created = {
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import type { Transaction } from "../generated/kysely-tailordb";
3
2
  import {
4
3
  ChartOfAccountsNotFoundError,
@@ -34,23 +33,6 @@ export interface CreateAccountInput {
34
33
  accountGroupId?: string;
35
34
  }
36
35
 
37
- export interface AuditCommands {
38
- logAuditEvent: (
39
- db: Transaction,
40
- input: {
41
- eventId: string;
42
- actorType: string;
43
- actorId: string;
44
- entityType: string;
45
- entityId: string;
46
- operationType: string;
47
- companyId?: string;
48
- changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[];
49
- },
50
- ctx: CommandContext,
51
- ) => Promise<{ ok: true; value: unknown }>;
52
- }
53
-
54
36
  interface GetCurrencyDep {
55
37
  getCurrency: (
56
38
  db: Transaction,
@@ -81,7 +63,6 @@ export async function run<CF extends Record<string, unknown>>(
81
63
  input: CreateAccountInput & CF,
82
64
  ctx: CommandContext,
83
65
  deps?: GetCurrencyDep,
84
- auditCommands?: AuditCommands,
85
66
  ) {
86
67
  const {
87
68
  chartOfAccountsId,
@@ -219,29 +200,5 @@ export async function run<CF extends Record<string, unknown>>(
219
200
  .returningAll()
220
201
  .executeTakeFirst();
221
202
 
222
- // 11. Emit audit event
223
- if (auditCommands) {
224
- await auditCommands.logAuditEvent(
225
- db,
226
- {
227
- eventId: randomUUID(),
228
- actorType: "USER",
229
- actorId: ctx.actorId,
230
- entityType: "Account",
231
- entityId: account!.id,
232
- operationType: "CREATE",
233
- companyId: coa.companyId,
234
- changes: [
235
- { fieldName: "code", newValue: code },
236
- { fieldName: "name", newValue: name },
237
- { fieldName: "accountType", newValue: accountType },
238
- { fieldName: "classification", newValue: classification },
239
- { fieldName: "reconciliation", newValue: reconciliation },
240
- ],
241
- },
242
- ctx,
243
- );
244
- }
245
-
246
203
  return ok({ account: account! });
247
204
  }
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from "vitest";
1
+ import { describe, expect, it } from "vitest";
2
2
  import { createMockDb } from "../../../testing/index";
3
3
  import type { Transaction } from "../generated/kysely-tailordb";
4
4
  import {
@@ -11,7 +11,7 @@ import {
11
11
  InvalidNumberRangeError,
12
12
  } from "../lib/errors.generated";
13
13
  import { baseActiveCoa, baseArchivedCoa, baseRootGroup, baseChildGroup } from "../testing/fixtures";
14
- import { run, type AuditCommands } from "./createAccountGroup";
14
+ import { run } from "./createAccountGroup";
15
15
  import type { CommandContext } from "@tailor-platform/erp-kit/module";
16
16
 
17
17
  const ctx: CommandContext = {
@@ -414,55 +414,6 @@ describe("createAccountGroup", () => {
414
414
  }
415
415
  });
416
416
 
417
- it("emits audit event recording acting user, timestamp, CoA reference, group code, and initial field values", async () => {
418
- const { db, spies } = createMockDb<Transaction>();
419
- const createdGroup = {
420
- ...baseRootGroup,
421
- id: "new-group-id",
422
- code: "4000",
423
- name: "Expenses",
424
- createdAt: new Date(),
425
- };
426
- spies.select
427
- .mockReturnValueOnce(baseActiveCoa) // CoA lookup
428
- .mockReturnValueOnce(undefined); // No duplicate code
429
- spies.insert.mockReturnValue(createdGroup);
430
-
431
- const mockLogAuditEvent = vi.fn().mockResolvedValue({ ok: true, value: {} });
432
- const auditCommands: AuditCommands = { logAuditEvent: mockLogAuditEvent };
433
-
434
- const result = await run(
435
- db,
436
- {
437
- chartOfAccountsId: baseActiveCoa.id,
438
- code: "4000",
439
- name: "Expenses",
440
- },
441
- ctx,
442
- auditCommands,
443
- );
444
-
445
- expect(result.ok).toBe(true);
446
- expect(mockLogAuditEvent).toHaveBeenCalledWith(
447
- db,
448
- expect.objectContaining({
449
- entityType: "AccountGroup",
450
- entityId: "new-group-id",
451
- operationType: "CREATE",
452
- companyId: baseActiveCoa.companyId,
453
- actorType: "USER",
454
- actorId: ctx.actorId,
455
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
456
- changes: expect.arrayContaining([
457
- { fieldName: "chartOfAccountsId", newValue: baseActiveCoa.id },
458
- { fieldName: "code", newValue: "4000" },
459
- { fieldName: "name", newValue: "Expenses" },
460
- ]),
461
- }),
462
- ctx,
463
- );
464
- });
465
-
466
417
  it("passes custom fields through to insert", async () => {
467
418
  const { db, spies } = createMockDb<Transaction>();
468
419
  const createdGroup = {
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import type { Transaction } from "../generated/kysely-tailordb";
3
2
  import {
4
3
  ChartOfAccountsNotFoundError,
@@ -21,23 +20,6 @@ export interface CreateAccountGroupInput {
21
20
  numberRangeEnd?: number | null;
22
21
  }
23
22
 
24
- export interface AuditCommands {
25
- logAuditEvent: (
26
- db: Transaction,
27
- input: {
28
- eventId: string;
29
- actorType: string;
30
- actorId: string;
31
- entityType: string;
32
- entityId: string;
33
- operationType: string;
34
- companyId?: string;
35
- changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[];
36
- },
37
- ctx: CommandContext,
38
- ) => Promise<{ ok: true; value: unknown }>;
39
- }
40
-
41
23
  /**
42
24
  * Function: createAccountGroup
43
25
  *
@@ -48,8 +30,7 @@ export interface AuditCommands {
48
30
  export async function run<CF extends Record<string, unknown>>(
49
31
  db: Transaction,
50
32
  input: CreateAccountGroupInput & CF,
51
- ctx: CommandContext,
52
- auditCommands?: AuditCommands,
33
+ _ctx: CommandContext,
53
34
  ) {
54
35
  const {
55
36
  chartOfAccountsId,
@@ -167,41 +148,5 @@ export async function run<CF extends Record<string, unknown>>(
167
148
  .returningAll()
168
149
  .executeTakeFirst();
169
150
 
170
- // 9. Emit audit event
171
- if (auditCommands) {
172
- const changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[] = [
173
- { fieldName: "chartOfAccountsId", newValue: chartOfAccountsId },
174
- { fieldName: "code", newValue: code },
175
- { fieldName: "name", newValue: name },
176
- ];
177
- if (parentAccountGroupId) {
178
- changes.push({ fieldName: "parentAccountGroupId", newValue: parentAccountGroupId });
179
- }
180
- if (sortOrder !== undefined && sortOrder !== null) {
181
- changes.push({ fieldName: "sortOrder", newValue: sortOrder });
182
- }
183
- if (rangeStart !== null) {
184
- changes.push({ fieldName: "numberRangeStart", newValue: rangeStart });
185
- }
186
- if (rangeEnd !== null) {
187
- changes.push({ fieldName: "numberRangeEnd", newValue: rangeEnd });
188
- }
189
-
190
- await auditCommands.logAuditEvent(
191
- db,
192
- {
193
- eventId: randomUUID(),
194
- actorType: "USER",
195
- actorId: ctx.actorId,
196
- entityType: "AccountGroup",
197
- entityId: accountGroup!.id,
198
- operationType: "CREATE",
199
- companyId: coa.companyId,
200
- changes,
201
- },
202
- ctx,
203
- );
204
- }
205
-
206
151
  return ok({ accountGroup: accountGroup! });
207
152
  }
@@ -1,4 +1,4 @@
1
- import { describe, expect, it, vi } from "vitest";
1
+ import { describe, expect, it } from "vitest";
2
2
  import { createMockDb } from "../../../testing/index";
3
3
  import type { Transaction } from "../generated/kysely-tailordb";
4
4
  import {
@@ -441,54 +441,6 @@ describe("createChartOfAccounts", () => {
441
441
  expect(result.value.chartOfAccounts.status).toBe("DRAFT");
442
442
  }
443
443
  });
444
-
445
- it("emits audit event recording acting user, timestamp, and initial field values", async () => {
446
- const { db, spies } = createMockDb<Transaction>();
447
- const createdCoa = { ...baseDraftCoa, id: "new-coa-id" };
448
- spies.select.mockReturnValueOnce(baseActiveCompany);
449
- spies.insert.mockReturnValue(createdCoa);
450
-
451
- const mockLogAuditEvent = vi.fn().mockResolvedValue({ ok: true, value: {} });
452
- const auditCommands = { logAuditEvent: mockLogAuditEvent };
453
-
454
- const result = await run(db, validInput, ctx, undefined, undefined, auditCommands);
455
-
456
- expect(result.ok).toBe(true);
457
- expect(mockLogAuditEvent).toHaveBeenCalledWith(
458
- db,
459
- expect.objectContaining({
460
- entityType: "ChartOfAccounts",
461
- entityId: "new-coa-id",
462
- operationType: "CREATE",
463
- companyId: validInput.companyId,
464
- actorType: "USER",
465
- actorId: ctx.actorId,
466
- }),
467
- ctx,
468
- );
469
- });
470
-
471
- it("audit event includes whether CoA was created from template or blank", async () => {
472
- const { db, spies } = createMockDb<Transaction>();
473
- const createdCoa = { ...baseDraftCoa, id: "new-coa-id" };
474
- spies.select.mockReturnValueOnce(baseActiveCompany);
475
- spies.insert.mockReturnValue(createdCoa);
476
-
477
- const mockLogAuditEvent = vi.fn().mockResolvedValue({ ok: true, value: {} });
478
- const auditCommands = { logAuditEvent: mockLogAuditEvent };
479
-
480
- // Test blank creation
481
- await run(db, validInput, ctx, undefined, undefined, auditCommands);
482
-
483
- expect(mockLogAuditEvent).toHaveBeenCalledWith(
484
- db,
485
- expect.objectContaining({
486
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
487
- changes: expect.arrayContaining([{ fieldName: "templateUsed", newValue: "blank" }]),
488
- }),
489
- ctx,
490
- );
491
- });
492
444
  });
493
445
 
494
446
  // Helper type for custom fields test
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import type { Transaction } from "../generated/kysely-tailordb";
3
2
  import {
4
3
  NameRequiredError,
@@ -51,23 +50,6 @@ export interface TemplateProvider {
51
50
  resolveTemplate: (id: string) => Promise<TemplateSnapshot | null>;
52
51
  }
53
52
 
54
- export interface AuditCommands {
55
- logAuditEvent: (
56
- db: Transaction,
57
- input: {
58
- eventId: string;
59
- actorType: string;
60
- actorId: string;
61
- entityType: string;
62
- entityId: string;
63
- operationType: string;
64
- companyId?: string;
65
- changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[];
66
- },
67
- ctx: CommandContext,
68
- ) => Promise<{ ok: true; value: unknown }>;
69
- }
70
-
71
53
  export interface OrganizationQueries {
72
54
  getCompany: (
73
55
  db: Transaction,
@@ -91,7 +73,6 @@ export async function run<CF extends Record<string, unknown>>(
91
73
  ctx: CommandContext,
92
74
  organizationQueries?: Pick<OrganizationQueries, "getCompany">,
93
75
  templateProvider?: TemplateProvider,
94
- auditCommands?: AuditCommands,
95
76
  ) {
96
77
  const { name, companyId, description, templateId, ...customFields } = input;
97
78
 
@@ -209,38 +190,6 @@ export async function run<CF extends Record<string, unknown>>(
209
190
  }
210
191
  }
211
192
 
212
- // 6. Emit audit event
213
- if (auditCommands) {
214
- const changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[] = [
215
- { fieldName: "name", newValue: name },
216
- { fieldName: "companyId", newValue: companyId },
217
- { fieldName: "baseCurrencyId", newValue: baseCurrencyId },
218
- { fieldName: "status", newValue: "DRAFT" },
219
- ];
220
- if (description) {
221
- changes.push({ fieldName: "description", newValue: description });
222
- }
223
- changes.push({
224
- fieldName: "templateUsed",
225
- newValue: templateId ? "template" : "blank",
226
- });
227
-
228
- await auditCommands.logAuditEvent(
229
- db,
230
- {
231
- eventId: randomUUID(),
232
- actorType: "USER",
233
- actorId: ctx.actorId,
234
- entityType: "ChartOfAccounts",
235
- entityId: coa!.id,
236
- operationType: "CREATE",
237
- companyId,
238
- changes,
239
- },
240
- ctx,
241
- );
242
- }
243
-
244
193
  return ok({ chartOfAccounts: coa! });
245
194
  }
246
195
 
@@ -181,19 +181,4 @@ describe("deactivateAccount", () => {
181
181
  expect(result.error).toBeInstanceOf(OpenBalancesExistError);
182
182
  }
183
183
  });
184
-
185
- it("emits audit event recording status transition from ACTIVE to INACTIVE and successor mapping", async () => {
186
- const { db, spies } = createMockDb<Transaction>();
187
- const deactivated = { ...baseActiveAccount, status: "INACTIVE" };
188
- spies.select.mockReturnValueOnce(baseActiveAccount).mockReturnValueOnce(baseActiveCoa);
189
- spies.update.mockReturnValue(deactivated);
190
-
191
- const result = await run(db, { id: baseActiveAccount.id }, ctx);
192
-
193
- // Audit event is emitted as part of successful deactivation
194
- expect(result.ok).toBe(true);
195
- if (result.ok) {
196
- expect(result.value.account.status).toBe("INACTIVE");
197
- }
198
- });
199
184
  });
@@ -1,4 +1,3 @@
1
- import { randomUUID } from "node:crypto";
2
1
  import type { Transaction } from "../generated/kysely-tailordb";
3
2
  import {
4
3
  AccountNotFoundError,
@@ -15,23 +14,6 @@ export interface DeactivateAccountInput {
15
14
  preDeactivationHook?: (accountId: string) => Promise<boolean>;
16
15
  }
17
16
 
18
- export interface AuditCommands {
19
- logAuditEvent: (
20
- db: Transaction,
21
- input: {
22
- eventId: string;
23
- actorType: string;
24
- actorId: string;
25
- entityType: string;
26
- entityId: string;
27
- operationType: string;
28
- companyId?: string;
29
- changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[];
30
- },
31
- ctx: CommandContext,
32
- ) => Promise<{ ok: true; value: unknown }>;
33
- }
34
-
35
17
  /**
36
18
  * Function: deactivateAccount
37
19
  *
@@ -39,12 +21,7 @@ export interface AuditCommands {
39
21
  * journal postings while preserving history. An optional successor account
40
22
  * can be designated during deactivation.
41
23
  */
42
- export async function run(
43
- db: Transaction,
44
- input: DeactivateAccountInput,
45
- ctx: CommandContext,
46
- auditCommands?: AuditCommands,
47
- ) {
24
+ export async function run(db: Transaction, input: DeactivateAccountInput, _ctx: CommandContext) {
48
25
  const { id, successorAccountId, preDeactivationHook } = input;
49
26
 
50
27
  // 1. Find account with forUpdate
@@ -109,34 +86,5 @@ export async function run(
109
86
  .returningAll()
110
87
  .executeTakeFirst();
111
88
 
112
- // 8. Emit audit event
113
- if (auditCommands) {
114
- const changes: { fieldName: string; oldValue?: unknown; newValue?: unknown }[] = [
115
- { fieldName: "status", oldValue: "ACTIVE", newValue: "INACTIVE" },
116
- ];
117
- if (successorAccountId) {
118
- changes.push({
119
- fieldName: "successorAccountId",
120
- oldValue: null,
121
- newValue: successorAccountId,
122
- });
123
- }
124
-
125
- await auditCommands.logAuditEvent(
126
- db,
127
- {
128
- eventId: randomUUID(),
129
- actorType: "USER",
130
- actorId: ctx.actorId,
131
- entityType: "Account",
132
- entityId: id,
133
- operationType: "UPDATE",
134
- companyId: coa.companyId,
135
- changes,
136
- },
137
- ctx,
138
- );
139
- }
140
-
141
89
  return ok({ account: updated! });
142
90
  }
@@ -1,9 +1,9 @@
1
- import { describe, expect, it, vi } from "vitest";
1
+ import { describe, expect, it } from "vitest";
2
2
  import { createMockDb } from "../../../testing/index";
3
3
  import type { Transaction } from "../generated/kysely-tailordb";
4
4
  import { ChartOfAccountsNotFoundError, InvalidStateTransitionError } from "../lib/errors.generated";
5
5
  import { baseDraftCoa, baseActiveCoa, baseArchivedCoa } from "../testing/fixtures";
6
- import { run, type AuditCommands } from "./deactivateChartOfAccounts";
6
+ import { run } from "./deactivateChartOfAccounts";
7
7
  import type { CommandContext } from "@tailor-platform/erp-kit/module";
8
8
 
9
9
  const ctx: CommandContext = {
@@ -61,31 +61,4 @@ describe("deactivateChartOfAccounts", () => {
61
61
  expect(result.value.chartOfAccounts.status).toBe("ARCHIVED");
62
62
  }
63
63
  });
64
-
65
- it("emits audit event recording status transition from ACTIVE to ARCHIVED", async () => {
66
- const { db, spies } = createMockDb<Transaction>();
67
- const archivedCoa = { ...baseActiveCoa, status: "ARCHIVED" };
68
- spies.select.mockReturnValueOnce(baseActiveCoa);
69
- spies.update.mockReturnValue(archivedCoa);
70
-
71
- const mockLogAuditEvent = vi.fn().mockResolvedValue({ ok: true, value: {} });
72
- const auditCommands: AuditCommands = { logAuditEvent: mockLogAuditEvent };
73
-
74
- const result = await run(db, { id: baseActiveCoa.id }, ctx, auditCommands);
75
-
76
- expect(result.ok).toBe(true);
77
- expect(mockLogAuditEvent).toHaveBeenCalledWith(
78
- db,
79
- expect.objectContaining({
80
- entityType: "ChartOfAccounts",
81
- entityId: baseActiveCoa.id,
82
- operationType: "UPDATE",
83
- companyId: baseActiveCoa.companyId,
84
- actorType: "USER",
85
- actorId: ctx.actorId,
86
- changes: [{ fieldName: "status", oldValue: "ACTIVE", newValue: "ARCHIVED" }],
87
- }),
88
- ctx,
89
- );
90
- });
91
64
  });