@yss123/cage-cli 0.1.0 → 0.2.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 +23 -1
- package/dist/analyze.js +2 -0
- package/dist/analyze.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +0 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +72 -0
- package/dist/context.js +202 -0
- package/dist/context.js.map +1 -0
- package/dist/create-prompt.d.ts +5 -0
- package/dist/create-prompt.js +50 -0
- package/dist/create-prompt.js.map +1 -0
- package/dist/create.d.ts +18 -1
- package/dist/create.js +30 -13
- package/dist/create.js.map +1 -1
- package/dist/dev.js +12 -51
- package/dist/dev.js.map +1 -1
- package/dist/gen/contracts.js +34 -13
- package/dist/gen/contracts.js.map +1 -1
- package/dist/gen/index.js +43 -3
- package/dist/gen/index.js.map +1 -1
- package/dist/gen/zod-code.d.ts +1 -1
- package/dist/gen/zod-code.js +3 -1
- package/dist/gen/zod-code.js.map +1 -1
- package/dist/graph-command.d.ts +11 -0
- package/dist/graph-command.js +67 -0
- package/dist/graph-command.js.map +1 -0
- package/dist/graph-model.d.ts +21 -0
- package/dist/graph-model.js +101 -0
- package/dist/graph-model.js.map +1 -0
- package/dist/graph-presentation.d.ts +11 -0
- package/dist/graph-presentation.js +25 -0
- package/dist/graph-presentation.js.map +1 -0
- package/dist/graph-query.d.ts +171 -0
- package/dist/graph-query.js +242 -0
- package/dist/graph-query.js.map +1 -0
- package/dist/graph-relations.d.ts +14 -0
- package/dist/graph-relations.js +142 -0
- package/dist/graph-relations.js.map +1 -0
- package/dist/graph-search.d.ts +21 -0
- package/dist/graph-search.js +63 -0
- package/dist/graph-search.js.map +1 -0
- package/dist/graph-snapshot.d.ts +2 -4
- package/dist/graph-snapshot.js +2 -19
- package/dist/graph-snapshot.js.map +1 -1
- package/dist/graph.js +19 -1
- package/dist/graph.js.map +1 -1
- package/dist/impact.d.ts +6 -0
- package/dist/impact.js +28 -16
- package/dist/impact.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +6 -0
- package/dist/init.js +131 -0
- package/dist/init.js.map +1 -0
- package/dist/main.js +77 -32
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +3 -6
- package/dist/migrate.js +14 -53
- package/dist/migrate.js.map +1 -1
- package/dist/ontology.d.ts +3 -1
- package/dist/ontology.js +13 -3
- package/dist/ontology.js.map +1 -1
- package/dist/project-structure.d.ts +8 -0
- package/dist/project-structure.js +94 -0
- package/dist/project-structure.js.map +1 -0
- package/dist/static-check.js +1 -4
- package/dist/static-check.js.map +1 -1
- package/dist/sync.js +82 -10
- package/dist/sync.js.map +1 -1
- package/graph-ui/app.js +46 -8
- package/graph-ui/graph-model.js +100 -0
- package/graph-ui/graph-relations.js +141 -0
- package/graph-ui/graph-search.js +62 -0
- package/graph-ui/model.js +19 -77
- package/graph-ui/relations.js +2 -125
- package/graph-ui/structure.js +4 -1
- package/graph-ui/style.css +21 -0
- package/package.json +8 -8
- package/templates/app/.env.example +58 -14
- package/templates/app/AGENTS.md +95 -12
- package/templates/app/Dockerfile +2 -0
- package/templates/app/README.md +46 -16
- package/templates/app/_gitignore +8 -0
- package/templates/app/apps/api/package.json +2 -2
- package/templates/app/apps/web/src/app/app.tsx +18 -0
- package/templates/app/apps/web/src/app/workspace-layout.tsx +70 -0
- package/templates/app/apps/web/src/main.tsx +4 -543
- package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +20 -0
- package/templates/app/apps/web/src/modules/approval/index.ts +2 -0
- package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +54 -0
- package/templates/app/apps/web/src/modules/auth/index.ts +1 -0
- package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +59 -0
- package/templates/app/apps/web/src/modules/inventory/index.ts +1 -0
- package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +74 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +60 -0
- package/templates/app/apps/web/src/modules/purchase/index.ts +2 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +210 -0
- package/templates/app/apps/web/src/shared/hooks/use-command.ts +29 -0
- package/templates/app/apps/web/src/shared/lib/error-message.ts +15 -0
- package/templates/app/apps/web/src/shared/ui/notice.tsx +13 -0
- package/templates/app/apps/web/src/shared/ui/page-heading.tsx +28 -0
- package/templates/app/apps/web/vite.config.ts +3 -0
- package/templates/app/cage.config.json +1 -1
- package/templates/app/docs/ai/README.md +77 -0
- package/templates/app/docs/ai/architecture.md +122 -0
- package/templates/app/docs/ai/ontology-context.md +117 -0
- package/templates/app/docs/ai/primitives.md +249 -0
- package/templates/app/docs/ai/project-structure.md +123 -0
- package/templates/app/docs/ai/purchase-example.md +97 -0
- package/templates/app/docs/ai/recipes.md +81 -0
- package/templates/app/docs/ai/relations.md +160 -0
- package/templates/app/docs/ai/transfers.md +92 -0
- package/templates/app/docs/ai/troubleshooting.md +60 -0
- package/templates/app/docs/ai/workflow.md +139 -0
- package/templates/app/docs/errors/CAGE-APPR-001.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-002.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-003.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-004.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-005.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-006.md +47 -0
- package/templates/app/docs/errors/CAGE-APPR-007.md +50 -0
- package/templates/app/docs/errors/CAGE-APPR-010.md +48 -0
- package/templates/app/docs/errors/CAGE-AUTH-001.md +47 -0
- package/templates/app/docs/errors/CAGE-BUDGET-001.md +47 -0
- package/templates/app/docs/errors/CAGE-BUDGET-002.md +47 -0
- package/templates/app/docs/errors/CAGE-BUDGET-003.md +47 -0
- package/templates/app/docs/errors/CAGE-CMD-002.md +47 -0
- package/templates/app/docs/errors/CAGE-CMD-003.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-001.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-002.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-003.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-004.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-005.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-006.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-007.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-008.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-009.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-010.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-011.md +47 -0
- package/templates/app/docs/errors/CAGE-CONN-012.md +47 -0
- package/templates/app/docs/errors/CAGE-CREATE-001.md +52 -0
- package/templates/app/docs/errors/CAGE-DECL-001.md +48 -0
- package/templates/app/docs/errors/CAGE-DECL-002.md +47 -0
- package/templates/app/docs/errors/CAGE-DECL-003.md +47 -0
- package/templates/app/docs/errors/CAGE-DECL-004.md +47 -0
- package/templates/app/docs/errors/CAGE-DEP-001.md +48 -0
- package/templates/app/docs/errors/CAGE-DEP-002.md +47 -0
- package/templates/app/docs/errors/CAGE-DEP-003.md +47 -0
- package/templates/app/docs/errors/CAGE-DEP-004.md +47 -0
- package/templates/app/docs/errors/CAGE-DEP-005.md +47 -0
- package/templates/app/docs/errors/CAGE-DLQ-001.md +48 -0
- package/templates/app/docs/errors/CAGE-ENV-001.md +52 -0
- package/templates/app/docs/errors/CAGE-EVENT-001.md +47 -0
- package/templates/app/docs/errors/CAGE-EVENT-002.md +50 -0
- package/templates/app/docs/errors/CAGE-FIELD-001.md +47 -0
- package/templates/app/docs/errors/CAGE-FIELD-002.md +47 -0
- package/templates/app/docs/errors/CAGE-FIELD-003.md +47 -0
- package/templates/app/docs/errors/CAGE-FIELD-004.md +47 -0
- package/templates/app/docs/errors/CAGE-GEN-001.md +48 -0
- package/templates/app/docs/errors/CAGE-GEN-002.md +47 -0
- package/templates/app/docs/errors/CAGE-GRANT-001.md +49 -0
- package/templates/app/docs/errors/CAGE-GRANT-002.md +48 -0
- package/templates/app/docs/errors/CAGE-GRANT-003.md +47 -0
- package/templates/app/docs/errors/CAGE-IMPACT-001.md +48 -0
- package/templates/app/docs/errors/CAGE-INIT-001.md +47 -0
- package/templates/app/docs/errors/CAGE-INIT-002.md +49 -0
- package/templates/app/docs/errors/CAGE-INIT-003.md +48 -0
- package/templates/app/docs/errors/CAGE-INIT-004.md +48 -0
- package/templates/app/docs/errors/CAGE-JOB-001.md +47 -0
- package/templates/app/docs/errors/CAGE-JOB-002.md +47 -0
- package/templates/app/docs/errors/CAGE-JOB-003.md +47 -0
- package/templates/app/docs/errors/CAGE-LINT-001.md +47 -0
- package/templates/app/docs/errors/CAGE-MIG-001.md +47 -0
- package/templates/app/docs/errors/CAGE-MIG-002.md +47 -0
- package/templates/app/docs/errors/CAGE-MIG-003.md +5 -0
- package/templates/app/docs/errors/CAGE-MIG-004.md +5 -0
- package/templates/app/docs/errors/CAGE-MIG-005.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-001.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-002.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-003.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-004.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-005.md +47 -0
- package/templates/app/docs/errors/CAGE-NAME-006.md +47 -0
- package/templates/app/docs/errors/CAGE-ORG-001.md +49 -0
- package/templates/app/docs/errors/CAGE-PAIR-002.md +50 -0
- package/templates/app/docs/errors/CAGE-QUERY-001.md +47 -0
- package/templates/app/docs/errors/CAGE-QUERY-002.md +47 -0
- package/templates/app/docs/errors/CAGE-QUERY-003.md +49 -0
- package/templates/app/docs/errors/CAGE-REACT-001.md +47 -0
- package/templates/app/docs/errors/CAGE-REACT-002.md +47 -0
- package/templates/app/docs/errors/CAGE-READS-001.md +47 -0
- package/templates/app/docs/errors/CAGE-REG-001.md +53 -0
- package/templates/app/docs/errors/CAGE-REG-002.md +48 -0
- package/templates/app/docs/errors/CAGE-REG-003.md +47 -0
- package/templates/app/docs/errors/CAGE-REL-001.md +64 -0
- package/templates/app/docs/errors/CAGE-ROUTE-001.md +47 -0
- package/templates/app/docs/errors/CAGE-SCOPE-001.md +47 -0
- package/templates/app/docs/errors/CAGE-SCOPE-002.md +47 -0
- package/templates/app/docs/errors/CAGE-SECRET-001.md +48 -0
- package/templates/app/docs/errors/CAGE-SECRET-002.md +47 -0
- package/templates/app/docs/errors/CAGE-SENS-001.md +48 -0
- package/templates/app/docs/errors/CAGE-SQL-001.md +47 -0
- package/templates/app/docs/errors/CAGE-SQL-002.md +47 -0
- package/templates/app/docs/errors/CAGE-STATE-001.md +49 -0
- package/templates/app/docs/errors/CAGE-STATE-002.md +47 -0
- package/templates/app/docs/errors/CAGE-STATE-003.md +47 -0
- package/templates/app/docs/errors/CAGE-STATE-004.md +47 -0
- package/templates/app/docs/errors/CAGE-STATE-005.md +48 -0
- package/templates/app/docs/errors/CAGE-STATE-010.md +48 -0
- package/templates/app/docs/errors/CAGE-STATE-011.md +48 -0
- package/templates/app/docs/errors/CAGE-STRUCT-001.md +51 -0
- package/templates/app/docs/errors/CAGE-STRUCT-002.md +51 -0
- package/templates/app/docs/errors/CAGE-SYNC-001.md +48 -0
- package/templates/app/docs/errors/CAGE-TEST-001.md +47 -0
- package/templates/app/docs/errors/CAGE-UNSAFE-001.md +48 -0
- package/templates/app/docs/errors/CAGE-UPGRADE-001.md +48 -0
- package/templates/app/docs/errors/README.md +307 -0
- package/templates/app/docs/errors/runtime.md +50 -0
- package/templates/app/package.json +4 -7
- package/templates/app/packages/contracts/package.json +1 -1
- package/templates/app/packages/contracts/src/{dept.ts → aggregates/dept/index.ts} +3 -3
- package/templates/app/packages/contracts/src/{inventory.ts → aggregates/inventory/index.ts} +3 -3
- package/templates/app/packages/contracts/src/{inventory-lock.ts → aggregates/inventory-lock/index.ts} +3 -3
- package/templates/app/packages/contracts/src/{purchase-order.ts → aggregates/purchase-order/index.ts} +3 -3
- package/templates/app/packages/contracts/src/{role.ts → aggregates/role/index.ts} +3 -3
- package/templates/app/packages/contracts/src/{user.ts → aggregates/user/index.ts} +3 -3
- package/templates/app/packages/contracts/src/index.ts +14 -14
- package/templates/app/packages/domain/package.json +4 -4
- package/templates/app/packages/domain/src/index.ts +4 -7
- package/templates/app/packages/domain/src/{erp.ts → integrations/erp.ts} +1 -1
- package/templates/app/packages/domain/src/modules/inventory/index.ts +2 -0
- package/templates/app/packages/domain/src/modules/purchase/index.ts +6 -0
- package/templates/app/packages/domain/src/{purchase-order.test.ts → modules/purchase/purchase-order.test.ts} +2 -2
- package/templates/app/packages/domain/src/{purchase-order.ts → modules/purchase/purchase-order.ts} +1 -1
- package/templates/app/packages/domain/src/{reactions.ts → workflows/purchase-inventory.ts} +2 -2
- package/templates/blank/.dockerignore +10 -0
- package/templates/blank/.env.example +61 -0
- package/templates/blank/.github/workflows/cage.yml +44 -0
- package/templates/blank/AGENTS.md +96 -0
- package/templates/blank/Dockerfile +25 -0
- package/templates/blank/README.md +37 -0
- package/templates/blank/_gitignore +8 -0
- package/templates/blank/apps/api/package.json +15 -0
- package/templates/blank/apps/api/src/main.ts +11 -0
- package/templates/blank/apps/api/src/worker.ts +8 -0
- package/templates/blank/apps/api/tsconfig.json +5 -0
- package/templates/blank/apps/web/index.html +13 -0
- package/templates/blank/apps/web/package.json +22 -0
- package/templates/blank/apps/web/src/app/app.tsx +44 -0
- package/templates/blank/apps/web/src/app/styles/global.css +516 -0
- package/templates/blank/apps/web/src/app/workspace-layout.tsx +70 -0
- package/templates/blank/apps/web/src/main.tsx +13 -0
- package/templates/blank/apps/web/src/modules/auth/index.ts +1 -0
- package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +87 -0
- package/templates/blank/apps/web/src/modules/workspace/index.ts +1 -0
- package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +45 -0
- package/templates/blank/apps/web/src/shared/lib/error-message.ts +11 -0
- package/templates/blank/apps/web/src/shared/ui/brand.tsx +11 -0
- package/templates/blank/apps/web/tsconfig.json +11 -0
- package/templates/blank/apps/web/vite.config.ts +19 -0
- package/templates/blank/cage.config.json +14 -0
- package/templates/blank/db/migrations/0001_init.sql +63 -0
- package/templates/blank/docs/ai/README.md +77 -0
- package/templates/blank/docs/ai/architecture.md +122 -0
- package/templates/blank/docs/ai/ontology-context.md +117 -0
- package/templates/blank/docs/ai/primitives.md +249 -0
- package/templates/blank/docs/ai/project-structure.md +123 -0
- package/templates/blank/docs/ai/purchase-example.md +97 -0
- package/templates/blank/docs/ai/recipes.md +81 -0
- package/templates/blank/docs/ai/relations.md +160 -0
- package/templates/blank/docs/ai/transfers.md +92 -0
- package/templates/blank/docs/ai/troubleshooting.md +60 -0
- package/templates/blank/docs/ai/workflow.md +139 -0
- package/templates/blank/docs/errors/CAGE-APPR-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-005.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-006.md +47 -0
- package/templates/blank/docs/errors/CAGE-APPR-007.md +50 -0
- package/templates/blank/docs/errors/CAGE-APPR-010.md +48 -0
- package/templates/blank/docs/errors/CAGE-AUTH-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-BUDGET-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-BUDGET-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-BUDGET-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-CMD-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-CMD-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-005.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-006.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-007.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-008.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-009.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-010.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-011.md +47 -0
- package/templates/blank/docs/errors/CAGE-CONN-012.md +47 -0
- package/templates/blank/docs/errors/CAGE-CREATE-001.md +52 -0
- package/templates/blank/docs/errors/CAGE-DECL-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-DECL-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-DECL-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-DECL-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-DEP-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-DEP-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-DEP-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-DEP-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-DEP-005.md +47 -0
- package/templates/blank/docs/errors/CAGE-DLQ-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-ENV-001.md +52 -0
- package/templates/blank/docs/errors/CAGE-EVENT-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-EVENT-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-FIELD-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-FIELD-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-FIELD-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-FIELD-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-GEN-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-GEN-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-GRANT-001.md +49 -0
- package/templates/blank/docs/errors/CAGE-GRANT-002.md +48 -0
- package/templates/blank/docs/errors/CAGE-GRANT-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-IMPACT-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-INIT-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-INIT-002.md +49 -0
- package/templates/blank/docs/errors/CAGE-INIT-003.md +48 -0
- package/templates/blank/docs/errors/CAGE-INIT-004.md +48 -0
- package/templates/blank/docs/errors/CAGE-JOB-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-JOB-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-JOB-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-LINT-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-MIG-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-MIG-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-MIG-003.md +5 -0
- package/templates/blank/docs/errors/CAGE-MIG-004.md +5 -0
- package/templates/blank/docs/errors/CAGE-MIG-005.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-005.md +47 -0
- package/templates/blank/docs/errors/CAGE-NAME-006.md +47 -0
- package/templates/blank/docs/errors/CAGE-ORG-001.md +49 -0
- package/templates/blank/docs/errors/CAGE-PAIR-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-QUERY-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-QUERY-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-QUERY-003.md +49 -0
- package/templates/blank/docs/errors/CAGE-REACT-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-REACT-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-READS-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-REG-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-REG-002.md +48 -0
- package/templates/blank/docs/errors/CAGE-REG-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-REL-001.md +64 -0
- package/templates/blank/docs/errors/CAGE-ROUTE-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-SCOPE-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-SCOPE-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-SECRET-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-SECRET-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-SENS-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-SQL-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-SQL-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-STATE-001.md +49 -0
- package/templates/blank/docs/errors/CAGE-STATE-002.md +47 -0
- package/templates/blank/docs/errors/CAGE-STATE-003.md +47 -0
- package/templates/blank/docs/errors/CAGE-STATE-004.md +47 -0
- package/templates/blank/docs/errors/CAGE-STATE-005.md +48 -0
- package/templates/blank/docs/errors/CAGE-STATE-010.md +48 -0
- package/templates/blank/docs/errors/CAGE-STATE-011.md +48 -0
- package/templates/blank/docs/errors/CAGE-STRUCT-001.md +51 -0
- package/templates/blank/docs/errors/CAGE-STRUCT-002.md +51 -0
- package/templates/blank/docs/errors/CAGE-SYNC-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-TEST-001.md +47 -0
- package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +48 -0
- package/templates/blank/docs/errors/README.md +307 -0
- package/templates/blank/docs/errors/runtime.md +50 -0
- package/templates/blank/docs/examples/purchase-admin/README.md +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +10 -0
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +14 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +18 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +663 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +70 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +13 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +20 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +2 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +54 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +1 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +59 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +1 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +74 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.tsx +60 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +2 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +210 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/hooks/use-command.ts +29 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +15 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +13 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +28 -0
- package/templates/blank/docs/examples/purchase-admin/cage.config.json +114 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +74 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +57 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +52 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +72 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +85 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +89 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +81 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +17 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +6 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +36 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +2 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +43 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +18 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +6 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +13 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +137 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +122 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +10 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +24 -0
- package/templates/blank/package.json +22 -0
- package/templates/blank/packages/contracts/package.json +16 -0
- package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +74 -0
- package/templates/blank/packages/contracts/src/aggregates/role/index.ts +85 -0
- package/templates/blank/packages/contracts/src/aggregates/user/index.ts +89 -0
- package/templates/blank/packages/contracts/src/index.ts +55 -0
- package/templates/blank/packages/contracts/src/queries/index.ts +13 -0
- package/templates/blank/packages/contracts/tsconfig.json +5 -0
- package/templates/blank/packages/domain/package.json +23 -0
- package/templates/blank/packages/domain/src/index.ts +4 -0
- package/templates/blank/packages/domain/tsconfig.json +5 -0
- package/templates/blank/pnpm-workspace.yaml +10 -0
- package/templates/blank/renovate.json +5 -0
- package/templates/blank/tsconfig.base.json +8 -0
- package/dist/database.d.ts +0 -5
- package/dist/database.js +0 -70
- package/dist/database.js.map +0 -1
- package/managed/errors/CAGE-APPR-001.md +0 -32
- package/managed/errors/CAGE-APPR-002.md +0 -32
- package/managed/errors/CAGE-APPR-003.md +0 -32
- package/managed/errors/CAGE-APPR-004.md +0 -32
- package/managed/errors/CAGE-APPR-005.md +0 -32
- package/managed/errors/CAGE-APPR-006.md +0 -32
- package/managed/errors/CAGE-APPR-007.md +0 -32
- package/managed/errors/CAGE-APPR-010.md +0 -32
- package/managed/errors/CAGE-AUTH-001.md +0 -32
- package/managed/errors/CAGE-BUDGET-001.md +0 -32
- package/managed/errors/CAGE-BUDGET-002.md +0 -32
- package/managed/errors/CAGE-BUDGET-003.md +0 -32
- package/managed/errors/CAGE-CMD-002.md +0 -32
- package/managed/errors/CAGE-CMD-003.md +0 -34
- package/managed/errors/CAGE-CONN-001.md +0 -32
- package/managed/errors/CAGE-CONN-002.md +0 -32
- package/managed/errors/CAGE-CONN-003.md +0 -32
- package/managed/errors/CAGE-CONN-004.md +0 -32
- package/managed/errors/CAGE-CONN-005.md +0 -32
- package/managed/errors/CAGE-CONN-006.md +0 -32
- package/managed/errors/CAGE-CONN-007.md +0 -32
- package/managed/errors/CAGE-CONN-008.md +0 -32
- package/managed/errors/CAGE-CONN-009.md +0 -32
- package/managed/errors/CAGE-CONN-010.md +0 -32
- package/managed/errors/CAGE-CONN-011.md +0 -32
- package/managed/errors/CAGE-CONN-012.md +0 -32
- package/managed/errors/CAGE-CREATE-001.md +0 -32
- package/managed/errors/CAGE-DECL-001.md +0 -34
- package/managed/errors/CAGE-DECL-002.md +0 -34
- package/managed/errors/CAGE-DECL-003.md +0 -34
- package/managed/errors/CAGE-DECL-004.md +0 -34
- package/managed/errors/CAGE-DEP-001.md +0 -34
- package/managed/errors/CAGE-DEP-002.md +0 -34
- package/managed/errors/CAGE-DEP-003.md +0 -34
- package/managed/errors/CAGE-DEP-004.md +0 -34
- package/managed/errors/CAGE-DEP-005.md +0 -34
- package/managed/errors/CAGE-DLQ-001.md +0 -32
- package/managed/errors/CAGE-ENV-001.md +0 -32
- package/managed/errors/CAGE-EVENT-001.md +0 -32
- package/managed/errors/CAGE-EVENT-002.md +0 -32
- package/managed/errors/CAGE-FIELD-001.md +0 -32
- package/managed/errors/CAGE-FIELD-002.md +0 -32
- package/managed/errors/CAGE-FIELD-003.md +0 -32
- package/managed/errors/CAGE-FIELD-004.md +0 -32
- package/managed/errors/CAGE-GEN-001.md +0 -33
- package/managed/errors/CAGE-GEN-002.md +0 -33
- package/managed/errors/CAGE-GRANT-001.md +0 -32
- package/managed/errors/CAGE-GRANT-002.md +0 -32
- package/managed/errors/CAGE-GRANT-003.md +0 -32
- package/managed/errors/CAGE-IMPACT-001.md +0 -32
- package/managed/errors/CAGE-JOB-001.md +0 -32
- package/managed/errors/CAGE-JOB-002.md +0 -32
- package/managed/errors/CAGE-JOB-003.md +0 -32
- package/managed/errors/CAGE-LINT-001.md +0 -32
- package/managed/errors/CAGE-MIG-001.md +0 -32
- package/managed/errors/CAGE-MIG-002.md +0 -32
- package/managed/errors/CAGE-MIG-003.md +0 -32
- package/managed/errors/CAGE-MIG-004.md +0 -32
- package/managed/errors/CAGE-MIG-005.md +0 -32
- package/managed/errors/CAGE-NAME-001.md +0 -32
- package/managed/errors/CAGE-NAME-002.md +0 -32
- package/managed/errors/CAGE-NAME-003.md +0 -32
- package/managed/errors/CAGE-NAME-004.md +0 -32
- package/managed/errors/CAGE-NAME-005.md +0 -32
- package/managed/errors/CAGE-NAME-006.md +0 -32
- package/managed/errors/CAGE-ORG-001.md +0 -32
- package/managed/errors/CAGE-PAIR-002.md +0 -33
- package/managed/errors/CAGE-QUERY-001.md +0 -32
- package/managed/errors/CAGE-QUERY-002.md +0 -32
- package/managed/errors/CAGE-QUERY-003.md +0 -32
- package/managed/errors/CAGE-REACT-001.md +0 -32
- package/managed/errors/CAGE-REACT-002.md +0 -32
- package/managed/errors/CAGE-READS-001.md +0 -32
- package/managed/errors/CAGE-REG-001.md +0 -32
- package/managed/errors/CAGE-REG-002.md +0 -32
- package/managed/errors/CAGE-REG-003.md +0 -32
- package/managed/errors/CAGE-ROUTE-001.md +0 -32
- package/managed/errors/CAGE-SCOPE-001.md +0 -32
- package/managed/errors/CAGE-SCOPE-002.md +0 -32
- package/managed/errors/CAGE-SECRET-001.md +0 -32
- package/managed/errors/CAGE-SECRET-002.md +0 -32
- package/managed/errors/CAGE-SENS-001.md +0 -32
- package/managed/errors/CAGE-SQL-001.md +0 -32
- package/managed/errors/CAGE-SQL-002.md +0 -32
- package/managed/errors/CAGE-STATE-001.md +0 -32
- package/managed/errors/CAGE-STATE-002.md +0 -32
- package/managed/errors/CAGE-STATE-003.md +0 -32
- package/managed/errors/CAGE-STATE-004.md +0 -32
- package/managed/errors/CAGE-STATE-005.md +0 -32
- package/managed/errors/CAGE-STATE-010.md +0 -32
- package/managed/errors/CAGE-STATE-011.md +0 -32
- package/managed/errors/CAGE-SYNC-001.md +0 -35
- package/managed/errors/CAGE-TEST-001.md +0 -33
- package/managed/errors/CAGE-UNSAFE-001.md +0 -32
- package/managed/errors/CAGE-UPGRADE-001.md +0 -32
- package/managed/errors/README.md +0 -99
- package/templates/app/compose.yaml +0 -39
- /package/templates/app/apps/web/src/{style.css → app/styles/global.css} +0 -0
- /package/templates/app/packages/contracts/src/{queries.ts → queries/index.ts} +0 -0
- /package/templates/app/packages/domain/src/{inventory.ts → modules/inventory/inventory.ts} +0 -0
- /package/templates/app/packages/domain/src/{approvals.ts → modules/purchase/approvals.ts} +0 -0
- /package/templates/app/packages/domain/src/{jobs.ts → modules/purchase/jobs.ts} +0 -0
- /package/templates/app/packages/domain/src/{queries.ts → modules/purchase/queries.ts} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// 生成物:由 cage gen 从 domain 声明生成,不要手改。
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { client, useCageList, useCageQuery, type TransferTask } from '@yss123/cage-client';
|
|
6
|
+
|
|
7
|
+
/** 用户:读侧快照(敏感字段是按权限掩码后的值) */
|
|
8
|
+
export const UserSchema = z.object({
|
|
9
|
+
id: z.string().uuid(),
|
|
10
|
+
username: z.string(),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
deptId: z.string().uuid(),
|
|
13
|
+
roleIds: z.array(z.string().uuid()),
|
|
14
|
+
phone: z.string().nullable().optional(),
|
|
15
|
+
email: z.string().nullable().optional(),
|
|
16
|
+
ssoSubject: z.string().nullable().optional(),
|
|
17
|
+
status: z.enum(["active", "disabled"]),
|
|
18
|
+
version: z.number().int(),
|
|
19
|
+
createdAt: z.string(),
|
|
20
|
+
updatedAt: z.string(),
|
|
21
|
+
});
|
|
22
|
+
export type User = z.infer<typeof UserSchema>;
|
|
23
|
+
export type UserStatus = User['status'];
|
|
24
|
+
export const UserStates = ['active', 'disabled'] as const;
|
|
25
|
+
|
|
26
|
+
/** 命令输入:和后端命令的输入校验完全一致 */
|
|
27
|
+
export const UserInputs = {
|
|
28
|
+
assignRoles: z.object({ id: z.string().uuid(), roleIds: z.array(z.string().uuid()).max(50) }),
|
|
29
|
+
create: z.object({ username: z.string().min(2).max(64).regex(new RegExp("^[A-Za-z0-9_.@-]+$")), name: z.string().min(1).max(100), deptId: z.string().uuid(), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional(), ssoSubject: z.string().max(200).nullable().optional() }),
|
|
30
|
+
disable: z.object({ id: z.string().uuid() }),
|
|
31
|
+
enable: z.object({ id: z.string().uuid() }),
|
|
32
|
+
setPassword: z.object({ id: z.string().uuid(), password: z.string().min(8).max(200) }),
|
|
33
|
+
update: z.object({ id: z.string().uuid(), name: z.string().min(1).max(100).optional(), deptId: z.string().uuid().optional(), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional() }),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** User.assignRoles 可能返回的错误码 */
|
|
37
|
+
export type UserAssignRolesError = 'CONFLICT' | 'CONSTRAINT_VIOLATED' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT' | 'INVALID_TRANSITION' | 'NOT_FOUND';
|
|
38
|
+
/** User.create 可能返回的错误码 */
|
|
39
|
+
export type UserCreateError = 'CONFLICT' | 'CONSTRAINT_VIOLATED' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT';
|
|
40
|
+
/** User.disable 可能返回的错误码 */
|
|
41
|
+
export type UserDisableError = 'CONFLICT' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT' | 'INVALID_TRANSITION' | 'NOT_FOUND';
|
|
42
|
+
/** User.enable 可能返回的错误码 */
|
|
43
|
+
export type UserEnableError = 'CONFLICT' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT' | 'INVALID_TRANSITION' | 'NOT_FOUND';
|
|
44
|
+
/** User.setPassword 可能返回的错误码 */
|
|
45
|
+
export type UserSetPasswordError = 'CONFLICT' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT' | 'INVALID_TRANSITION' | 'NOT_FOUND';
|
|
46
|
+
/** User.update 可能返回的错误码 */
|
|
47
|
+
export type UserUpdateError = 'CONFLICT' | 'DOMAIN_ERROR' | 'FORBIDDEN' | 'INVALID_INPUT' | 'INVALID_TRANSITION' | 'NOT_FOUND';
|
|
48
|
+
|
|
49
|
+
export type UserSortKey = 'createdAt' | 'updatedAt' | 'username' | 'name' | 'deptId' | 'phone' | 'email' | 'ssoSubject';
|
|
50
|
+
export interface UserListParams {
|
|
51
|
+
page?: number;
|
|
52
|
+
pageSize?: number;
|
|
53
|
+
/** 排序:字段名,前面加 - 表示倒序 */
|
|
54
|
+
sort?: UserSortKey | `-${UserSortKey}`;
|
|
55
|
+
/** 可以逗号分隔多个状态 */
|
|
56
|
+
status?: string;
|
|
57
|
+
createdAfter?: string;
|
|
58
|
+
createdBefore?: string;
|
|
59
|
+
username?: string | number | boolean;
|
|
60
|
+
deptId?: string | number | boolean;
|
|
61
|
+
ssoSubject?: string | number | boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** 调用方法:每个命令一个;client 自动生成并附带幂等键和 CSRF 令牌 */
|
|
65
|
+
export const user = {
|
|
66
|
+
/** 设置用户的角色(不能分配包含自己没有的能力的角色) */
|
|
67
|
+
assignRoles: (id: string, input: Omit<z.input<typeof UserInputs.assignRoles>, 'id'>, expectedVersion?: number) => client.post<User, UserAssignRolesError>(`/api/user/${encodeURIComponent(id)}/assign-roles`, { ...input, expectedVersion }),
|
|
68
|
+
/** 新建用户(默认没有任何角色) */
|
|
69
|
+
create: (input: z.input<typeof UserInputs.create>) => client.post<User, UserCreateError>('/api/user/create', input),
|
|
70
|
+
/** 停用用户 */
|
|
71
|
+
disable: (id: string, expectedVersion?: number) => client.post<User, UserDisableError>(`/api/user/${encodeURIComponent(id)}/disable`, { expectedVersion }),
|
|
72
|
+
/** 启用用户 */
|
|
73
|
+
enable: (id: string, expectedVersion?: number) => client.post<User, UserEnableError>(`/api/user/${encodeURIComponent(id)}/enable`, { expectedVersion }),
|
|
74
|
+
/** 重置密码 */
|
|
75
|
+
setPassword: (id: string, input: Omit<z.input<typeof UserInputs.setPassword>, 'id'>, expectedVersion?: number) => client.post<User, UserSetPasswordError>(`/api/user/${encodeURIComponent(id)}/set-password`, { ...input, expectedVersion }),
|
|
76
|
+
/** 修改用户信息 */
|
|
77
|
+
update: (id: string, input: Omit<z.input<typeof UserInputs.update>, 'id'>, expectedVersion?: number) => client.post<User, UserUpdateError>(`/api/user/${encodeURIComponent(id)}/update`, { ...input, expectedVersion }),
|
|
78
|
+
/** 异步导出 CSV:返回任务,使用 client.transfer(id) 查状态,完成后下载。需要 User.export 能力。 */
|
|
79
|
+
export: (params: UserListParams = {}, options: { idempotencyKey?: string } = {}) => client.post<TransferTask, 'CONFLICT'>('/api/user/export', params, options),
|
|
80
|
+
get: (id: string) => client.get<User>(`/api/user/${encodeURIComponent(id)}`),
|
|
81
|
+
list: (params: UserListParams = {}) => client.get<{ items: User[]; total: number; page: number; pageSize: number }>('/api/user', params as Record<string, unknown>),
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** 详情查询 hook:响应也用 schema 校验;范围外返回 NOT_FOUND */
|
|
85
|
+
export const useUser = (id: string) => useCageQuery(['user', id], `/api/user/${encodeURIComponent(id)}`, UserSchema, { enabled: !!id });
|
|
86
|
+
/** 列表查询 hook:走读侧账号与安全视图 */
|
|
87
|
+
export const useUserList = (params: UserListParams = {}) => useCageList(['user'], '/api/user', params as Record<string, unknown>, UserSchema);
|
|
88
|
+
/** 查询缓存键前缀:命令成功后让它失效 */
|
|
89
|
+
export const userKeys = { all: ['user'] as const, one: (id: string) => ['user', id] as const };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// 生成物:由 cage gen 从 domain 声明生成,不要手改。
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export * from './aggregates/dept';
|
|
5
|
+
export * from './aggregates/role';
|
|
6
|
+
export * from './aggregates/user';
|
|
7
|
+
export * from './queries';
|
|
8
|
+
import { can as baseCan, useCan as baseUseCan } from '@yss123/cage-client';
|
|
9
|
+
import { DeptInputs } from './aggregates/dept';
|
|
10
|
+
import { RoleInputs } from './aggregates/role';
|
|
11
|
+
import { UserInputs } from './aggregates/user';
|
|
12
|
+
export { client, configureClient, loadMe, currentUser, CageQueryError, useTransfer, type CageResult, type CommonError, type TransferTask, type ImportReport } from '@yss123/cage-client';
|
|
13
|
+
|
|
14
|
+
/** 能力目录(由代码派生):写错能力点名会编译失败 */
|
|
15
|
+
export const capabilities = [
|
|
16
|
+
'Dept.archive',
|
|
17
|
+
'Dept.create',
|
|
18
|
+
'Dept.export',
|
|
19
|
+
'Dept.read',
|
|
20
|
+
'Dept.update',
|
|
21
|
+
'Role.archive',
|
|
22
|
+
'Role.create',
|
|
23
|
+
'Role.export',
|
|
24
|
+
'Role.grantCapability',
|
|
25
|
+
'Role.read',
|
|
26
|
+
'Role.rename',
|
|
27
|
+
'Role.revokeCapability',
|
|
28
|
+
'Role.setScope',
|
|
29
|
+
'Sys.audit.read',
|
|
30
|
+
'Sys.ops.manage',
|
|
31
|
+
'Sys.ops.read',
|
|
32
|
+
'User.assignRoles',
|
|
33
|
+
'User.create',
|
|
34
|
+
'User.disable',
|
|
35
|
+
'User.enable',
|
|
36
|
+
'User.export',
|
|
37
|
+
'User.read',
|
|
38
|
+
'User.setPassword',
|
|
39
|
+
'User.unmask.email',
|
|
40
|
+
'User.unmask.name',
|
|
41
|
+
'User.unmask.phone',
|
|
42
|
+
'User.update',
|
|
43
|
+
] as const;
|
|
44
|
+
export type Capability = (typeof capabilities)[number];
|
|
45
|
+
|
|
46
|
+
/** 当前用户有没有某个能力点。只影响界面显示:绕过前端直接调接口,内核一样会拒绝 */
|
|
47
|
+
export const can = (capability: Capability): boolean => baseCan(capability);
|
|
48
|
+
export const useCan = (capability: Capability): boolean => baseUseCan(capability);
|
|
49
|
+
|
|
50
|
+
/** 各聚合的命令输入 schema:按聚合名、命令名访问,可直接供表单库校验 */
|
|
51
|
+
export const schemas = {
|
|
52
|
+
Dept: DeptInputs,
|
|
53
|
+
Role: RoleInputs,
|
|
54
|
+
User: UserInputs,
|
|
55
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@app/domain",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"development": "./src/index.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc -p tsconfig.json",
|
|
14
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@yss123/cage-kernel": "0.2.0",
|
|
18
|
+
"@yss123/cage-admin": "0.2.0",
|
|
19
|
+
"@yss123/cage-approval": "0.2.0",
|
|
20
|
+
"@yss123/cage-connectors": "0.2.0",
|
|
21
|
+
"zod": "^4.1.5"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023", "lib": ["ES2023", "DOM"],
|
|
4
|
+
"module": "NodeNext", "moduleResolution": "NodeNext", "strict": true,
|
|
5
|
+
"esModuleInterop": true, "skipLibCheck": true, "declaration": true,
|
|
6
|
+
"sourceMap": true, "resolveJsonModule": true, "isolatedModules": true
|
|
7
|
+
}
|
|
8
|
+
}
|
package/dist/database.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type CageConfig } from './config.js';
|
|
2
|
-
/** 首次为项目生成独立凭证;已有配置保持原样,避免与持久卷中的角色密码失配。 */
|
|
3
|
-
export declare function setupDatabase(cfg: CageConfig): boolean;
|
|
4
|
-
/** Docker 仅负责基础设施,建库、账号权限和迁移仍复用框架现有 migrate 流程。 */
|
|
5
|
-
export declare function database(cfg: CageConfig, action?: string): Promise<number>;
|
package/dist/database.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// 开发数据库的环境配置与 Docker 生命周期属于框架工具链。
|
|
2
|
-
// 业务仓库只保留 compose.yaml/.env 等部署参数,不维护连接、建库或凭证生成脚本。
|
|
3
|
-
import { existsSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { randomBytes } from 'node:crypto';
|
|
5
|
-
import { spawn } from 'node:child_process';
|
|
6
|
-
import { abs } from './config.js';
|
|
7
|
-
import { migrate } from './migrate.js';
|
|
8
|
-
/** 首次为项目生成独立凭证;已有配置保持原样,避免与持久卷中的角色密码失配。 */
|
|
9
|
-
export function setupDatabase(cfg) {
|
|
10
|
-
const target = abs(cfg, '.env');
|
|
11
|
-
if (existsSync(target))
|
|
12
|
-
return false;
|
|
13
|
-
const secret = () => randomBytes(24).toString('hex');
|
|
14
|
-
const passwords = { postgres: secret(), test: secret(), app: secret(), read: secret(), migrate: secret() };
|
|
15
|
-
const port = cfg.devDbPort;
|
|
16
|
-
const url = (user, password, port, database) => `postgresql://${user}:${password}@127.0.0.1:${port}/${database}`;
|
|
17
|
-
const content = [
|
|
18
|
-
'# 仅供本地开发,由 cage db setup 生成;不要提交或复制进镜像。',
|
|
19
|
-
`CAGE_POSTGRES_PORT=${port}`,
|
|
20
|
-
`CAGE_TEST_POSTGRES_PORT=${port + 1}`,
|
|
21
|
-
`POSTGRES_PASSWORD=${passwords.postgres}`,
|
|
22
|
-
`CAGE_TEST_POSTGRES_PASSWORD=${passwords.test}`,
|
|
23
|
-
`CAGE_SUPER_DATABASE_URL=${url('postgres', passwords.postgres, port, 'postgres')}`,
|
|
24
|
-
`CAGE_APP_DATABASE_URL=${url('cage_app', passwords.app, port, 'cage_dev')}`,
|
|
25
|
-
`CAGE_READ_DATABASE_URL=${url('cage_read', passwords.read, port, 'cage_dev')}`,
|
|
26
|
-
`CAGE_MIGRATE_DATABASE_URL=${url('cage_migrate', passwords.migrate, port, 'cage_dev')}`,
|
|
27
|
-
'# 测试会初始化集群角色,必须使用独立的可丢弃测试集群。',
|
|
28
|
-
`CAGE_TEST_DATABASE_URL=${url('postgres', passwords.test, port + 1, 'postgres')}`,
|
|
29
|
-
`CAGE_COOKIE_SECRET=${secret()}`,
|
|
30
|
-
'CAGE_STAGE=fake',
|
|
31
|
-
'CAGE_WEB_PORT=5173',
|
|
32
|
-
'PORT=3000',
|
|
33
|
-
'HOST=127.0.0.1',
|
|
34
|
-
'',
|
|
35
|
-
].join('\n');
|
|
36
|
-
writeFileSync(target, content, { mode: 0o600, flag: 'wx' });
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
/** Docker 仅负责基础设施,建库、账号权限和迁移仍复用框架现有 migrate 流程。 */
|
|
40
|
-
export async function database(cfg, action) {
|
|
41
|
-
if (action === 'setup') {
|
|
42
|
-
console.log(setupDatabase(cfg)
|
|
43
|
-
? '已生成 .env(不输出密码)。随后运行 cage db up、cage db init、cage dev。'
|
|
44
|
-
: '已有 .env,保留当前数据库配置。');
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
if (action === 'init') {
|
|
48
|
-
await migrate(cfg, true);
|
|
49
|
-
return 0;
|
|
50
|
-
}
|
|
51
|
-
// 参数列表由命令固定,不接受任意 shell 文本;down 不删除持久卷。
|
|
52
|
-
const actions = {
|
|
53
|
-
up: ['up', '-d', '--wait'],
|
|
54
|
-
down: ['down'],
|
|
55
|
-
status: ['ps'],
|
|
56
|
-
};
|
|
57
|
-
if (!action || !actions[action])
|
|
58
|
-
throw new Error('用法:cage db setup|up|init|status|down');
|
|
59
|
-
const child = spawn('docker', ['compose', '--profile', 'test', ...actions[action]], {
|
|
60
|
-
cwd: cfg.root,
|
|
61
|
-
env: process.env,
|
|
62
|
-
stdio: 'inherit',
|
|
63
|
-
windowsHide: true,
|
|
64
|
-
});
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
child.once('error', reject);
|
|
67
|
-
child.once('exit', (code) => resolve(code ?? 1));
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=database.js.map
|
package/dist/database.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-001
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/kernel/src/primitives/flow.ts:134](../../packages/kernel/src/primitives/flow.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
for (const f of def.routable) {
|
|
11
|
-
if (!(f in agg.fields)) throw declError('CAGE-APPR-001', `可路由字段 ${agg.name}.${f} 不存在`);
|
|
12
|
-
}
|
|
13
|
-
for (const c of [def.onApproved, def.onRejected]) {
|
|
14
|
-
if (c.agg !== agg) throw declError('CAGE-APPR-002', `审批结论命令必须属于 ${agg.name}`);
|
|
15
|
-
if (!c.invokedBy.includes('process')) {
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-002
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/kernel/src/primitives/flow.ts:137](../../packages/kernel/src/primitives/flow.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
for (const c of [def.onApproved, def.onRejected]) {
|
|
11
|
-
if (c.agg !== agg) throw declError('CAGE-APPR-002', `审批结论命令必须属于 ${agg.name}`);
|
|
12
|
-
if (!c.invokedBy.includes('process')) {
|
|
13
|
-
throw declError('CAGE-APPR-003', `审批结论命令必须声明 invokedBy: 'process'`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-003
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/kernel/src/primitives/flow.ts:139](../../packages/kernel/src/primitives/flow.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
if (!c.invokedBy.includes('process')) {
|
|
11
|
-
throw declError('CAGE-APPR-003', `审批结论命令必须声明 invokedBy: 'process'`);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return Object.freeze({
|
|
15
|
-
[APPROVAL]: true as const,
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-004
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/approval/src/bridge.ts:8](../../packages/approval/src/bridge.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
const binding = k.registry.approvalByProcess(r.process);
|
|
11
|
-
if (!binding) throw new Error(`[CAGE-APPR-004] 没有流程 ${r.process} 的审批绑定`);
|
|
12
|
-
const cmd = r.outcome === 'approved' ? binding.a.onApproved : binding.a.onRejected;
|
|
13
|
-
const ctx = k.processCtx({
|
|
14
|
-
process: r.process,
|
|
15
|
-
tenantId: r.tenantId,
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-005
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/approval/src/route.ts:96](../../packages/approval/src/route.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
export function route(process: string, nodes: RouteNode[]): Route {
|
|
11
|
-
if (!/^[a-z][a-z0-9-]*$/.test(process)) throw declError('CAGE-APPR-005', `流程名 ${process} 必须是小写短横线`);
|
|
12
|
-
if (nodes.length === 0) throw declError('CAGE-APPR-006', `流程 ${process} 至少需要一个步骤`);
|
|
13
|
-
const fields = new Set<string>();
|
|
14
|
-
for (const n of nodes) {
|
|
15
|
-
const steps = n.kind === 'step' ? [n] : n.steps;
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-006
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/approval/src/route.ts:97](../../packages/approval/src/route.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
if (!/^[a-z][a-z0-9-]*$/.test(process)) throw declError('CAGE-APPR-005', `流程名 ${process} 必须是小写短横线`);
|
|
11
|
-
if (nodes.length === 0) throw declError('CAGE-APPR-006', `流程 ${process} 至少需要一个步骤`);
|
|
12
|
-
const fields = new Set<string>();
|
|
13
|
-
for (const n of nodes) {
|
|
14
|
-
const steps = n.kind === 'step' ? [n] : n.steps;
|
|
15
|
-
if (n.kind === 'when') fields.add(n.cond.field);
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-007
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/approval/src/engine.ts:64](../../packages/approval/src/engine.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
if (who.length === 0) {
|
|
11
|
-
throw new Error(`[CAGE-APPR-007] 流程 ${this.route.process} 第 ${index + 1} 步「${s.title}」找不到审批人,请在 /admin 配置部门负责人或角色`);
|
|
12
|
-
}
|
|
13
|
-
for (const assignee of new Set(who)) {
|
|
14
|
-
await tx.insertInto('flow.approval_task').values({ instance_id: instanceId, tenant_id: tenantId, step: index, title: s.title, assignee }).execute();
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-APPR-010
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/cli/src/rules.ts:140](../../packages/cli/src/rules.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
|
|
11
|
-
/** CAGE-APPR-010:invokedBy 为 process 的命令必须有审批绑定或反应调用它,否则没有人能调用 */
|
|
12
|
-
export function checkProcessCommands(g: Ontology): Finding[] {
|
|
13
|
-
const { into } = index(g);
|
|
14
|
-
const findings: Finding[] = [];
|
|
15
|
-
for (const c of g.nodes.filter((n) => n.kind === 'command')) {
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对流程绑定、可路由字段、结论命令及审批人配置。结论只能调用所属聚合的 process 命令。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
onApproved: approve // approve 声明 invokedBy: 'process'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
onApproved: otherAggregateCommand // 结论落到了错误聚合
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-AUTH-001
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/http/src/oidc.ts:20](../../packages/http/src/oidc.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
(disco ??= fetch(new URL('.well-known/openid-configuration', o.issuer.endsWith('/') ? o.issuer : `${o.issuer}/`)).then(async (r) => {
|
|
11
|
-
if (!r.ok) throw new Error(`[CAGE-AUTH-001] OIDC 发现文档获取失败:${r.status}`);
|
|
12
|
-
return (await r.json()) as Discovery;
|
|
13
|
-
}));
|
|
14
|
-
const secure = opts.cookieSecure ?? process.env.NODE_ENV === 'production';
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
核对 OIDC 发现文档、issuer 和客户端配置,在部署环境配置所需变量。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
OIDC_ISSUER + OIDC_CLIENT_ID + OIDC_REDIRECT_URI
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
// issuer 不匹配或缺少客户端配置
|
|
32
|
-
```
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# CAGE-BUDGET-001
|
|
2
|
-
|
|
3
|
-
## 什么时候出现
|
|
4
|
-
|
|
5
|
-
命中以下实现中的检查时触发。终端会附具体声明位置、原因和修复方法。
|
|
6
|
-
|
|
7
|
-
来源:[packages/cli/src/budget.ts:45](../../packages/cli/src/budget.ts)
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
findings.push({
|
|
11
|
-
code: 'CAGE-BUDGET-001',
|
|
12
|
-
reason: `内核 ${lines} 行,超过 5000 行预算`,
|
|
13
|
-
fix: '拆出扩展职责,或提交架构评审调整预算',
|
|
14
|
-
});
|
|
15
|
-
if (primitives !== null && primitives > 16)
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 怎么修
|
|
19
|
-
|
|
20
|
-
减少内核职责,移除不必要的 unsafe;预算调整及基线更新必须经过评审。
|
|
21
|
-
|
|
22
|
-
## 正例
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
node packages/cli/bin/cage.js budget
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## 反例
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
// 未评审就增加公共原语或 unsafe 数量
|
|
32
|
-
```
|