@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.
- package/CHANGELOG.md +15 -0
- package/package.json +1 -1
- package/skills/erp-kit-app-1-requirements/SKILL.md +6 -0
- package/skills/erp-kit-app-2-requirements-review/SKILL.md +6 -0
- package/skills/erp-kit-app-3-plan/SKILL.md +6 -0
- package/skills/erp-kit-app-4-plan-review/SKILL.md +6 -0
- package/skills/erp-kit-app-5-impl-backend/SKILL.md +7 -0
- package/skills/erp-kit-app-6-impl-frontend/SKILL.md +6 -0
- package/skills/erp-kit-app-7-impl-review/SKILL.md +6 -0
- package/skills/erp-kit-app-shared/SKILL.md +2 -0
- package/skills/erp-kit-mock-scenario/SKILL.md +6 -0
- package/skills/erp-kit-module-1-requirements/SKILL.md +6 -0
- package/skills/erp-kit-module-2-requirements-review/SKILL.md +6 -0
- package/skills/erp-kit-module-3-plan/SKILL.md +6 -0
- package/skills/erp-kit-module-3-update-plan/SKILL.md +6 -0
- package/skills/erp-kit-module-4-plan-review/SKILL.md +6 -0
- package/skills/erp-kit-module-5-impl/SKILL.md +6 -0
- package/skills/erp-kit-module-6-impl-review/SKILL.md +6 -0
- package/skills/erp-kit-module-shared/SKILL.md +2 -0
- package/skills/erp-kit-module-shared/references/commands.md +3 -0
- package/skills/erp-kit-update/SKILL.md +6 -0
- package/src/modules/accounting/command/assignProfitCenterToHierarchyNode.test.ts +3 -3
- package/src/modules/accounting/command/assignProfitCenterToHierarchyNode.ts +1 -1
- package/src/modules/accounting/command/createCostCenterHierarchyNode.test.ts +3 -3
- package/src/modules/accounting/command/createCostCenterHierarchyNode.ts +1 -1
- package/src/modules/accounting/command/moveCostCenterHierarchyNode.test.ts +2 -2
- package/src/modules/accounting/command/moveCostCenterHierarchyNode.ts +1 -1
- package/src/modules/accounting/module.ts +1 -0
- package/src/modules/business-partner/command/createPartnerBankAccount.test.ts +3 -3
- package/src/modules/business-partner/command/createPartnerBankAccount.ts +1 -1
- package/src/modules/business-partner/module.ts +1 -0
- package/src/modules/coa-management/command/activateAccount.test.ts +0 -15
- package/src/modules/coa-management/command/activateAccount.ts +1 -42
- package/src/modules/coa-management/command/activateChartOfAccounts.test.ts +2 -31
- package/src/modules/coa-management/command/activateChartOfAccounts.ts +1 -37
- package/src/modules/coa-management/command/createAccount.test.ts +0 -28
- package/src/modules/coa-management/command/createAccount.ts +0 -43
- package/src/modules/coa-management/command/createAccountGroup.test.ts +2 -51
- package/src/modules/coa-management/command/createAccountGroup.ts +1 -56
- package/src/modules/coa-management/command/createChartOfAccounts.test.ts +1 -49
- package/src/modules/coa-management/command/createChartOfAccounts.ts +0 -51
- package/src/modules/coa-management/command/deactivateAccount.test.ts +0 -15
- package/src/modules/coa-management/command/deactivateAccount.ts +1 -53
- package/src/modules/coa-management/command/deactivateChartOfAccounts.test.ts +2 -29
- package/src/modules/coa-management/command/deactivateChartOfAccounts.ts +1 -37
- package/src/modules/coa-management/command/deleteAccount.test.ts +0 -13
- package/src/modules/coa-management/command/deleteAccount.ts +1 -42
- package/src/modules/coa-management/command/deleteAccountGroup.test.ts +0 -19
- package/src/modules/coa-management/command/deleteAccountGroup.ts +1 -42
- package/src/modules/coa-management/command/deleteChartOfAccounts.test.ts +2 -58
- package/src/modules/coa-management/command/deleteChartOfAccounts.ts +4 -88
- package/src/modules/coa-management/command/moveAccountGroup.test.ts +0 -27
- package/src/modules/coa-management/command/moveAccountGroup.ts +1 -48
- package/src/modules/coa-management/command/reactivateAccount.test.ts +0 -15
- package/src/modules/coa-management/command/reactivateAccount.ts +1 -53
- package/src/modules/coa-management/command/updateAccount.test.ts +0 -15
- package/src/modules/coa-management/command/updateAccount.ts +0 -92
- package/src/modules/coa-management/command/updateAccountGroup.test.ts +0 -20
- package/src/modules/coa-management/command/updateAccountGroup.ts +1 -61
- package/src/modules/coa-management/command/updateChartOfAccounts.test.ts +2 -31
- package/src/modules/coa-management/command/updateChartOfAccounts.ts +1 -50
- package/src/modules/coa-management/docs/commands/ActivateAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/ActivateChartOfAccounts.md +1 -4
- package/src/modules/coa-management/docs/commands/CreateAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/CreateAccountGroup.md +2 -5
- package/src/modules/coa-management/docs/commands/CreateChartOfAccounts.md +2 -6
- package/src/modules/coa-management/docs/commands/DeactivateAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/DeactivateChartOfAccounts.md +1 -4
- package/src/modules/coa-management/docs/commands/DeleteAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/DeleteAccountGroup.md +1 -4
- package/src/modules/coa-management/docs/commands/DeleteChartOfAccounts.md +1 -6
- package/src/modules/coa-management/docs/commands/MoveAccountGroup.md +1 -4
- package/src/modules/coa-management/docs/commands/ReactivateAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/UpdateAccount.md +1 -4
- package/src/modules/coa-management/docs/commands/UpdateAccountGroup.md +2 -5
- package/src/modules/coa-management/docs/commands/UpdateChartOfAccounts.md +1 -4
- package/src/modules/coa-management/module.ts +16 -27
- package/src/modules/finance-ledger/module.ts +1 -0
- package/src/modules/inventory/command/approveInventoryAdjustment.test.ts +1 -1
- package/src/modules/inventory/command/approveInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/cancelStockMovement.test.ts +2 -2
- package/src/modules/inventory/command/cancelStockMovement.ts +1 -1
- package/src/modules/inventory/command/confirmInventoryAdjustment.test.ts +4 -4
- package/src/modules/inventory/command/confirmInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/confirmStockMovement.test.ts +1 -1
- package/src/modules/inventory/command/confirmStockMovement.ts +1 -1
- package/src/modules/inventory/command/createInventoryAdjustment.test.ts +6 -6
- package/src/modules/inventory/command/createInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/createStockMovement.test.ts +3 -3
- package/src/modules/inventory/command/createStockMovement.ts +1 -1
- package/src/modules/inventory/command/executeStockMovement.test.ts +5 -5
- package/src/modules/inventory/command/executeStockMovement.ts +1 -1
- package/src/modules/inventory/command/rejectInventoryAdjustment.test.ts +1 -1
- package/src/modules/inventory/command/rejectInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/reviseInventoryAdjustment.test.ts +2 -2
- package/src/modules/inventory/command/reviseInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/submitInventoryAdjustment.test.ts +1 -1
- package/src/modules/inventory/command/submitInventoryAdjustment.ts +1 -1
- package/src/modules/inventory/command/updateStockMovement.test.ts +4 -4
- package/src/modules/inventory/command/updateStockMovement.ts +2 -2
- package/src/modules/inventory/module.ts +1 -0
- package/src/modules/item-management/command/createTaxonomyNode.test.ts +4 -4
- package/src/modules/item-management/command/createTaxonomyNode.ts +1 -1
- package/src/modules/item-management/command/moveTaxonomyNode.test.ts +2 -2
- package/src/modules/item-management/command/moveTaxonomyNode.ts +2 -2
- package/src/modules/item-management/command/updateTaxonomyNode.test.ts +2 -2
- package/src/modules/item-management/command/updateTaxonomyNode.ts +1 -1
- package/src/modules/item-management/module.ts +1 -0
- package/src/modules/manufacturing/command/createRouting.ts +1 -1
- package/src/modules/manufacturing/command/recordInventoryIssueOutcome.test.ts +1 -1
- package/src/modules/manufacturing/command/recordInventoryIssueOutcome.ts +1 -1
- package/src/modules/manufacturing/command/recordManufacturingCostSettlementAcknowledgment.test.ts +1 -1
- package/src/modules/manufacturing/command/recordManufacturingCostSettlementAcknowledgment.ts +1 -1
- package/src/modules/manufacturing/command/reviewManufacturingCostSummary.test.ts +1 -1
- package/src/modules/manufacturing/command/reviewManufacturingCostSummary.ts +1 -1
- package/src/modules/manufacturing/command/updateRouting.ts +1 -1
- package/src/modules/manufacturing/module.ts +1 -0
- package/src/modules/organization/module.ts +1 -0
- package/src/modules/primitives/module.ts +1 -0
- package/src/modules/product-management/command/assignProductToCategory.test.ts +2 -2
- package/src/modules/product-management/command/assignProductToCategory.ts +2 -2
- package/src/modules/product-management/command/createProductAttribute.test.ts +1 -1
- package/src/modules/product-management/command/createProductAttribute.ts +1 -1
- package/src/modules/product-management/command/createProductAttributeValue.test.ts +1 -1
- package/src/modules/product-management/command/createProductAttributeValue.ts +1 -1
- package/src/modules/product-management/command/createProductCategory.test.ts +2 -2
- package/src/modules/product-management/command/createProductCategory.ts +1 -1
- package/src/modules/product-management/command/setProductAttributeAssignment.test.ts +3 -3
- package/src/modules/product-management/command/setProductAttributeAssignment.ts +2 -2
- package/src/modules/product-management/module.ts +1 -0
- package/src/modules/purchase/command/activatePurchasePaymentTerm.test.ts +4 -4
- package/src/modules/purchase/command/activatePurchasePaymentTerm.ts +2 -2
- package/src/modules/purchase/command/deactivatePurchasePaymentTerm.test.ts +4 -4
- package/src/modules/purchase/command/deactivatePurchasePaymentTerm.ts +2 -2
- package/src/modules/purchase/command/updatePurchasePaymentTerm.test.ts +2 -2
- package/src/modules/purchase/command/updatePurchasePaymentTerm.ts +1 -1
- package/src/modules/purchase/module.ts +1 -0
- package/src/modules/sales/command/createSalesOrder.ts +1 -1
- package/src/modules/sales/module.ts +1 -0
- package/templates/scaffold/app/backend/eslint.config.js +17 -0
- package/templates/scaffold/app/backend/package.json +1 -0
- package/templates/scaffold/app/backend/src/tests/stories/audit-log/user--view-audit-log-detail.test.ts +3 -3
- package/templates/scaffold/app/backend/src/tests/stories/role-management/user--assign-role-to-user.test.ts +4 -4
- package/templates/scaffold/app/backend/src/tests/stories/role-management/user--remove-role-from-user.test.ts +4 -4
- package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--toggle-user-status.test.ts +6 -6
- package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--update-own-profile.test.ts +13 -13
- package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--update-user-profile.test.ts +16 -17
- package/templates/scaffold/app/backend/src/tests/stories/user-lifecycle/user--view-user-detail.test.ts +3 -3
- package/templates/scaffold/app/backend/tailor.config.ts +15 -1
- package/templates/scaffold/app/backend/tsconfig.json +1 -1
- package/templates/scaffold/app/frontend/src/App.tsx +57 -16
- package/templates/scaffold/module/eslint.config.js +24 -0
- package/templates/scaffold/module/module.ts +1 -0
- package/templates/scaffold/module/package.json +3 -1
- package/templates/scaffold/module/vitest.config.ts +11 -0
- /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/[id]/components/audit-entry-detail.tsx +0 -0
- /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/[id]/page.tsx +0 -0
- /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/components/audit-entries-table.tsx +0 -0
- /package/templates/scaffold/app/frontend/src/pages/{user-management/audit → audit}/page.tsx +0 -0
|
@@ -119,5 +119,5 @@ export async function run<CF extends Record<string, unknown>>(
|
|
|
119
119
|
createdOperations.push(operation!);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
return ok({ routing: updatedRouting!,
|
|
122
|
+
return ok({ routing: updatedRouting!, routingOperations: createdOperations });
|
|
123
123
|
}
|
|
@@ -82,6 +82,7 @@ export interface DefineModuleParams<WCF extends Record<string, TailorAnyDBField>
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
85
86
|
export const defineModule = <const WCF extends Record<string, TailorAnyDBField> = EmptyFields>(
|
|
86
87
|
params: DefineModuleParams<WCF>,
|
|
87
88
|
) => {
|
|
@@ -36,6 +36,7 @@ export interface DefineModuleParams<
|
|
|
36
36
|
exchangeRate?: CreateExchangeRateTypeParams<ERF>;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
39
40
|
export const defineModule = <
|
|
40
41
|
const CatF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
41
42
|
const UnitF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
@@ -63,7 +63,7 @@ describe("assignProductToCategory", () => {
|
|
|
63
63
|
const result = await run(db, input);
|
|
64
64
|
expect(result.ok).toBe(true);
|
|
65
65
|
if (result.ok) {
|
|
66
|
-
expect(result.value.
|
|
66
|
+
expect(result.value.productCategoryAssignment).toEqual(newAssignment);
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
|
|
@@ -83,7 +83,7 @@ describe("assignProductToCategory", () => {
|
|
|
83
83
|
const result = await run(db, input);
|
|
84
84
|
expect(result.ok).toBe(true);
|
|
85
85
|
if (result.ok) {
|
|
86
|
-
expect(result.value.
|
|
86
|
+
expect(result.value.productCategoryAssignment).toEqual(baseCategoryAssignment);
|
|
87
87
|
}
|
|
88
88
|
expect(spies.insert).not.toHaveBeenCalled();
|
|
89
89
|
});
|
|
@@ -44,7 +44,7 @@ export async function run(db: Transaction, input: AssignProductToCategoryInput)
|
|
|
44
44
|
.forUpdate()
|
|
45
45
|
.executeTakeFirst();
|
|
46
46
|
if (existing) {
|
|
47
|
-
return ok({
|
|
47
|
+
return ok({ productCategoryAssignment: existing });
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const assignment = await db
|
|
@@ -58,5 +58,5 @@ export async function run(db: Transaction, input: AssignProductToCategoryInput)
|
|
|
58
58
|
.returningAll()
|
|
59
59
|
.executeTakeFirstOrThrow();
|
|
60
60
|
|
|
61
|
-
return ok({ assignment });
|
|
61
|
+
return ok({ productCategoryAssignment: assignment });
|
|
62
62
|
}
|
|
@@ -51,7 +51,7 @@ describe("createProductAttribute", () => {
|
|
|
51
51
|
|
|
52
52
|
expect(result.ok).toBe(true);
|
|
53
53
|
if (result.ok) {
|
|
54
|
-
expect(result.value.
|
|
54
|
+
expect(result.value.productAttribute.code).toBe("COLOR");
|
|
55
55
|
}
|
|
56
56
|
expect(spies.insert).toHaveBeenCalled();
|
|
57
57
|
});
|
|
@@ -61,7 +61,7 @@ describe("createProductAttributeValue", () => {
|
|
|
61
61
|
|
|
62
62
|
expect(result.ok).toBe(true);
|
|
63
63
|
if (result.ok) {
|
|
64
|
-
expect(result.value.
|
|
64
|
+
expect(result.value.productAttributeValue.label).toBe("Green");
|
|
65
65
|
}
|
|
66
66
|
expect(spies.insert).toHaveBeenCalled();
|
|
67
67
|
});
|
|
@@ -105,7 +105,7 @@ describe("createProductCategory", () => {
|
|
|
105
105
|
const result = await run(db, input, ctx, deps);
|
|
106
106
|
expect(result.ok).toBe(true);
|
|
107
107
|
if (result.ok) {
|
|
108
|
-
expect(result.value.
|
|
108
|
+
expect(result.value.productCategory).toEqual(newCategory);
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
|
|
@@ -129,7 +129,7 @@ describe("createProductCategory", () => {
|
|
|
129
129
|
const result = await run(db, input, ctx, deps);
|
|
130
130
|
expect(result.ok).toBe(true);
|
|
131
131
|
if (result.ok) {
|
|
132
|
-
expect(result.value.
|
|
132
|
+
expect(result.value.productCategory).toEqual(newCategory);
|
|
133
133
|
}
|
|
134
134
|
});
|
|
135
135
|
});
|
|
@@ -114,7 +114,7 @@ describe("setProductAttributeAssignment", () => {
|
|
|
114
114
|
|
|
115
115
|
expect(result.ok).toBe(true);
|
|
116
116
|
if (result.ok) {
|
|
117
|
-
expect(result.value.
|
|
117
|
+
expect(result.value.productAttributeAssignment).toEqual(existingAssignment);
|
|
118
118
|
}
|
|
119
119
|
// Should not insert or update
|
|
120
120
|
expect(spies.insert).not.toHaveBeenCalled();
|
|
@@ -165,7 +165,7 @@ describe("setProductAttributeAssignment", () => {
|
|
|
165
165
|
|
|
166
166
|
expect(result.ok).toBe(true);
|
|
167
167
|
if (result.ok) {
|
|
168
|
-
expect(result.value.
|
|
168
|
+
expect(result.value.productAttributeAssignment.productId).toBe(baseDraftProduct.id);
|
|
169
169
|
}
|
|
170
170
|
expect(spies.insert).toHaveBeenCalled();
|
|
171
171
|
});
|
|
@@ -199,7 +199,7 @@ describe("setProductAttributeAssignment", () => {
|
|
|
199
199
|
|
|
200
200
|
expect(result.ok).toBe(true);
|
|
201
201
|
if (result.ok) {
|
|
202
|
-
expect(result.value.
|
|
202
|
+
expect(result.value.productAttributeAssignment.valueId).toBe(baseColorBlue.id);
|
|
203
203
|
}
|
|
204
204
|
expect(spies.insert).toHaveBeenCalled();
|
|
205
205
|
});
|
|
@@ -68,7 +68,7 @@ export async function run(db: Transaction, input: SetProductAttributeAssignmentI
|
|
|
68
68
|
// Idempotent no-op: if exact triple already exists, return existing
|
|
69
69
|
const exactMatch = existingAssignments.find((a) => a.valueId === valueId);
|
|
70
70
|
if (exactMatch) {
|
|
71
|
-
return ok({
|
|
71
|
+
return ok({ productAttributeAssignment: exactMatch });
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// Status-based rules
|
|
@@ -98,5 +98,5 @@ export async function run(db: Transaction, input: SetProductAttributeAssignmentI
|
|
|
98
98
|
.returningAll()
|
|
99
99
|
.executeTakeFirstOrThrow();
|
|
100
100
|
|
|
101
|
-
return ok({ assignment });
|
|
101
|
+
return ok({ productAttributeAssignment: assignment });
|
|
102
102
|
}
|
|
@@ -110,6 +110,7 @@ export interface DefineModuleParams<
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
113
114
|
export const defineModule = <
|
|
114
115
|
const PF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
115
116
|
const PAF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
@@ -13,9 +13,9 @@ describe("activatePurchasePaymentTerm", () => {
|
|
|
13
13
|
spies.update.mockReturnValueOnce({ ...inactivePaymentTerm, status: "ACTIVE" });
|
|
14
14
|
|
|
15
15
|
const result = await run(db, { id: inactivePaymentTerm.id }, commandCtx);
|
|
16
|
-
const value = expectOk<{
|
|
16
|
+
const value = expectOk<{ purchasePaymentTerm: typeof inactivePaymentTerm }>(result);
|
|
17
17
|
|
|
18
|
-
expect(value.
|
|
18
|
+
expect(value.purchasePaymentTerm.status).toBe("ACTIVE");
|
|
19
19
|
expect(spies.set).toHaveBeenCalledWith(expect.objectContaining({ status: "ACTIVE" }));
|
|
20
20
|
});
|
|
21
21
|
|
|
@@ -24,9 +24,9 @@ describe("activatePurchasePaymentTerm", () => {
|
|
|
24
24
|
spies.select.mockReturnValueOnce(basePaymentTerm);
|
|
25
25
|
|
|
26
26
|
const result = await run(db, { id: basePaymentTerm.id }, commandCtx);
|
|
27
|
-
const value = expectOk<{
|
|
27
|
+
const value = expectOk<{ purchasePaymentTerm: typeof basePaymentTerm }>(result);
|
|
28
28
|
|
|
29
|
-
expect(value.
|
|
29
|
+
expect(value.purchasePaymentTerm).toEqual(basePaymentTerm);
|
|
30
30
|
expect(spies.update).not.toHaveBeenCalled();
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -18,7 +18,7 @@ export async function run(
|
|
|
18
18
|
return err(new PaymentTermNotFoundError(input.id));
|
|
19
19
|
}
|
|
20
20
|
if (paymentTerm.status === "ACTIVE") {
|
|
21
|
-
return ok({ paymentTerm });
|
|
21
|
+
return ok({ purchasePaymentTerm: paymentTerm });
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const validation = validateScheduleLines(
|
|
@@ -35,5 +35,5 @@ export async function run(
|
|
|
35
35
|
.returningAll()
|
|
36
36
|
.executeTakeFirstOrThrow();
|
|
37
37
|
|
|
38
|
-
return ok({
|
|
38
|
+
return ok({ purchasePaymentTerm: activated });
|
|
39
39
|
}
|
|
@@ -13,9 +13,9 @@ describe("deactivatePurchasePaymentTerm", () => {
|
|
|
13
13
|
spies.update.mockReturnValueOnce({ ...basePaymentTerm, status: "INACTIVE" });
|
|
14
14
|
|
|
15
15
|
const result = await run(db, { id: basePaymentTerm.id }, commandCtx);
|
|
16
|
-
const value = expectOk<{
|
|
16
|
+
const value = expectOk<{ purchasePaymentTerm: typeof basePaymentTerm }>(result);
|
|
17
17
|
|
|
18
|
-
expect(value.
|
|
18
|
+
expect(value.purchasePaymentTerm.status).toBe("INACTIVE");
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it("returns success when the payment term is already inactive", async () => {
|
|
@@ -23,9 +23,9 @@ describe("deactivatePurchasePaymentTerm", () => {
|
|
|
23
23
|
spies.select.mockReturnValueOnce(inactivePaymentTerm);
|
|
24
24
|
|
|
25
25
|
const result = await run(db, { id: inactivePaymentTerm.id }, commandCtx);
|
|
26
|
-
const value = expectOk<{
|
|
26
|
+
const value = expectOk<{ purchasePaymentTerm: typeof inactivePaymentTerm }>(result);
|
|
27
27
|
|
|
28
|
-
expect(value.
|
|
28
|
+
expect(value.purchasePaymentTerm).toEqual(inactivePaymentTerm);
|
|
29
29
|
expect(spies.update).not.toHaveBeenCalled();
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -18,7 +18,7 @@ export async function run(
|
|
|
18
18
|
return err(new PaymentTermNotFoundError(input.id));
|
|
19
19
|
}
|
|
20
20
|
if (paymentTerm.status === "INACTIVE") {
|
|
21
|
-
return ok({ paymentTerm });
|
|
21
|
+
return ok({ purchasePaymentTerm: paymentTerm });
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const supplierProfile = await db
|
|
@@ -37,5 +37,5 @@ export async function run(
|
|
|
37
37
|
.returningAll()
|
|
38
38
|
.executeTakeFirstOrThrow();
|
|
39
39
|
|
|
40
|
-
return ok({
|
|
40
|
+
return ok({ purchasePaymentTerm: deactivated });
|
|
41
41
|
}
|
|
@@ -30,7 +30,7 @@ describe("updatePurchasePaymentTerm", () => {
|
|
|
30
30
|
commandCtx,
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
-
expect(expectOk(result).
|
|
33
|
+
expect(expectOk(result).purchasePaymentTerm.name).toBe("Net 45");
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("updates an inactive payment term without reactivating it", async () => {
|
|
@@ -45,7 +45,7 @@ describe("updatePurchasePaymentTerm", () => {
|
|
|
45
45
|
commandCtx,
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
expect(expectOk(result).
|
|
48
|
+
expect(expectOk(result).purchasePaymentTerm.status).toBe("INACTIVE");
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
it("preserves historical purchase-order snapshots after update", async () => {
|
|
@@ -111,6 +111,7 @@ export interface DefineModuleParams<
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
114
115
|
export const defineModule = <
|
|
115
116
|
const SPF extends Record<string, TailorAnyDBField> = Record<never, never>,
|
|
116
117
|
const PTF extends Record<string, TailorAnyDBField> = Record<never, never>,
|
|
@@ -136,5 +136,5 @@ export async function run(db: Transaction, input: CreateSalesOrderInput, ctx: Co
|
|
|
136
136
|
insertedLines.push(inserted);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
return ok({ salesOrder: salesOrder!,
|
|
139
|
+
return ok({ salesOrder: salesOrder!, salesOrderLines: insertedLines });
|
|
140
140
|
}
|
|
@@ -176,6 +176,7 @@ export interface DefineModuleParams<
|
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
179
180
|
export const defineModule = <
|
|
180
181
|
const ChF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
181
182
|
const LiF extends Record<string, TailorAnyDBField> = EmptyFields,
|
|
@@ -29,4 +29,21 @@ export default defineConfig([
|
|
|
29
29
|
"import-x/no-unresolved": ["error", { ignore: ["^@tailor-platform/"] }],
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
files: ["src/executors/**/*.ts", "src/resolvers/**/*.ts"],
|
|
34
|
+
ignores: ["**/*.test.ts"],
|
|
35
|
+
rules: {
|
|
36
|
+
"no-restricted-imports": [
|
|
37
|
+
"error",
|
|
38
|
+
{
|
|
39
|
+
patterns: [
|
|
40
|
+
{
|
|
41
|
+
regex: "^node:",
|
|
42
|
+
message: "Node.js built-in modules are not allowed in executors/resolvers.",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
32
49
|
]);
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"lint:fix": "eslint --cache --fix .",
|
|
11
11
|
"seed": "node --env-file-if-exists=.env seed/exec.mjs",
|
|
12
12
|
"seed:reset": "node --env-file-if-exists=.env seed/exec.mjs --truncate --yes",
|
|
13
|
+
"seed:validate": "node --env-file-if-exists=.env seed/exec.mjs validate",
|
|
13
14
|
"test:integration": "vitest run",
|
|
14
15
|
"typecheck": "tsc --noEmit",
|
|
15
16
|
"gql-tada:check": "gql-tada check"
|
|
@@ -38,8 +38,8 @@ const listRoles = graphql(`
|
|
|
38
38
|
`);
|
|
39
39
|
|
|
40
40
|
const createUser = graphql(`
|
|
41
|
-
mutation ($name: String!, $email: String!, $
|
|
42
|
-
createUser(name: $name, email: $email,
|
|
41
|
+
mutation ($name: String!, $email: String!, $roleIds: [String!]) {
|
|
42
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
43
43
|
id
|
|
44
44
|
name
|
|
45
45
|
email
|
|
@@ -69,7 +69,7 @@ describe("user--view-audit-log-detail", () => {
|
|
|
69
69
|
|
|
70
70
|
const email = `audit-detail-${Date.now()}@example.com`;
|
|
71
71
|
const createResult = await gql
|
|
72
|
-
.mutation(createUser, { name: "Audit Detail User", email, roleId })
|
|
72
|
+
.mutation(createUser, { name: "Audit Detail User", email, roleIds: [roleId] })
|
|
73
73
|
.toPromise();
|
|
74
74
|
|
|
75
75
|
expect(createResult.data?.createUser.name).toBe("Audit Detail User");
|
|
@@ -14,8 +14,8 @@ const listRoles = graphql(`
|
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
16
|
const createUser = graphql(`
|
|
17
|
-
mutation ($name: String!, $email: String!, $
|
|
18
|
-
createUser(name: $name, email: $email,
|
|
17
|
+
mutation ($name: String!, $email: String!, $roleIds: [String!]) {
|
|
18
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
19
19
|
id
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -61,7 +61,7 @@ describe("user--assign-role-to-user", () => {
|
|
|
61
61
|
.mutation(createUser, {
|
|
62
62
|
name: "Assign Role User",
|
|
63
63
|
email: `assign-role-${Date.now()}@example.com`,
|
|
64
|
-
roleId,
|
|
64
|
+
roleIds: [roleId],
|
|
65
65
|
})
|
|
66
66
|
.toPromise();
|
|
67
67
|
const userId = createResult.data!.createUser.id;
|
|
@@ -90,7 +90,7 @@ describe("user--assign-role-to-user", () => {
|
|
|
90
90
|
.mutation(createUser, {
|
|
91
91
|
name: "Idempotent Role User",
|
|
92
92
|
email: `idem-role-${Date.now()}@example.com`,
|
|
93
|
-
roleId,
|
|
93
|
+
roleIds: [roleId],
|
|
94
94
|
})
|
|
95
95
|
.toPromise();
|
|
96
96
|
const userId = createResult.data!.createUser.id;
|
|
@@ -14,8 +14,8 @@ const listRoles = graphql(`
|
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
16
|
const createUser = graphql(`
|
|
17
|
-
mutation ($name: String!, $email: String!, $
|
|
18
|
-
createUser(name: $name, email: $email,
|
|
17
|
+
mutation ($name: String!, $email: String!, $roleIds: [String!]) {
|
|
18
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
19
19
|
id
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -53,7 +53,7 @@ describe("user--remove-role-from-user", () => {
|
|
|
53
53
|
.mutation(createUser, {
|
|
54
54
|
name: "Remove Role User",
|
|
55
55
|
email: `remove-role-${Date.now()}@example.com`,
|
|
56
|
-
roleId,
|
|
56
|
+
roleIds: [roleId],
|
|
57
57
|
})
|
|
58
58
|
.toPromise();
|
|
59
59
|
const userId = createResult.data!.createUser.id;
|
|
@@ -75,7 +75,7 @@ describe("user--remove-role-from-user", () => {
|
|
|
75
75
|
.mutation(createUser, {
|
|
76
76
|
name: "Cancel Remove User",
|
|
77
77
|
email: `cancel-remove-${Date.now()}@example.com`,
|
|
78
|
-
roleId,
|
|
78
|
+
roleIds: [roleId],
|
|
79
79
|
})
|
|
80
80
|
.toPromise();
|
|
81
81
|
const userId = createResult.data!.createUser.id;
|
|
@@ -14,8 +14,8 @@ const listRoles = graphql(`
|
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
16
|
const createUserWithStatus = graphql(`
|
|
17
|
-
mutation CreateUserWithStatus($name: String!, $email: String!, $
|
|
18
|
-
createUser(name: $name, email: $email,
|
|
17
|
+
mutation CreateUserWithStatus($name: String!, $email: String!, $roleIds: [String!]) {
|
|
18
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
19
19
|
id
|
|
20
20
|
status
|
|
21
21
|
}
|
|
@@ -23,8 +23,8 @@ const createUserWithStatus = graphql(`
|
|
|
23
23
|
`);
|
|
24
24
|
|
|
25
25
|
const createUserIdOnly = graphql(`
|
|
26
|
-
mutation CreateUserIdOnly($name: String!, $email: String!, $
|
|
27
|
-
createUser(name: $name, email: $email,
|
|
26
|
+
mutation CreateUserIdOnly($name: String!, $email: String!, $roleIds: [String!]) {
|
|
27
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
28
28
|
id
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -79,7 +79,7 @@ describe("user--toggle-user-status", () => {
|
|
|
79
79
|
.mutation(createUserWithStatus, {
|
|
80
80
|
name: "Deactivate Test",
|
|
81
81
|
email: `deactivate-${Date.now()}@example.com`,
|
|
82
|
-
|
|
82
|
+
roleIds: [roleId!],
|
|
83
83
|
})
|
|
84
84
|
.toPromise();
|
|
85
85
|
expect(createResult.data?.createUser.status).toBe("ACTIVE");
|
|
@@ -101,7 +101,7 @@ describe("user--toggle-user-status", () => {
|
|
|
101
101
|
.mutation(createUserIdOnly, {
|
|
102
102
|
name: "Reactivate Test",
|
|
103
103
|
email: `reactivate-${Date.now()}@example.com`,
|
|
104
|
-
|
|
104
|
+
roleIds: [roleId!],
|
|
105
105
|
})
|
|
106
106
|
.toPromise();
|
|
107
107
|
|
|
@@ -14,8 +14,8 @@ const listRoles = graphql(`
|
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
16
|
const createUserIdOnly = graphql(`
|
|
17
|
-
mutation CreateUserIdOnly($name: String!, $email: String!, $
|
|
18
|
-
createUser(name: $name, email: $email,
|
|
17
|
+
mutation CreateUserIdOnly($name: String!, $email: String!, $roleIds: [String!]) {
|
|
18
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
19
19
|
id
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -44,7 +44,7 @@ describe("user--update-own-profile", () => {
|
|
|
44
44
|
.mutation(createUserIdOnly, {
|
|
45
45
|
name: "Original Name",
|
|
46
46
|
email,
|
|
47
|
-
|
|
47
|
+
roleIds: [roleId!],
|
|
48
48
|
})
|
|
49
49
|
.toPromise();
|
|
50
50
|
|
|
@@ -68,18 +68,18 @@ describe("user--update-own-profile", () => {
|
|
|
68
68
|
.mutation(createUserIdOnly, {
|
|
69
69
|
name: "Keep Name",
|
|
70
70
|
email,
|
|
71
|
-
|
|
71
|
+
roleIds: [roleId!],
|
|
72
72
|
})
|
|
73
73
|
.toPromise();
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
await expect(
|
|
76
|
+
gql
|
|
77
|
+
.mutation(updateUserProfile, {
|
|
78
|
+
userId: createResult.data!.createUser.id,
|
|
79
|
+
name: "",
|
|
80
|
+
email,
|
|
81
|
+
})
|
|
82
|
+
.toPromise(),
|
|
83
|
+
).rejects.toThrow();
|
|
84
84
|
});
|
|
85
85
|
});
|
|
@@ -14,8 +14,8 @@ const listRoles = graphql(`
|
|
|
14
14
|
`);
|
|
15
15
|
|
|
16
16
|
const createUserIdOnly = graphql(`
|
|
17
|
-
mutation CreateUserIdOnly($name: String!, $email: String!, $
|
|
18
|
-
createUser(name: $name, email: $email,
|
|
17
|
+
mutation CreateUserIdOnly($name: String!, $email: String!, $roleIds: [String!]) {
|
|
18
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
19
19
|
id
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -59,7 +59,7 @@ describe("user--update-user-profile", () => {
|
|
|
59
59
|
.mutation(createUserIdOnly, {
|
|
60
60
|
name: "Before Update",
|
|
61
61
|
email,
|
|
62
|
-
|
|
62
|
+
roleIds: [roleId!],
|
|
63
63
|
})
|
|
64
64
|
.toPromise();
|
|
65
65
|
|
|
@@ -83,7 +83,7 @@ describe("user--update-user-profile", () => {
|
|
|
83
83
|
.mutation(createUserIdOnly, {
|
|
84
84
|
name: "Email Update User",
|
|
85
85
|
email: `old-email-${ts}@example.com`,
|
|
86
|
-
|
|
86
|
+
roleIds: [roleId!],
|
|
87
87
|
})
|
|
88
88
|
.toPromise();
|
|
89
89
|
|
|
@@ -108,7 +108,7 @@ describe("user--update-user-profile", () => {
|
|
|
108
108
|
.mutation(createUserIdOnly, {
|
|
109
109
|
name: "User A",
|
|
110
110
|
email: `dup-a-${ts}@example.com`,
|
|
111
|
-
|
|
111
|
+
roleIds: [roleId!],
|
|
112
112
|
})
|
|
113
113
|
.toPromise();
|
|
114
114
|
|
|
@@ -116,7 +116,7 @@ describe("user--update-user-profile", () => {
|
|
|
116
116
|
.mutation(createUserIdOnly, {
|
|
117
117
|
name: "User B",
|
|
118
118
|
email: `dup-b-${ts}@example.com`,
|
|
119
|
-
|
|
119
|
+
roleIds: [roleId!],
|
|
120
120
|
})
|
|
121
121
|
.toPromise();
|
|
122
122
|
|
|
@@ -140,19 +140,18 @@ describe("user--update-user-profile", () => {
|
|
|
140
140
|
.mutation(createUserIdOnly, {
|
|
141
141
|
name: "Clear Name User",
|
|
142
142
|
email,
|
|
143
|
-
|
|
143
|
+
roleIds: [roleId!],
|
|
144
144
|
})
|
|
145
145
|
.toPromise();
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(res.data?.updateUserProfile).toBeDefined();
|
|
147
|
+
await expect(
|
|
148
|
+
gql
|
|
149
|
+
.mutation(updateUserProfileName, {
|
|
150
|
+
userId: createResult.data!.createUser.id,
|
|
151
|
+
name: "",
|
|
152
|
+
email,
|
|
153
|
+
})
|
|
154
|
+
.toPromise(),
|
|
155
|
+
).rejects.toThrow();
|
|
157
156
|
});
|
|
158
157
|
});
|
|
@@ -46,8 +46,8 @@ const listRoles = graphql(`
|
|
|
46
46
|
`);
|
|
47
47
|
|
|
48
48
|
const createUserIdOnly = graphql(`
|
|
49
|
-
mutation CreateUserIdOnly($name: String!, $email: String!, $
|
|
50
|
-
createUser(name: $name, email: $email,
|
|
49
|
+
mutation CreateUserIdOnly($name: String!, $email: String!, $roleIds: [String!]) {
|
|
50
|
+
createUser(name: $name, email: $email, roleIds: $roleIds) {
|
|
51
51
|
id
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -84,7 +84,7 @@ describe("user--view-user-detail", () => {
|
|
|
84
84
|
.mutation(createUserIdOnly, {
|
|
85
85
|
name: "Inactive Detail User",
|
|
86
86
|
email: `inactive-detail-${Date.now()}@example.com`,
|
|
87
|
-
|
|
87
|
+
roleIds: [roleId!],
|
|
88
88
|
})
|
|
89
89
|
.toPromise();
|
|
90
90
|
const userId = createResult.data!.createUser.id;
|
|
@@ -33,7 +33,21 @@ const auth = defineAuth("default", {
|
|
|
33
33
|
machineUsers: {
|
|
34
34
|
developer: {
|
|
35
35
|
attributes: {
|
|
36
|
-
permissions: [
|
|
36
|
+
permissions: [
|
|
37
|
+
"user-management:createUser",
|
|
38
|
+
"user-management:activateUser",
|
|
39
|
+
"user-management:deactivateUser",
|
|
40
|
+
"user-management:reactivateUser",
|
|
41
|
+
"user-management:createRole",
|
|
42
|
+
"user-management:assignPermissionToRole",
|
|
43
|
+
"user-management:revokePermissionFromRole",
|
|
44
|
+
"user-management:assignRoleToUser",
|
|
45
|
+
"user-management:revokeRoleFromUser",
|
|
46
|
+
"user-management:createPermission",
|
|
47
|
+
"user-management:updateUser",
|
|
48
|
+
"user-management:updateOwnProfile",
|
|
49
|
+
"audit:logAuditEvent",
|
|
50
|
+
],
|
|
37
51
|
},
|
|
38
52
|
},
|
|
39
53
|
},
|