@tailor-platform/erp-kit 0.0.1 → 0.1.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/README.md +196 -28
- package/dist/cli.js +894 -0
- package/package.json +65 -8
- package/rules/app-compose/backend/auth.md +78 -0
- package/rules/app-compose/frontend/auth.md +55 -0
- package/rules/app-compose/frontend/component.md +55 -0
- package/rules/app-compose/frontend/page.md +86 -0
- package/rules/app-compose/frontend/screen-detailview.md +112 -0
- package/rules/app-compose/frontend/screen-form.md +145 -0
- package/rules/app-compose/frontend/screen-listview.md +159 -0
- package/rules/app-compose/structure.md +32 -0
- package/rules/module-development/commands.md +54 -0
- package/rules/module-development/cross-module-type-injection.md +28 -0
- package/rules/module-development/dependency-modules.md +24 -0
- package/rules/module-development/errors.md +12 -0
- package/rules/module-development/executors.md +67 -0
- package/rules/module-development/exports.md +13 -0
- package/rules/module-development/models.md +34 -0
- package/rules/module-development/structure.md +27 -0
- package/rules/module-development/sync-vs-async-operations.md +83 -0
- package/rules/module-development/testing.md +43 -0
- package/rules/sdk-best-practices/db-relations.md +74 -0
- package/rules/sdk-best-practices/sdk-docs.md +14 -0
- package/schemas/app-compose/actors.yml +34 -0
- package/schemas/app-compose/business-flow.yml +50 -0
- package/schemas/app-compose/requirements.yml +33 -0
- package/schemas/app-compose/resolver.yml +47 -0
- package/schemas/app-compose/screen.yml +81 -0
- package/schemas/app-compose/story.yml +67 -0
- package/schemas/module/command.yml +52 -0
- package/schemas/module/feature.yml +58 -0
- package/schemas/module/model.yml +70 -0
- package/schemas/module/module.yml +50 -0
- package/skills/1-module-docs/SKILL.md +107 -0
- package/skills/2-module-feature-breakdown/SKILL.md +66 -0
- package/skills/3-module-doc-review/SKILL.md +230 -0
- package/skills/4-module-tdd-implementation/SKILL.md +56 -0
- package/skills/5-module-implementation-review/SKILL.md +400 -0
- package/skills/app-compose-1-requirement-analysis/SKILL.md +85 -0
- package/skills/app-compose-2-requirements-breakdown/SKILL.md +88 -0
- package/skills/app-compose-3-doc-review/SKILL.md +112 -0
- package/skills/app-compose-4-design-mock/SKILL.md +248 -0
- package/skills/app-compose-5-design-mock-review/SKILL.md +283 -0
- package/skills/app-compose-6-implementation-spec/SKILL.md +122 -0
- package/skills/mock-scenario/SKILL.md +118 -0
- package/src/app.ts +1 -0
- package/src/cli.ts +120 -0
- package/src/commands/check.test.ts +30 -0
- package/src/commands/check.ts +66 -0
- package/src/commands/init.test.ts +77 -0
- package/src/commands/init.ts +87 -0
- package/src/commands/mock/index.ts +53 -0
- package/src/commands/mock/start.ts +179 -0
- package/src/commands/mock/validate.test.ts +185 -0
- package/src/commands/mock/validate.ts +198 -0
- package/src/commands/scaffold.test.ts +76 -0
- package/src/commands/scaffold.ts +119 -0
- package/src/commands/sync-check.test.ts +125 -0
- package/src/commands/sync-check.ts +182 -0
- package/src/integration.test.ts +63 -0
- package/src/mdschema.ts +48 -0
- package/src/mockServer.ts +55 -0
- package/src/module.ts +86 -0
- package/src/modules/accounting/.gitkeep +0 -0
- package/src/modules/coa-management/.gitkeep +0 -0
- package/src/modules/inventory/.gitkeep +0 -0
- package/src/modules/manufacturing/.gitkeep +0 -0
- package/src/modules/primitives/README.md +39 -0
- package/src/modules/primitives/command/activateCategory.test.ts +75 -0
- package/src/modules/primitives/command/activateCategory.ts +50 -0
- package/src/modules/primitives/command/activateCurrency.test.ts +70 -0
- package/src/modules/primitives/command/activateCurrency.ts +50 -0
- package/src/modules/primitives/command/activateUnit.test.ts +53 -0
- package/src/modules/primitives/command/activateUnit.ts +50 -0
- package/src/modules/primitives/command/convertAmount.test.ts +275 -0
- package/src/modules/primitives/command/convertAmount.ts +126 -0
- package/src/modules/primitives/command/convertQuantity.test.ts +219 -0
- package/src/modules/primitives/command/convertQuantity.ts +73 -0
- package/src/modules/primitives/command/createCategory.test.ts +126 -0
- package/src/modules/primitives/command/createCategory.ts +89 -0
- package/src/modules/primitives/command/createCurrency.test.ts +191 -0
- package/src/modules/primitives/command/createCurrency.ts +77 -0
- package/src/modules/primitives/command/createExchangeRate.test.ts +216 -0
- package/src/modules/primitives/command/createExchangeRate.ts +91 -0
- package/src/modules/primitives/command/createUnit.test.ts +214 -0
- package/src/modules/primitives/command/createUnit.ts +88 -0
- package/src/modules/primitives/command/deactivateCategory.test.ts +97 -0
- package/src/modules/primitives/command/deactivateCategory.ts +62 -0
- package/src/modules/primitives/command/deactivateCurrency.test.ts +85 -0
- package/src/modules/primitives/command/deactivateCurrency.ts +55 -0
- package/src/modules/primitives/command/deactivateUnit.test.ts +78 -0
- package/src/modules/primitives/command/deactivateUnit.ts +62 -0
- package/src/modules/primitives/command/setBaseCurrency.test.ts +98 -0
- package/src/modules/primitives/command/setBaseCurrency.ts +74 -0
- package/src/modules/primitives/command/setReferenceUnit.test.ts +108 -0
- package/src/modules/primitives/command/setReferenceUnit.ts +84 -0
- package/src/modules/primitives/db/currency.ts +30 -0
- package/src/modules/primitives/db/exchangeRate.ts +28 -0
- package/src/modules/primitives/db/unit.ts +32 -0
- package/src/modules/primitives/db/uomCategory.ts +32 -0
- package/src/modules/primitives/docs/commands/ActivateCategory.md +34 -0
- package/src/modules/primitives/docs/commands/ActivateCurrency.md +33 -0
- package/src/modules/primitives/docs/commands/ActivateUnit.md +34 -0
- package/src/modules/primitives/docs/commands/ConvertAmount.md +50 -0
- package/src/modules/primitives/docs/commands/ConvertQuantity.md +43 -0
- package/src/modules/primitives/docs/commands/CreateCategory.md +44 -0
- package/src/modules/primitives/docs/commands/CreateCurrency.md +47 -0
- package/src/modules/primitives/docs/commands/CreateExchangeRate.md +48 -0
- package/src/modules/primitives/docs/commands/CreateUnit.md +48 -0
- package/src/modules/primitives/docs/commands/DeactivateCategory.md +38 -0
- package/src/modules/primitives/docs/commands/DeactivateCurrency.md +38 -0
- package/src/modules/primitives/docs/commands/DeactivateUnit.md +38 -0
- package/src/modules/primitives/docs/commands/SetBaseCurrency.md +39 -0
- package/src/modules/primitives/docs/commands/SetReferenceUnit.md +43 -0
- package/src/modules/primitives/docs/features/currency-definitions.md +55 -0
- package/src/modules/primitives/docs/features/exchange-rates.md +61 -0
- package/src/modules/primitives/docs/features/unit-conversion.md +66 -0
- package/src/modules/primitives/docs/features/uom-categories.md +52 -0
- package/src/modules/primitives/docs/models/Currency.md +45 -0
- package/src/modules/primitives/docs/models/ExchangeRate.md +33 -0
- package/src/modules/primitives/docs/models/Unit.md +46 -0
- package/src/modules/primitives/docs/models/UoMCategory.md +44 -0
- package/src/modules/primitives/generated/kysely-tailordb.ts +95 -0
- package/src/modules/primitives/index.ts +40 -0
- package/src/modules/primitives/lib/errors.ts +138 -0
- package/src/modules/primitives/lib/types.ts +20 -0
- package/src/modules/primitives/module.ts +66 -0
- package/src/modules/primitives/permissions.ts +18 -0
- package/src/modules/primitives/tailor.config.ts +11 -0
- package/src/modules/primitives/testing/fixtures.ts +161 -0
- package/src/modules/product-management/.gitkeep +0 -0
- package/src/modules/purchase/.gitkeep +0 -0
- package/src/modules/sales/.gitkeep +0 -0
- package/src/modules/shared/createContext.test.ts +39 -0
- package/src/modules/shared/createContext.ts +15 -0
- package/src/modules/shared/defineCommand.test.ts +42 -0
- package/src/modules/shared/defineCommand.ts +19 -0
- package/src/modules/shared/definePermissions.test.ts +146 -0
- package/src/modules/shared/definePermissions.ts +94 -0
- package/src/modules/shared/entityTypes.ts +15 -0
- package/src/modules/shared/errors.ts +22 -0
- package/src/modules/shared/index.ts +1 -0
- package/src/modules/shared/internal.ts +13 -0
- package/src/modules/shared/requirePermission.test.ts +47 -0
- package/src/modules/shared/requirePermission.ts +8 -0
- package/src/modules/shared/types.ts +4 -0
- package/src/modules/supplier-management/.gitkeep +0 -0
- package/src/modules/supplier-portal/.gitkeep +0 -0
- package/src/modules/testing/index.ts +120 -0
- package/src/modules/user-management/README.md +38 -0
- package/src/modules/user-management/command/activateUser.test.ts +112 -0
- package/src/modules/user-management/command/activateUser.ts +67 -0
- package/src/modules/user-management/command/assignPermissionToRole.test.ts +119 -0
- package/src/modules/user-management/command/assignPermissionToRole.ts +87 -0
- package/src/modules/user-management/command/assignRoleToUser.test.ts +162 -0
- package/src/modules/user-management/command/assignRoleToUser.ts +93 -0
- package/src/modules/user-management/command/createPermission.test.ts +143 -0
- package/src/modules/user-management/command/createPermission.ts +66 -0
- package/src/modules/user-management/command/createRole.test.ts +115 -0
- package/src/modules/user-management/command/createRole.ts +52 -0
- package/src/modules/user-management/command/createUser.test.ts +198 -0
- package/src/modules/user-management/command/createUser.ts +85 -0
- package/src/modules/user-management/command/deactivateUser.test.ts +112 -0
- package/src/modules/user-management/command/deactivateUser.ts +67 -0
- package/src/modules/user-management/command/logAuditEvent.test.ts +179 -0
- package/src/modules/user-management/command/logAuditEvent.ts +59 -0
- package/src/modules/user-management/command/reactivateUser.test.ts +115 -0
- package/src/modules/user-management/command/reactivateUser.ts +67 -0
- package/src/modules/user-management/command/revokePermissionFromRole.test.ts +112 -0
- package/src/modules/user-management/command/revokePermissionFromRole.ts +81 -0
- package/src/modules/user-management/command/revokeRoleFromUser.test.ts +112 -0
- package/src/modules/user-management/command/revokeRoleFromUser.ts +81 -0
- package/src/modules/user-management/db/auditEvent.ts +47 -0
- package/src/modules/user-management/db/permission.ts +31 -0
- package/src/modules/user-management/db/role.ts +28 -0
- package/src/modules/user-management/db/rolePermission.ts +44 -0
- package/src/modules/user-management/db/user.ts +38 -0
- package/src/modules/user-management/db/userRole.ts +44 -0
- package/src/modules/user-management/docs/commands/ActivateUser.md +36 -0
- package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +39 -0
- package/src/modules/user-management/docs/commands/AssignRoleToUser.md +43 -0
- package/src/modules/user-management/docs/commands/CreatePermission.md +35 -0
- package/src/modules/user-management/docs/commands/CreateRole.md +35 -0
- package/src/modules/user-management/docs/commands/CreateUser.md +41 -0
- package/src/modules/user-management/docs/commands/DeactivateUser.md +38 -0
- package/src/modules/user-management/docs/commands/LogAuditEvent.md +37 -0
- package/src/modules/user-management/docs/commands/ReactivateUser.md +37 -0
- package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +40 -0
- package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +40 -0
- package/src/modules/user-management/docs/features/audit-trail.md +80 -0
- package/src/modules/user-management/docs/features/role-based-access-control.md +76 -0
- package/src/modules/user-management/docs/features/user-account-management.md +64 -0
- package/src/modules/user-management/docs/models/AuditEvent.md +34 -0
- package/src/modules/user-management/docs/models/Permission.md +31 -0
- package/src/modules/user-management/docs/models/Role.md +31 -0
- package/src/modules/user-management/docs/models/RolePermission.md +33 -0
- package/src/modules/user-management/docs/models/User.md +47 -0
- package/src/modules/user-management/docs/models/UserRole.md +34 -0
- package/src/modules/user-management/docs/plans/2026-01-30-flattened-permissions-design.md +52 -0
- package/src/modules/user-management/executor/recomputeOnRolePermissionChange.ts +61 -0
- package/src/modules/user-management/generated/enums.ts +24 -0
- package/src/modules/user-management/generated/kysely-tailordb.ts +112 -0
- package/src/modules/user-management/index.ts +32 -0
- package/src/modules/user-management/lib/errors.ts +81 -0
- package/src/modules/user-management/lib/recomputeUserPermissions.ts +53 -0
- package/src/modules/user-management/lib/types.ts +31 -0
- package/src/modules/user-management/module.ts +77 -0
- package/src/modules/user-management/permissions.ts +15 -0
- package/src/modules/user-management/tailor.config.ts +11 -0
- package/src/modules/user-management/testing/fixtures.ts +98 -0
- package/src/schemas.ts +25 -0
- package/src/testing.ts +10 -0
- package/src/util.ts +3 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { runMdschema } from "../mdschema.js";
|
|
4
|
+
import { ALL_SCHEMAS } from "../schemas.js";
|
|
5
|
+
|
|
6
|
+
export const MODULE_TYPES = ["module", "feature", "command", "model"] as const;
|
|
7
|
+
export const APP_TYPES = [
|
|
8
|
+
"requirements",
|
|
9
|
+
"actors",
|
|
10
|
+
"business-flow",
|
|
11
|
+
"story",
|
|
12
|
+
"screen",
|
|
13
|
+
"resolver",
|
|
14
|
+
] as const;
|
|
15
|
+
export const ALL_TYPES = [...MODULE_TYPES, ...APP_TYPES] as const;
|
|
16
|
+
|
|
17
|
+
export type ScaffoldType = (typeof ALL_TYPES)[number];
|
|
18
|
+
|
|
19
|
+
const MODULE_DIR_MAP: Record<string, string> = {
|
|
20
|
+
feature: "docs/features",
|
|
21
|
+
command: "docs/commands",
|
|
22
|
+
model: "docs/models",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const APP_DIR_MAP: Record<string, string> = {
|
|
26
|
+
actors: "docs/actors",
|
|
27
|
+
"business-flow": "docs/business-flow",
|
|
28
|
+
screen: "docs/screen",
|
|
29
|
+
resolver: "docs/resolver",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function isModuleType(type: string): boolean {
|
|
33
|
+
return (MODULE_TYPES as readonly string[]).includes(type);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveScaffoldPath(
|
|
37
|
+
type: ScaffoldType,
|
|
38
|
+
parentName: string,
|
|
39
|
+
name: string | undefined,
|
|
40
|
+
root: string,
|
|
41
|
+
): string {
|
|
42
|
+
// Types that map to README.md (no name needed)
|
|
43
|
+
if (type === "module" || type === "requirements") {
|
|
44
|
+
return path.join(root, parentName, "README.md");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!name) {
|
|
48
|
+
throw new Error(`Name is required for scaffold type "${type}"`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// business-flow produces a README inside a named directory
|
|
52
|
+
if (type === "business-flow") {
|
|
53
|
+
return path.join(root, parentName, "docs/business-flow", name, "README.md");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// story accepts "flow/story-name" to place under the correct flow directory
|
|
57
|
+
if (type === "story") {
|
|
58
|
+
const parts = name.split("/");
|
|
59
|
+
if (parts.length !== 2) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Story name must be "<flow>/<story>" (e.g., "onboarding/admin--create-user")`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return path.join(root, parentName, "docs/business-flow", parts[0], "story", `${parts[1]}.md`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Module sub-types
|
|
68
|
+
if (MODULE_DIR_MAP[type]) {
|
|
69
|
+
return path.join(root, parentName, MODULE_DIR_MAP[type], `${name}.md`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// App sub-types
|
|
73
|
+
if (APP_DIR_MAP[type]) {
|
|
74
|
+
return path.join(root, parentName, APP_DIR_MAP[type], `${name}.md`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw new Error(`Unknown scaffold type: ${type}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function runScaffold(
|
|
81
|
+
type: ScaffoldType,
|
|
82
|
+
parentName: string,
|
|
83
|
+
name: string | undefined,
|
|
84
|
+
root: string,
|
|
85
|
+
cwd: string,
|
|
86
|
+
): Promise<number> {
|
|
87
|
+
const outputPath = resolveScaffoldPath(type, parentName, name, root);
|
|
88
|
+
const absoluteOutput = path.resolve(cwd, outputPath);
|
|
89
|
+
|
|
90
|
+
if (fs.existsSync(absoluteOutput)) {
|
|
91
|
+
console.error(`File already exists: ${outputPath}`);
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const schemaPath = ALL_SCHEMAS[type];
|
|
96
|
+
if (!schemaPath) {
|
|
97
|
+
console.error(`No schema found for type: ${type}`);
|
|
98
|
+
return 2;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
fs.mkdirSync(path.dirname(absoluteOutput), { recursive: true });
|
|
103
|
+
} catch (err) {
|
|
104
|
+
console.error(
|
|
105
|
+
`Failed to create directory: ${err instanceof Error ? err.message : String(err)}`,
|
|
106
|
+
);
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const { exitCode, stdout, stderr } = await runMdschema(
|
|
111
|
+
["generate", "--schema", schemaPath, "--output", absoluteOutput],
|
|
112
|
+
cwd,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (stdout.trim()) console.log(stdout);
|
|
116
|
+
if (stderr.trim()) console.error(stderr);
|
|
117
|
+
|
|
118
|
+
return exitCode;
|
|
119
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
5
|
+
import { runSyncCheck } from "./sync-check.js";
|
|
6
|
+
|
|
7
|
+
describe("runSyncCheck", () => {
|
|
8
|
+
let tmpDir: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sync-check-"));
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("returns 0 for an empty directory with no sources or docs", async () => {
|
|
19
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: "examples" }, tmpDir);
|
|
20
|
+
expect(result.exitCode).toBe(0);
|
|
21
|
+
expect(result.errors).toHaveLength(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("reports missing doc when source exists without doc", async () => {
|
|
25
|
+
const srcDir = path.join(tmpDir, "modules", "foo", "command");
|
|
26
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
27
|
+
fs.writeFileSync(path.join(srcDir, "createOrder.ts"), "export {}");
|
|
28
|
+
|
|
29
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: "examples" }, tmpDir);
|
|
30
|
+
expect(result.exitCode).toBe(1);
|
|
31
|
+
expect(result.errors).toContainEqual(
|
|
32
|
+
expect.objectContaining({ type: "missing-doc", expectedBasename: "createorder" }),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("reports orphaned doc when doc exists without source", async () => {
|
|
37
|
+
const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
|
|
38
|
+
fs.mkdirSync(docDir, { recursive: true });
|
|
39
|
+
fs.writeFileSync(path.join(docDir, "createOrder.md"), "# CreateOrder");
|
|
40
|
+
|
|
41
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: "examples" }, tmpDir);
|
|
42
|
+
expect(result.exitCode).toBe(1);
|
|
43
|
+
expect(result.errors).toContainEqual(
|
|
44
|
+
expect.objectContaining({ type: "orphaned-doc", expectedBasename: "createorder" }),
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("returns 0 when source and doc match", async () => {
|
|
49
|
+
const srcDir = path.join(tmpDir, "modules", "foo", "command");
|
|
50
|
+
const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
|
|
51
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
52
|
+
fs.mkdirSync(docDir, { recursive: true });
|
|
53
|
+
fs.writeFileSync(path.join(srcDir, "createOrder.ts"), "export {}");
|
|
54
|
+
fs.writeFileSync(path.join(docDir, "createOrder.md"), "# CreateOrder");
|
|
55
|
+
|
|
56
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: "examples" }, tmpDir);
|
|
57
|
+
expect(result.exitCode).toBe(0);
|
|
58
|
+
expect(result.errors).toHaveLength(0);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("excludes test files from source matching", async () => {
|
|
62
|
+
const srcDir = path.join(tmpDir, "modules", "foo", "command");
|
|
63
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
64
|
+
fs.writeFileSync(path.join(srcDir, "createOrder.test.ts"), "test()");
|
|
65
|
+
|
|
66
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: "examples" }, tmpDir);
|
|
67
|
+
expect(result.exitCode).toBe(0);
|
|
68
|
+
expect(result.errors).toHaveLength(0);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("uses custom modulesRoot to rewrite glob patterns", async () => {
|
|
72
|
+
const srcDir = path.join(tmpDir, "custom-mods", "foo", "command");
|
|
73
|
+
const docDir = path.join(tmpDir, "custom-mods", "foo", "docs", "commands");
|
|
74
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
75
|
+
fs.mkdirSync(docDir, { recursive: true });
|
|
76
|
+
fs.writeFileSync(path.join(srcDir, "createOrder.ts"), "export {}");
|
|
77
|
+
fs.writeFileSync(path.join(docDir, "createOrder.md"), "# CreateOrder");
|
|
78
|
+
|
|
79
|
+
const result = await runSyncCheck({ modulesRoot: "custom-mods" }, tmpDir);
|
|
80
|
+
expect(result.exitCode).toBe(0);
|
|
81
|
+
expect(result.summary.totalSources).toBe(1);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("uses custom appRoot to rewrite glob patterns", async () => {
|
|
85
|
+
const srcDir = path.join(
|
|
86
|
+
tmpDir,
|
|
87
|
+
"apps",
|
|
88
|
+
"app1",
|
|
89
|
+
"backend",
|
|
90
|
+
"src",
|
|
91
|
+
"modules",
|
|
92
|
+
"m1",
|
|
93
|
+
"resolvers",
|
|
94
|
+
);
|
|
95
|
+
const docDir = path.join(tmpDir, "apps", "app1", "docs", "resolver");
|
|
96
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
97
|
+
fs.mkdirSync(docDir, { recursive: true });
|
|
98
|
+
fs.writeFileSync(path.join(srcDir, "myResolver.ts"), "export {}");
|
|
99
|
+
fs.writeFileSync(path.join(docDir, "myResolver.md"), "# MyResolver");
|
|
100
|
+
|
|
101
|
+
const result = await runSyncCheck({ appRoot: "apps" }, tmpDir);
|
|
102
|
+
expect(result.exitCode).toBe(0);
|
|
103
|
+
expect(result.summary.totalSources).toBe(1);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("checks only module patterns when appRoot is not set", async () => {
|
|
107
|
+
const resolverSrcDir = path.join(
|
|
108
|
+
tmpDir,
|
|
109
|
+
"examples",
|
|
110
|
+
"app1",
|
|
111
|
+
"backend",
|
|
112
|
+
"src",
|
|
113
|
+
"modules",
|
|
114
|
+
"m1",
|
|
115
|
+
"resolvers",
|
|
116
|
+
);
|
|
117
|
+
fs.mkdirSync(resolverSrcDir, { recursive: true });
|
|
118
|
+
fs.writeFileSync(path.join(resolverSrcDir, "myResolver.ts"), "export {}");
|
|
119
|
+
|
|
120
|
+
const result = await runSyncCheck({ modulesRoot: "modules", appRoot: undefined }, tmpDir);
|
|
121
|
+
// Without appRoot, app-compose patterns are not checked
|
|
122
|
+
expect(result.exitCode).toBe(0);
|
|
123
|
+
expect(result.errors).toHaveLength(0);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fg from "fast-glob";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
|
|
5
|
+
interface CategoryConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
sourcePattern: string;
|
|
8
|
+
docPattern: string;
|
|
9
|
+
exclusions: RegExp[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CheckError {
|
|
13
|
+
type: "missing-doc" | "orphaned-doc";
|
|
14
|
+
category: string;
|
|
15
|
+
sourcePath?: string;
|
|
16
|
+
docPath?: string;
|
|
17
|
+
expectedBasename: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface SyncCheckResult {
|
|
21
|
+
exitCode: number;
|
|
22
|
+
errors: CheckError[];
|
|
23
|
+
summary: {
|
|
24
|
+
categoriesChecked: number;
|
|
25
|
+
totalSources: number;
|
|
26
|
+
totalDocs: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function moduleCategories(root: string): CategoryConfig[] {
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
name: "command",
|
|
34
|
+
sourcePattern: `${root}/*/command/*.ts`,
|
|
35
|
+
docPattern: `${root}/*/docs/commands/*.md`,
|
|
36
|
+
exclusions: [/\.test\.ts$/],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "model",
|
|
40
|
+
sourcePattern: `${root}/*/db/*.ts`,
|
|
41
|
+
docPattern: `${root}/*/docs/models/*.md`,
|
|
42
|
+
exclusions: [/\.test\.ts$/, /^index\.ts$/],
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function appComposeCategories(root: string): CategoryConfig[] {
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
name: "resolver",
|
|
51
|
+
sourcePattern: `${root}/*/backend/src/modules/**/resolvers/*.ts`,
|
|
52
|
+
docPattern: `${root}/*/docs/resolver/*.md`,
|
|
53
|
+
exclusions: [/\.test\.ts$/, /^index\.ts$/],
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function shouldExclude(fileName: string, exclusions: RegExp[]): boolean {
|
|
59
|
+
return exclusions.some((pattern) => pattern.test(fileName));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export async function runSyncCheck(
|
|
63
|
+
config: { modulesRoot?: string; appRoot?: string },
|
|
64
|
+
cwd: string,
|
|
65
|
+
): Promise<SyncCheckResult> {
|
|
66
|
+
const errors: CheckError[] = [];
|
|
67
|
+
let totalSources = 0;
|
|
68
|
+
let totalDocs = 0;
|
|
69
|
+
|
|
70
|
+
const allCategories: CategoryConfig[] = [];
|
|
71
|
+
if (config.modulesRoot) {
|
|
72
|
+
allCategories.push(...moduleCategories(config.modulesRoot));
|
|
73
|
+
}
|
|
74
|
+
if (config.appRoot) {
|
|
75
|
+
allCategories.push(...appComposeCategories(config.appRoot));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
for (const category of allCategories) {
|
|
79
|
+
const sources = await fg(category.sourcePattern, { cwd });
|
|
80
|
+
const docs = await fg(category.docPattern, { cwd });
|
|
81
|
+
|
|
82
|
+
const sourceBasenames = new Map<string, string>();
|
|
83
|
+
const docBasenames = new Map<string, string>();
|
|
84
|
+
|
|
85
|
+
for (const sourcePath of sources) {
|
|
86
|
+
const fileName = path.basename(sourcePath);
|
|
87
|
+
if (shouldExclude(fileName, category.exclusions)) continue;
|
|
88
|
+
const basename = path.basename(sourcePath, path.extname(sourcePath));
|
|
89
|
+
sourceBasenames.set(basename.toLowerCase(), sourcePath);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const docPath of docs) {
|
|
93
|
+
const basename = path.basename(docPath, path.extname(docPath));
|
|
94
|
+
docBasenames.set(basename.toLowerCase(), docPath);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [basename, sourcePath] of sourceBasenames) {
|
|
98
|
+
if (!docBasenames.has(basename)) {
|
|
99
|
+
errors.push({
|
|
100
|
+
type: "missing-doc",
|
|
101
|
+
category: category.name,
|
|
102
|
+
sourcePath,
|
|
103
|
+
expectedBasename: basename,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (const [basename, docPath] of docBasenames) {
|
|
109
|
+
if (!sourceBasenames.has(basename)) {
|
|
110
|
+
errors.push({
|
|
111
|
+
type: "orphaned-doc",
|
|
112
|
+
category: category.name,
|
|
113
|
+
docPath,
|
|
114
|
+
expectedBasename: basename,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
totalSources += sourceBasenames.size;
|
|
120
|
+
totalDocs += docBasenames.size;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
exitCode: errors.length > 0 ? 1 : 0,
|
|
125
|
+
errors,
|
|
126
|
+
summary: {
|
|
127
|
+
categoriesChecked: allCategories.length,
|
|
128
|
+
totalSources,
|
|
129
|
+
totalDocs,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function formatSyncCheckReport(result: SyncCheckResult): string {
|
|
135
|
+
const lines: string[] = [];
|
|
136
|
+
lines.push(chalk.bold("docs-sync-check: Checking source-documentation correspondence...\n"));
|
|
137
|
+
|
|
138
|
+
if (result.errors.length > 0) {
|
|
139
|
+
lines.push(chalk.red.bold("Errors:\n"));
|
|
140
|
+
const byCategory = new Map<string, CheckError[]>();
|
|
141
|
+
for (const error of result.errors) {
|
|
142
|
+
const existing = byCategory.get(error.category) ?? [];
|
|
143
|
+
existing.push(error);
|
|
144
|
+
byCategory.set(error.category, existing);
|
|
145
|
+
}
|
|
146
|
+
for (const [category, categoryErrors] of byCategory) {
|
|
147
|
+
lines.push(chalk.cyan(` Category: ${category}\n`));
|
|
148
|
+
for (const error of categoryErrors) {
|
|
149
|
+
if (error.type === "missing-doc") {
|
|
150
|
+
lines.push(` ${chalk.red(error.sourcePath)}`);
|
|
151
|
+
lines.push(` ${chalk.yellow("Missing documentation for:")} ${error.expectedBasename}`);
|
|
152
|
+
} else {
|
|
153
|
+
lines.push(` ${chalk.red(error.docPath)}`);
|
|
154
|
+
lines.push(
|
|
155
|
+
` ${chalk.yellow("Orphaned documentation:")} no source file for ${error.expectedBasename}`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
lines.push("");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
lines.push(chalk.green("All source files have corresponding documentation.\n"));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
lines.push(chalk.bold("Summary:"));
|
|
166
|
+
lines.push(` Categories checked: ${result.summary.categoriesChecked}`);
|
|
167
|
+
lines.push(
|
|
168
|
+
` Source files: ${result.summary.totalSources}, Doc files: ${result.summary.totalDocs}`,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
if (result.errors.length > 0) {
|
|
172
|
+
lines.push(chalk.red(` Errors: ${result.errors.length}`));
|
|
173
|
+
lines.push("");
|
|
174
|
+
lines.push(chalk.red.bold(`docs-sync-check failed with ${result.errors.length} error(s).`));
|
|
175
|
+
} else {
|
|
176
|
+
lines.push(chalk.green(" Errors: 0"));
|
|
177
|
+
lines.push("");
|
|
178
|
+
lines.push(chalk.green.bold("docs-sync-check passed."));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return lines.join("\n");
|
|
182
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { describe, it, expect } from "vitest";
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const CLI_PATH = path.resolve(__dirname, "..", "dist", "cli.js");
|
|
9
|
+
const REPO_ROOT = path.resolve(__dirname, "..", "..", "..");
|
|
10
|
+
|
|
11
|
+
const skipReason = fs.existsSync(CLI_PATH) ? undefined : "Run `pnpm build` first";
|
|
12
|
+
|
|
13
|
+
describe.skipIf(skipReason)("integration", () => {
|
|
14
|
+
it("check command runs against sdk-plugins modules", () => {
|
|
15
|
+
// mdschema may report validation errors in real docs, so we allow non-zero exit codes
|
|
16
|
+
// but verify the CLI itself doesn't crash with an unexpected error
|
|
17
|
+
try {
|
|
18
|
+
const result = execFileSync(
|
|
19
|
+
"node",
|
|
20
|
+
[CLI_PATH, "check", "--modules-root", "packages/erp-kit/src/modules"],
|
|
21
|
+
{
|
|
22
|
+
cwd: REPO_ROOT,
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
env: { ...process.env },
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
expect(result).toBeDefined();
|
|
28
|
+
} catch (err: unknown) {
|
|
29
|
+
const error = err as { status: number; stderr: string };
|
|
30
|
+
// exit code 1 = validation errors in docs (acceptable)
|
|
31
|
+
// exit code 2 = CLI usage error (unexpected)
|
|
32
|
+
expect(error.status).toBe(1);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("sync-check command runs against sdk-plugins modules", () => {
|
|
37
|
+
try {
|
|
38
|
+
const result = execFileSync(
|
|
39
|
+
"node",
|
|
40
|
+
[CLI_PATH, "sync-check", "--modules-root", "packages/erp-kit/src/modules"],
|
|
41
|
+
{
|
|
42
|
+
cwd: REPO_ROOT,
|
|
43
|
+
encoding: "utf-8",
|
|
44
|
+
env: { ...process.env },
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
expect(result).toContain("docs-sync-check");
|
|
48
|
+
} catch (err: unknown) {
|
|
49
|
+
const error = err as { status: number; stdout: string };
|
|
50
|
+
// sync-check may fail with errors=1 but should still produce a report
|
|
51
|
+
expect(error.stdout).toContain("docs-sync-check");
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("--help prints usage", () => {
|
|
56
|
+
const result = execFileSync("node", [CLI_PATH, "--help"], {
|
|
57
|
+
encoding: "utf-8",
|
|
58
|
+
});
|
|
59
|
+
expect(result).toContain("erp-kit");
|
|
60
|
+
expect(result).toContain("check");
|
|
61
|
+
expect(result).toContain("scaffold");
|
|
62
|
+
});
|
|
63
|
+
});
|
package/src/mdschema.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
|
|
8
|
+
interface PackageJson {
|
|
9
|
+
bin?: string | Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getMdschemaBin(): string {
|
|
13
|
+
const pkgPath = require.resolve("@jackchuka/mdschema/package.json");
|
|
14
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8")) as PackageJson;
|
|
15
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.mdschema;
|
|
16
|
+
if (!bin) {
|
|
17
|
+
throw new Error("Could not resolve mdschema binary from package.json bin field");
|
|
18
|
+
}
|
|
19
|
+
return path.join(path.dirname(pkgPath), bin);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface MdschemaResult {
|
|
23
|
+
exitCode: number;
|
|
24
|
+
stdout: string;
|
|
25
|
+
stderr: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function runMdschema(args: string[], cwd?: string): Promise<MdschemaResult> {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
execFile(
|
|
31
|
+
getMdschemaBin(),
|
|
32
|
+
args,
|
|
33
|
+
{ encoding: "utf-8", cwd, timeout: 30_000 },
|
|
34
|
+
(error, stdout, stderr) => {
|
|
35
|
+
if (error) {
|
|
36
|
+
const execError = error as NodeJS.ErrnoException & { status?: number };
|
|
37
|
+
resolve({
|
|
38
|
+
exitCode: execError.code === "ENOENT" ? 127 : (execError.status ?? 1),
|
|
39
|
+
stdout: stdout ?? "",
|
|
40
|
+
stderr: stderr ?? "",
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
resolve({ exitCode: 0, stdout: stdout ?? "", stderr: stderr ?? "" });
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface MockServer {
|
|
5
|
+
url: string;
|
|
6
|
+
port: number;
|
|
7
|
+
stop: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Start a Mockoon mock server from a mock.json file.
|
|
12
|
+
* Returns a handle with the server URL and a stop function.
|
|
13
|
+
*/
|
|
14
|
+
export async function createMockServer(mockJsonPath: string, port?: number): Promise<MockServer> {
|
|
15
|
+
const { MockoonServer, createLoggerInstance, listenServerEvents } =
|
|
16
|
+
await import("@mockoon/commons-server");
|
|
17
|
+
type Environment = import("@mockoon/commons").Environment;
|
|
18
|
+
|
|
19
|
+
const resolvedPath = resolve(mockJsonPath);
|
|
20
|
+
const environment = JSON.parse(readFileSync(resolvedPath, "utf-8")) as Environment;
|
|
21
|
+
if (port !== undefined) {
|
|
22
|
+
environment.port = port;
|
|
23
|
+
}
|
|
24
|
+
const actualPort = environment.port;
|
|
25
|
+
|
|
26
|
+
const logger = createLoggerInstance(null);
|
|
27
|
+
const server = new MockoonServer(environment, {
|
|
28
|
+
environmentDirectory: dirname(resolvedPath),
|
|
29
|
+
enableAdminApi: false,
|
|
30
|
+
disableTls: true,
|
|
31
|
+
enableRandomLatency: false,
|
|
32
|
+
maxTransactionLogs: 100,
|
|
33
|
+
envVarsPrefix: "MOCKOON_",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
listenServerEvents(server, environment, logger, false);
|
|
37
|
+
|
|
38
|
+
await new Promise<void>((resolve, reject) => {
|
|
39
|
+
server.on("started", resolve);
|
|
40
|
+
server.on("error", (errorCode, originalError) => {
|
|
41
|
+
reject(originalError ?? new Error(`Mockoon error: ${errorCode}`));
|
|
42
|
+
});
|
|
43
|
+
server.start();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
url: `http://127.0.0.1:${actualPort}`,
|
|
48
|
+
port: actualPort,
|
|
49
|
+
stop: () =>
|
|
50
|
+
new Promise<void>((resolve) => {
|
|
51
|
+
server.on("stopped", resolve);
|
|
52
|
+
server.stop();
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
}
|
package/src/module.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// shared/internal
|
|
2
|
+
export { defineCommand, type Command } from "./modules/shared/defineCommand";
|
|
3
|
+
export { definePermissions } from "./modules/shared/definePermissions";
|
|
4
|
+
export { requirePermission } from "./modules/shared/requirePermission";
|
|
5
|
+
export { createDomainError, InsufficientPermissionError } from "./modules/shared/errors";
|
|
6
|
+
export type { CommandContext } from "./modules/shared/types";
|
|
7
|
+
export type {
|
|
8
|
+
InferSchema,
|
|
9
|
+
Selectable,
|
|
10
|
+
Insertable,
|
|
11
|
+
Updateable,
|
|
12
|
+
FieldsToInsertable,
|
|
13
|
+
} from "./modules/shared/entityTypes";
|
|
14
|
+
|
|
15
|
+
// primitives
|
|
16
|
+
export { defineModule as definePrimitivesModule } from "./modules/primitives/module";
|
|
17
|
+
export {
|
|
18
|
+
permissions as primitivesPermissions,
|
|
19
|
+
own as primitivesOwn,
|
|
20
|
+
all as primitivesAll,
|
|
21
|
+
} from "./modules/primitives/permissions";
|
|
22
|
+
export {
|
|
23
|
+
UoMCategoryNotFoundError,
|
|
24
|
+
UnitNotFoundError,
|
|
25
|
+
IncompatibleUnitsError,
|
|
26
|
+
InactiveUnitError,
|
|
27
|
+
CurrencyNotFoundError,
|
|
28
|
+
InactiveCurrencyError,
|
|
29
|
+
ExchangeRateNotFoundError,
|
|
30
|
+
CannotDeactivateReferenceUnitError,
|
|
31
|
+
CategoryNotActiveError,
|
|
32
|
+
DuplicateUnitSymbolError,
|
|
33
|
+
InvalidConversionFactorError,
|
|
34
|
+
InvalidRoundingPrecisionError,
|
|
35
|
+
DuplicateCategoryNameError,
|
|
36
|
+
CategoryHasActiveUnitsError,
|
|
37
|
+
UnitNotInCategoryError,
|
|
38
|
+
InvalidISOCodeError,
|
|
39
|
+
DuplicateCurrencyCodeError,
|
|
40
|
+
InvalidDecimalPlacesError,
|
|
41
|
+
CannotDeactivateBaseCurrencyError,
|
|
42
|
+
CannotSetInactiveAsBaseCurrencyError,
|
|
43
|
+
SameCurrencyPairError,
|
|
44
|
+
InvalidExchangeRateError,
|
|
45
|
+
} from "./modules/primitives/lib/errors";
|
|
46
|
+
export { type ConvertQuantityInput } from "./modules/primitives/command/convertQuantity";
|
|
47
|
+
export { type ActivateCategoryInput } from "./modules/primitives/command/activateCategory";
|
|
48
|
+
export { type DeactivateCategoryInput } from "./modules/primitives/command/deactivateCategory";
|
|
49
|
+
export { type SetReferenceUnitInput } from "./modules/primitives/command/setReferenceUnit";
|
|
50
|
+
export { type ActivateUnitInput } from "./modules/primitives/command/activateUnit";
|
|
51
|
+
export { type DeactivateUnitInput } from "./modules/primitives/command/deactivateUnit";
|
|
52
|
+
export { type ConvertAmountInput } from "./modules/primitives/command/convertAmount";
|
|
53
|
+
export { type ActivateCurrencyInput } from "./modules/primitives/command/activateCurrency";
|
|
54
|
+
export { type DeactivateCurrencyInput } from "./modules/primitives/command/deactivateCurrency";
|
|
55
|
+
export { type SetBaseCurrencyInput } from "./modules/primitives/command/setBaseCurrency";
|
|
56
|
+
// user-management
|
|
57
|
+
export { defineModule as defineUserManagementModule } from "./modules/user-management/module";
|
|
58
|
+
export {
|
|
59
|
+
permissions as userManagementPermissions,
|
|
60
|
+
own as userManagementOwn,
|
|
61
|
+
all as userManagementAll,
|
|
62
|
+
} from "./modules/user-management/permissions";
|
|
63
|
+
export { AuditEventEventType, UserStatus } from "./modules/user-management/generated/enums";
|
|
64
|
+
export {
|
|
65
|
+
UserNotFoundError,
|
|
66
|
+
UserAlreadyExistsError,
|
|
67
|
+
UserNotActiveError,
|
|
68
|
+
InvalidEmailError,
|
|
69
|
+
MissingRequiredFieldError,
|
|
70
|
+
InvalidStatusTransitionError,
|
|
71
|
+
PermissionNotFoundError,
|
|
72
|
+
DuplicatePermissionKeyError,
|
|
73
|
+
InvalidPermissionKeyFormatError,
|
|
74
|
+
RoleNotFoundError,
|
|
75
|
+
DuplicateRoleNameError,
|
|
76
|
+
AssignmentNotFoundError,
|
|
77
|
+
InvalidEventTypeError,
|
|
78
|
+
} from "./modules/user-management/lib/errors";
|
|
79
|
+
export { type ActivateUserInput } from "./modules/user-management/command/activateUser";
|
|
80
|
+
export { type DeactivateUserInput } from "./modules/user-management/command/deactivateUser";
|
|
81
|
+
export { type ReactivateUserInput } from "./modules/user-management/command/reactivateUser";
|
|
82
|
+
export { type AssignPermissionToRoleInput } from "./modules/user-management/command/assignPermissionToRole";
|
|
83
|
+
export { type RevokePermissionFromRoleInput } from "./modules/user-management/command/revokePermissionFromRole";
|
|
84
|
+
export { type AssignRoleToUserInput } from "./modules/user-management/command/assignRoleToUser";
|
|
85
|
+
export { type RevokeRoleFromUserInput } from "./modules/user-management/command/revokeRoleFromUser";
|
|
86
|
+
export { type LogAuditEventInput } from "./modules/user-management/command/logAuditEvent";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|