@yss123/cage-cli 0.2.0 → 0.3.1
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 +47 -3
- package/bin/cage.js +5 -0
- package/bin/create-cage-app.js +5 -0
- package/dist/analyze.d.ts +16 -0
- package/dist/analyze.js +18 -2
- package/dist/analyze.js.map +1 -1
- package/dist/approval-tree.d.ts +88 -0
- package/dist/approval-tree.js +18 -0
- package/dist/approval-tree.js.map +1 -0
- package/dist/baseline.d.ts +8 -0
- package/dist/baseline.js +13 -0
- package/dist/baseline.js.map +1 -1
- package/dist/bootstrap.d.ts +20 -0
- package/dist/bootstrap.js +75 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/budget.d.ts +7 -0
- package/dist/budget.js +49 -5
- package/dist/budget.js.map +1 -1
- package/dist/capabilities.d.ts +38 -0
- package/dist/capabilities.js +148 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/config.d.ts +31 -2
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +14 -0
- package/dist/context.js +35 -2
- package/dist/context.js.map +1 -1
- package/dist/create-prompt.d.ts +7 -0
- package/dist/create-prompt.js +12 -0
- package/dist/create-prompt.js.map +1 -1
- package/dist/create.d.ts +21 -1
- package/dist/create.js +23 -1
- package/dist/create.js.map +1 -1
- package/dist/derive.d.ts +23 -0
- package/dist/derive.js +40 -0
- package/dist/derive.js.map +1 -1
- package/dist/dev.d.ts +6 -0
- package/dist/dev.js +11 -0
- package/dist/dev.js.map +1 -1
- package/dist/doctor.d.ts +98 -0
- package/dist/doctor.js +93 -0
- package/dist/doctor.js.map +1 -0
- package/dist/env.d.ts +6 -0
- package/dist/env.js +11 -0
- package/dist/env.js.map +1 -1
- package/dist/findings.d.ts +27 -0
- package/dist/findings.js +20 -0
- package/dist/findings.js.map +1 -1
- package/dist/gen/contracts.d.ts +28 -0
- package/dist/gen/contracts.js +52 -12
- package/dist/gen/contracts.js.map +1 -1
- package/dist/gen/index.d.ts +26 -0
- package/dist/gen/index.js +69 -1
- package/dist/gen/index.js.map +1 -1
- package/dist/gen/zod-code.d.ts +42 -0
- package/dist/gen/zod-code.js +178 -16
- package/dist/gen/zod-code.js.map +1 -1
- package/dist/graph-approvals.d.ts +70 -0
- package/dist/graph-approvals.js +93 -0
- package/dist/graph-approvals.js.map +1 -0
- package/dist/graph-business.d.ts +135 -0
- package/dist/graph-business.js +404 -0
- package/dist/graph-business.js.map +1 -0
- package/dist/graph-command.d.ts +17 -0
- package/dist/graph-command.js +21 -0
- package/dist/graph-command.js.map +1 -1
- package/dist/graph-model.d.ts +44 -0
- package/dist/graph-model.js +36 -3
- package/dist/graph-model.js.map +1 -1
- package/dist/graph-presentation.d.ts +16 -0
- package/dist/graph-presentation.js +10 -1
- package/dist/graph-presentation.js.map +1 -1
- package/dist/graph-query.d.ts +95 -0
- package/dist/graph-query.js +62 -0
- package/dist/graph-query.js.map +1 -1
- package/dist/graph-relations.d.ts +20 -0
- package/dist/graph-relations.js +42 -10
- package/dist/graph-relations.js.map +1 -1
- package/dist/graph-search.d.ts +35 -0
- package/dist/graph-search.js +36 -0
- package/dist/graph-search.js.map +1 -1
- package/dist/graph-snapshot.d.ts +26 -0
- package/dist/graph-snapshot.js +30 -1
- package/dist/graph-snapshot.js.map +1 -1
- package/dist/graph.d.ts +13 -2
- package/dist/graph.js +61 -4
- package/dist/graph.js.map +1 -1
- package/dist/impact.d.ts +50 -0
- package/dist/impact.js +62 -2
- package/dist/impact.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +12 -0
- package/dist/init.js +15 -0
- package/dist/init.js.map +1 -1
- package/dist/load.d.ts +10 -0
- package/dist/load.js +15 -0
- package/dist/load.js.map +1 -1
- package/dist/main.d.ts +6 -0
- package/dist/main.js +93 -5
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +12 -0
- package/dist/migrate.js +17 -0
- package/dist/migrate.js.map +1 -1
- package/dist/ontology.d.ts +67 -2
- package/dist/ontology.js +94 -4
- package/dist/ontology.js.map +1 -1
- package/dist/process-rules.d.ts +21 -0
- package/dist/process-rules.js +100 -0
- package/dist/process-rules.js.map +1 -0
- package/dist/process.d.ts +32 -0
- package/dist/process.js +32 -0
- package/dist/process.js.map +1 -1
- package/dist/project-structure.d.ts +5 -0
- package/dist/project-structure.js +10 -0
- package/dist/project-structure.js.map +1 -1
- package/dist/registration.d.ts +16 -0
- package/dist/registration.js +56 -0
- package/dist/registration.js.map +1 -0
- package/dist/rules.d.ts +52 -0
- package/dist/rules.js +58 -0
- package/dist/rules.js.map +1 -1
- package/dist/runtime-diagnostics.d.ts +27 -0
- package/dist/runtime-diagnostics.js +60 -0
- package/dist/runtime-diagnostics.js.map +1 -0
- package/dist/snapshots.d.ts +40 -0
- package/dist/snapshots.js +62 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/static-check.d.ts +33 -0
- package/dist/static-check.js +37 -1
- package/dist/static-check.js.map +1 -1
- package/dist/sync.d.ts +11 -0
- package/dist/sync.js +66 -9
- package/dist/sync.js.map +1 -1
- package/dist/upgrade.d.ts +16 -0
- package/dist/upgrade.js +21 -0
- package/dist/upgrade.js.map +1 -1
- package/dist/verify.d.ts +14 -0
- package/dist/verify.js +19 -0
- package/dist/verify.js.map +1 -1
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -1
- package/graph-ui/app.js +321 -27
- package/graph-ui/approval-flow.js +185 -0
- package/graph-ui/approval-parallel.js +110 -0
- package/graph-ui/approval-tree.js +17 -0
- package/graph-ui/business.css +1011 -0
- package/graph-ui/business.js +566 -0
- package/graph-ui/flowchart-interaction.js +177 -0
- package/graph-ui/flowchart.js +1059 -0
- package/graph-ui/graph-approvals.js +92 -0
- package/graph-ui/graph-business.js +403 -0
- package/graph-ui/graph-model.js +36 -3
- package/graph-ui/graph-relations.js +42 -10
- package/graph-ui/graph-search.js +36 -0
- package/graph-ui/index.html +26 -12
- package/graph-ui/model.js +28 -0
- package/graph-ui/relations.js +4 -0
- package/graph-ui/structure.js +44 -0
- package/graph-ui/style.css +12 -0
- package/package.json +6 -4
- package/templates/app/.dockerignore +2 -0
- package/templates/app/.env.example +10 -0
- package/templates/app/AGENTS.md +50 -10
- package/templates/app/README.md +9 -5
- package/templates/app/_gitignore +1 -0
- package/templates/app/apps/api/package.json +2 -2
- package/templates/app/apps/api/src/main.ts +5 -1
- package/templates/app/apps/api/src/worker.ts +3 -0
- package/templates/app/apps/web/index.html +1 -0
- package/templates/app/apps/web/package.json +7 -3
- package/templates/app/apps/web/src/app/app.tsx +122 -12
- package/templates/app/apps/web/src/app/styles/global.css +88 -8
- package/templates/app/apps/web/src/app/use-session.ts +43 -0
- package/templates/app/apps/web/src/app/workspace-layout.tsx +58 -19
- package/templates/app/apps/web/src/main.tsx +5 -0
- package/templates/app/apps/web/src/modules/approval/components/task-operation-dialog.tsx +61 -0
- package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +13 -5
- package/templates/app/apps/web/src/modules/approval/index.ts +4 -0
- package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +89 -38
- package/templates/app/apps/web/src/modules/approval/pages/approval-tasks.css +18 -0
- package/templates/app/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
- package/templates/app/apps/web/src/modules/inventory/index.ts +4 -0
- package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
- package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +67 -0
- package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
- package/templates/app/apps/web/src/modules/purchase/components/order-reviewers.tsx +38 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
- package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +32 -3
- package/templates/app/apps/web/src/modules/purchase/index.ts +5 -0
- package/templates/app/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-intelligence.css +17 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +156 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +54 -22
- package/templates/app/apps/web/src/modules/workspace/index.ts +5 -0
- package/templates/app/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
- package/templates/app/apps/web/src/shared/hooks/use-command.ts +13 -0
- package/templates/app/apps/web/src/shared/lib/error-message.ts +15 -1
- package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/app/apps/web/src/shared/ui/approval-member-picker.css +10 -0
- package/templates/app/apps/web/src/shared/ui/approval-member-picker.tsx +51 -0
- package/templates/app/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
- package/templates/app/apps/web/src/shared/ui/assistant-panel.css +134 -0
- package/templates/app/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
- package/templates/app/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
- package/templates/app/apps/web/src/shared/ui/attachment-upload.css +28 -0
- package/templates/app/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
- package/templates/app/apps/web/src/shared/ui/notice.tsx +7 -0
- package/templates/app/apps/web/src/shared/ui/page-heading.tsx +7 -0
- package/templates/app/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/app/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/app/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/app/apps/web/vite.config.ts +5 -0
- package/templates/app/cage.config.json +23 -0
- package/templates/app/db/migrations/0002_draft.sql +12 -0
- package/templates/app/db/migrations/0003_draft.sql +8 -0
- package/templates/app/db/migrations/0004_draft.sql +27 -0
- package/templates/app/deploy/nginx.conf +52 -0
- package/templates/app/docs/ai/README.md +28 -2
- package/templates/app/docs/ai/approvals.md +260 -0
- package/templates/app/docs/ai/architecture.md +26 -0
- package/templates/app/docs/ai/commenting.md +203 -0
- package/templates/app/docs/ai/diagnostics.md +80 -0
- package/templates/app/docs/ai/files.md +93 -0
- package/templates/app/docs/ai/intelligence.md +348 -0
- package/templates/app/docs/ai/ontology-context.md +59 -4
- package/templates/app/docs/ai/primitives.md +34 -1
- package/templates/app/docs/ai/project-structure.md +8 -3
- package/templates/app/docs/ai/purchase-example.md +35 -7
- package/templates/app/docs/ai/recipes.md +10 -2
- package/templates/app/docs/ai/routing.md +86 -0
- package/templates/app/docs/ai/troubleshooting.md +5 -0
- package/templates/app/docs/ai/workflow.md +24 -11
- package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/app/docs/errors/CAGE-APPR-001.md +13 -9
- package/templates/app/docs/errors/CAGE-APPR-002.md +2 -2
- package/templates/app/docs/errors/CAGE-APPR-003.md +1 -1
- package/templates/app/docs/errors/CAGE-APPR-004.md +4 -4
- package/templates/app/docs/errors/CAGE-APPR-005.md +4 -4
- package/templates/app/docs/errors/CAGE-APPR-006.md +29 -8
- package/templates/app/docs/errors/CAGE-APPR-007.md +9 -7
- package/templates/app/docs/errors/CAGE-APPR-010.md +5 -5
- package/templates/app/docs/errors/CAGE-AUDIT-001.md +53 -0
- package/templates/app/docs/errors/CAGE-AUTH-001.md +1 -1
- package/templates/app/docs/errors/CAGE-BIZ-001.md +51 -0
- package/templates/app/docs/errors/CAGE-BIZ-002.md +49 -0
- package/templates/app/docs/errors/CAGE-BUDGET-001.md +1 -1
- package/templates/app/docs/errors/CAGE-BUDGET-002.md +1 -1
- package/templates/app/docs/errors/CAGE-BUDGET-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CMD-002.md +1 -1
- package/templates/app/docs/errors/CAGE-CMD-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-001.md +3 -3
- package/templates/app/docs/errors/CAGE-CONN-002.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-003.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-004.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-005.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-006.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-007.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-008.md +5 -5
- package/templates/app/docs/errors/CAGE-CONN-009.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-010.md +6 -6
- package/templates/app/docs/errors/CAGE-CONN-011.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-012.md +1 -1
- package/templates/app/docs/errors/CAGE-CONN-013.md +49 -0
- package/templates/app/docs/errors/CAGE-CONN-014.md +48 -0
- package/templates/app/docs/errors/CAGE-CONN-015.md +49 -0
- package/templates/app/docs/errors/CAGE-CREATE-001.md +10 -9
- package/templates/app/docs/errors/CAGE-DECL-001.md +2 -2
- package/templates/app/docs/errors/CAGE-DECL-002.md +7 -6
- package/templates/app/docs/errors/CAGE-DECL-003.md +1 -1
- package/templates/app/docs/errors/CAGE-DECL-004.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-001.md +2 -2
- package/templates/app/docs/errors/CAGE-DEP-002.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-003.md +2 -2
- package/templates/app/docs/errors/CAGE-DEP-004.md +1 -1
- package/templates/app/docs/errors/CAGE-DEP-005.md +1 -1
- package/templates/app/docs/errors/CAGE-DIAG-001.md +53 -0
- package/templates/app/docs/errors/CAGE-DLQ-001.md +2 -2
- package/templates/app/docs/errors/CAGE-ENV-001.md +4 -4
- package/templates/app/docs/errors/CAGE-ENV-002.md +51 -0
- package/templates/app/docs/errors/CAGE-ENV-003.md +48 -0
- package/templates/app/docs/errors/CAGE-EVENT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-EVENT-002.md +7 -7
- package/templates/app/docs/errors/CAGE-FIELD-001.md +2 -2
- package/templates/app/docs/errors/CAGE-FIELD-002.md +1 -1
- package/templates/app/docs/errors/CAGE-FIELD-003.md +1 -1
- package/templates/app/docs/errors/CAGE-FIELD-004.md +1 -1
- package/templates/app/docs/errors/CAGE-FILE-001.md +56 -0
- package/templates/app/docs/errors/CAGE-GEN-001.md +2 -2
- package/templates/app/docs/errors/CAGE-GEN-002.md +1 -1
- package/templates/app/docs/errors/CAGE-GEN-003.md +53 -0
- package/templates/app/docs/errors/CAGE-GRANT-001.md +3 -3
- package/templates/app/docs/errors/CAGE-GRANT-002.md +2 -2
- package/templates/app/docs/errors/CAGE-GRANT-003.md +7 -6
- package/templates/app/docs/errors/CAGE-IMPACT-001.md +2 -2
- package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -0
- package/templates/app/docs/errors/CAGE-INIT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-003.md +2 -2
- package/templates/app/docs/errors/CAGE-INIT-004.md +1 -1
- package/templates/app/docs/errors/CAGE-INIT-005.md +52 -0
- package/templates/app/docs/errors/CAGE-JOB-001.md +1 -1
- package/templates/app/docs/errors/CAGE-JOB-002.md +1 -1
- package/templates/app/docs/errors/CAGE-JOB-003.md +1 -1
- package/templates/app/docs/errors/CAGE-LINT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-001.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-002.md +1 -1
- package/templates/app/docs/errors/CAGE-MIG-005.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-001.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-002.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-003.md +3 -3
- package/templates/app/docs/errors/CAGE-NAME-004.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-005.md +1 -1
- package/templates/app/docs/errors/CAGE-NAME-006.md +1 -1
- package/templates/app/docs/errors/CAGE-ORG-001.md +7 -6
- package/templates/app/docs/errors/CAGE-PAIR-002.md +6 -5
- package/templates/app/docs/errors/CAGE-QUERY-001.md +1 -1
- package/templates/app/docs/errors/CAGE-QUERY-002.md +2 -2
- package/templates/app/docs/errors/CAGE-QUERY-003.md +7 -6
- package/templates/app/docs/errors/CAGE-REACT-001.md +3 -3
- package/templates/app/docs/errors/CAGE-REACT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-REACT-003.md +50 -0
- package/templates/app/docs/errors/CAGE-READS-001.md +9 -6
- package/templates/app/docs/errors/CAGE-REG-001.md +13 -12
- package/templates/app/docs/errors/CAGE-REG-002.md +2 -1
- package/templates/app/docs/errors/CAGE-REG-003.md +1 -1
- package/templates/app/docs/errors/CAGE-REL-001.md +14 -14
- package/templates/app/docs/errors/CAGE-ROUTE-001.md +7 -6
- package/templates/app/docs/errors/CAGE-SCOPE-001.md +1 -1
- package/templates/app/docs/errors/CAGE-SCOPE-002.md +2 -2
- package/templates/app/docs/errors/CAGE-SECRET-001.md +2 -2
- package/templates/app/docs/errors/CAGE-SECRET-002.md +1 -1
- package/templates/app/docs/errors/CAGE-SENS-001.md +5 -5
- package/templates/app/docs/errors/CAGE-SQL-001.md +1 -1
- package/templates/app/docs/errors/CAGE-SQL-002.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-001.md +3 -3
- package/templates/app/docs/errors/CAGE-STATE-002.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-003.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-004.md +1 -1
- package/templates/app/docs/errors/CAGE-STATE-005.md +3 -2
- package/templates/app/docs/errors/CAGE-STATE-010.md +5 -5
- package/templates/app/docs/errors/CAGE-STATE-011.md +5 -5
- package/templates/app/docs/errors/CAGE-STRUCT-001.md +1 -1
- package/templates/app/docs/errors/CAGE-STRUCT-002.md +1 -1
- package/templates/app/docs/errors/CAGE-SYNC-001.md +3 -2
- package/templates/app/docs/errors/CAGE-TEST-001.md +1 -1
- package/templates/app/docs/errors/CAGE-TEST-002.md +50 -0
- package/templates/app/docs/errors/CAGE-TEST-003.md +52 -0
- package/templates/app/docs/errors/CAGE-UNSAFE-001.md +3 -2
- package/templates/app/docs/errors/CAGE-UPGRADE-001.md +2 -2
- package/templates/app/docs/errors/CAGE-WORKER-001.md +48 -0
- package/templates/app/docs/errors/CAGE-WORKER-002.md +50 -0
- package/templates/app/docs/errors/CAGE-WORKER-003.md +48 -0
- package/templates/app/docs/errors/README.md +52 -2
- package/templates/app/package.json +3 -3
- package/templates/app/packages/contracts/package.json +1 -1
- package/templates/app/packages/contracts/src/aggregates/approval-member/index.ts +70 -0
- package/templates/app/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/app/packages/contracts/src/aggregates/inventory/index.ts +5 -5
- package/templates/app/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
- package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +34 -12
- package/templates/app/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/app/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/app/packages/contracts/src/index.ts +16 -1
- package/templates/app/packages/contracts/src/queries/index.ts +2 -2
- package/templates/app/packages/domain/package.json +5 -4
- package/templates/app/packages/domain/src/index.ts +4 -0
- package/templates/app/packages/domain/src/integrations/erp.ts +15 -0
- package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
- package/templates/app/packages/domain/src/modules/inventory/index.ts +1 -0
- package/templates/app/packages/domain/src/modules/inventory/inventory.ts +12 -0
- package/templates/app/packages/domain/src/modules/purchase/approval-members.ts +54 -0
- package/templates/app/packages/domain/src/modules/purchase/approvals.ts +38 -6
- package/templates/app/packages/domain/src/modules/purchase/index.ts +2 -0
- package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +224 -0
- package/templates/app/packages/domain/src/modules/purchase/jobs.ts +5 -0
- package/templates/app/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
- package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +125 -4
- package/templates/app/packages/domain/src/modules/purchase/queries.ts +5 -0
- package/templates/app/packages/domain/src/workflows/purchase-inventory.ts +6 -0
- package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
- package/templates/blank/.dockerignore +2 -0
- package/templates/blank/.env.example +10 -0
- package/templates/blank/AGENTS.md +50 -10
- package/templates/blank/README.md +4 -1
- package/templates/blank/_gitignore +1 -0
- package/templates/blank/apps/api/package.json +1 -1
- package/templates/blank/apps/api/src/main.ts +4 -1
- package/templates/blank/apps/api/src/worker.ts +2 -0
- package/templates/blank/apps/web/index.html +1 -0
- package/templates/blank/apps/web/package.json +7 -3
- package/templates/blank/apps/web/src/app/app.tsx +80 -18
- package/templates/blank/apps/web/src/app/styles/global.css +90 -0
- package/templates/blank/apps/web/src/app/use-session.ts +43 -0
- package/templates/blank/apps/web/src/app/workspace-layout.tsx +30 -5
- package/templates/blank/apps/web/src/main.tsx +5 -0
- package/templates/blank/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +18 -1
- package/templates/blank/apps/web/src/modules/directory/index.ts +7 -0
- package/templates/blank/apps/web/src/modules/directory/pages/user-detail-page.tsx +78 -0
- package/templates/blank/apps/web/src/modules/directory/pages/users-page.tsx +93 -0
- package/templates/blank/apps/web/src/modules/workspace/index.ts +4 -0
- package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +17 -0
- package/templates/blank/apps/web/src/shared/lib/error-message.ts +11 -0
- package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/blank/apps/web/src/shared/ui/brand.tsx +10 -2
- package/templates/blank/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/blank/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/blank/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/blank/apps/web/vite.config.ts +5 -0
- package/templates/blank/deploy/nginx.conf +52 -0
- package/templates/blank/docs/ai/README.md +28 -2
- package/templates/blank/docs/ai/approvals.md +260 -0
- package/templates/blank/docs/ai/architecture.md +26 -0
- package/templates/blank/docs/ai/commenting.md +203 -0
- package/templates/blank/docs/ai/diagnostics.md +80 -0
- package/templates/blank/docs/ai/files.md +93 -0
- package/templates/blank/docs/ai/intelligence.md +348 -0
- package/templates/blank/docs/ai/ontology-context.md +59 -4
- package/templates/blank/docs/ai/primitives.md +34 -1
- package/templates/blank/docs/ai/project-structure.md +8 -3
- package/templates/blank/docs/ai/purchase-example.md +35 -7
- package/templates/blank/docs/ai/recipes.md +10 -2
- package/templates/blank/docs/ai/routing.md +86 -0
- package/templates/blank/docs/ai/troubleshooting.md +5 -0
- package/templates/blank/docs/ai/workflow.md +24 -11
- package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/blank/docs/errors/CAGE-APPR-001.md +13 -9
- package/templates/blank/docs/errors/CAGE-APPR-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-APPR-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-APPR-004.md +4 -4
- package/templates/blank/docs/errors/CAGE-APPR-005.md +4 -4
- package/templates/blank/docs/errors/CAGE-APPR-006.md +29 -8
- package/templates/blank/docs/errors/CAGE-APPR-007.md +9 -7
- package/templates/blank/docs/errors/CAGE-APPR-010.md +5 -5
- package/templates/blank/docs/errors/CAGE-AUDIT-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-AUTH-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-BIZ-001.md +51 -0
- package/templates/blank/docs/errors/CAGE-BIZ-002.md +49 -0
- package/templates/blank/docs/errors/CAGE-BUDGET-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-BUDGET-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-BUDGET-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CMD-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-CMD-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-CONN-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-006.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-007.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-008.md +5 -5
- package/templates/blank/docs/errors/CAGE-CONN-009.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-010.md +6 -6
- package/templates/blank/docs/errors/CAGE-CONN-011.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-012.md +1 -1
- package/templates/blank/docs/errors/CAGE-CONN-013.md +49 -0
- package/templates/blank/docs/errors/CAGE-CONN-014.md +48 -0
- package/templates/blank/docs/errors/CAGE-CONN-015.md +49 -0
- package/templates/blank/docs/errors/CAGE-CREATE-001.md +10 -9
- package/templates/blank/docs/errors/CAGE-DECL-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-DECL-002.md +7 -6
- package/templates/blank/docs/errors/CAGE-DECL-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-DECL-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-DEP-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-003.md +2 -2
- package/templates/blank/docs/errors/CAGE-DEP-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-DEP-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-DIAG-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-DLQ-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-ENV-001.md +4 -4
- package/templates/blank/docs/errors/CAGE-ENV-002.md +51 -0
- package/templates/blank/docs/errors/CAGE-ENV-003.md +48 -0
- package/templates/blank/docs/errors/CAGE-EVENT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-EVENT-002.md +7 -7
- package/templates/blank/docs/errors/CAGE-FIELD-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-FIELD-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-FIELD-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-FIELD-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-FILE-001.md +56 -0
- package/templates/blank/docs/errors/CAGE-GEN-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-GEN-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-GEN-003.md +53 -0
- package/templates/blank/docs/errors/CAGE-GRANT-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-GRANT-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-GRANT-003.md +7 -6
- package/templates/blank/docs/errors/CAGE-IMPACT-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -0
- package/templates/blank/docs/errors/CAGE-INIT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-003.md +2 -2
- package/templates/blank/docs/errors/CAGE-INIT-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-INIT-005.md +52 -0
- package/templates/blank/docs/errors/CAGE-JOB-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-JOB-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-JOB-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-LINT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-MIG-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-003.md +3 -3
- package/templates/blank/docs/errors/CAGE-NAME-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-005.md +1 -1
- package/templates/blank/docs/errors/CAGE-NAME-006.md +1 -1
- package/templates/blank/docs/errors/CAGE-ORG-001.md +7 -6
- package/templates/blank/docs/errors/CAGE-PAIR-002.md +6 -5
- package/templates/blank/docs/errors/CAGE-QUERY-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-QUERY-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-QUERY-003.md +7 -6
- package/templates/blank/docs/errors/CAGE-REACT-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-REACT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-REACT-003.md +50 -0
- package/templates/blank/docs/errors/CAGE-READS-001.md +9 -6
- package/templates/blank/docs/errors/CAGE-REG-001.md +13 -12
- package/templates/blank/docs/errors/CAGE-REG-002.md +2 -1
- package/templates/blank/docs/errors/CAGE-REG-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-REL-001.md +14 -14
- package/templates/blank/docs/errors/CAGE-ROUTE-001.md +7 -6
- package/templates/blank/docs/errors/CAGE-SCOPE-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-SCOPE-002.md +2 -2
- package/templates/blank/docs/errors/CAGE-SECRET-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-SECRET-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-SENS-001.md +5 -5
- package/templates/blank/docs/errors/CAGE-SQL-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-SQL-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-001.md +3 -3
- package/templates/blank/docs/errors/CAGE-STATE-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-003.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-004.md +1 -1
- package/templates/blank/docs/errors/CAGE-STATE-005.md +3 -2
- package/templates/blank/docs/errors/CAGE-STATE-010.md +5 -5
- package/templates/blank/docs/errors/CAGE-STATE-011.md +5 -5
- package/templates/blank/docs/errors/CAGE-STRUCT-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-STRUCT-002.md +1 -1
- package/templates/blank/docs/errors/CAGE-SYNC-001.md +3 -2
- package/templates/blank/docs/errors/CAGE-TEST-001.md +1 -1
- package/templates/blank/docs/errors/CAGE-TEST-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-TEST-003.md +52 -0
- package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +3 -2
- package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +2 -2
- package/templates/blank/docs/errors/CAGE-WORKER-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-WORKER-002.md +50 -0
- package/templates/blank/docs/errors/CAGE-WORKER-003.md +48 -0
- package/templates/blank/docs/errors/README.md +52 -2
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +5 -1
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +3 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +122 -12
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +88 -8
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/use-session.ts +43 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +58 -19
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/components/task-operation-dialog.tsx +61 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +13 -5
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +89 -38
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks.css +18 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +67 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-reviewers.tsx +38 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.tsx +32 -3
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-intelligence.css +17 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +156 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +54 -22
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/hooks/use-command.ts +13 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +15 -1
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/approval-member-picker.css +10 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/approval-member-picker.tsx +51 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.css +134 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.css +28 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +7 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +7 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.css +47 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.tsx +76 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/require-capability.tsx +34 -0
- package/templates/blank/docs/examples/purchase-admin/cage.config.json +23 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/approval-member/index.ts +70 -0
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +5 -5
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +34 -12
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +16 -1
- package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +2 -2
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +4 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +15 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/intelligence.ts +20 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +1 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +12 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approval-members.ts +54 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +38 -6
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +2 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +224 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +125 -4
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +6 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -0
- package/templates/blank/package.json +3 -3
- package/templates/blank/packages/contracts/package.json +1 -1
- package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +10 -10
- package/templates/blank/packages/contracts/src/aggregates/role/index.ts +15 -15
- package/templates/blank/packages/contracts/src/aggregates/user/index.ts +16 -16
- package/templates/blank/packages/contracts/src/index.ts +1 -1
- package/templates/blank/packages/contracts/src/queries/index.ts +1 -1
- package/templates/blank/packages/domain/package.json +5 -4
- package/templates/blank/packages/domain/src/index.ts +2 -1
|
@@ -69,6 +69,14 @@ worker → 消费 outbox → 异步反应 / 审批 / 连接器
|
|
|
69
69
|
|
|
70
70
|
资源标签 `acquires: 'inventory.lock'`、`releases: 'inventory.lock'` 为图规则提供证据。它们不会自动加锁或释放,真正效果来自 `acquireLock/releaseLock` 命令。
|
|
71
71
|
|
|
72
|
+
有界批量步骤可用 `reactionEach`:声明目标命令、最大项数、唯一排序键和映射,按稳定顺序串行调用。`order` 表达同一事件的步骤依赖,同事务链仍整体回滚。具体声明见[原语指南](primitives.md#有界集合与步骤顺序)。
|
|
73
|
+
|
|
74
|
+
出站分成外部执行与短事务回写两个阶段。框架先领取本地执行租约,用 `${tenantId}:${declaredKey}` 作为远端幂等键,可靠保存回执后再在短事务调用成功命令;回写失败可复用已保存回执。远端必须实际支持幂等,框架不能承诺任意外部系统恰好一次。不可安全重试的写入结果未知时隔离并要求核对,不能把超时当作远端未执行。
|
|
75
|
+
|
|
76
|
+
当前没有通用的远端回执确认或解除 `unknown` 的管理入口,普通死信重放不会解除未知状态。此类操作要按连接器实际协议制定受控恢复或业务补偿;不能发明恢复 API,也不能直接 SQL 改执行状态后重发。
|
|
77
|
+
|
|
78
|
+
首阶段按单机、API 与 worker 同版本升级部署。worker 启动校验必要引擎,发布消费者清单、注册指纹和心跳;不认识事件或缺少必要消费者时不会静默完成。停止时先停新任务、取消可取消 IO,再有界等待在途工作;定时任务同时使用本地运行标记与数据库互斥锁防止跨周期/实例重叠。连接器限流和认证队列均为单进程预算,多实例共享限流另需设计。
|
|
79
|
+
|
|
72
80
|
## 权限是几层判断
|
|
73
81
|
|
|
74
82
|
| 层 | 例子 | 说明 |
|
|
@@ -84,6 +92,23 @@ worker → 消费 outbox → 异步反应 / 审批 / 连接器
|
|
|
84
92
|
|
|
85
93
|
`useCan()`、`can()` 只决定按钮呈现;前端隐藏按钮不能代替后端授权。新增命令不会自动授给已有生产角色,角色分配和额度调整也受防提权约束。
|
|
86
94
|
|
|
95
|
+
授权通知监听异常时不再复用缓存,每次重新读取授权;重新订阅后清空缓存,并阻止旧请求回填旧上下文。`/readyz` 反映数据库和授权监听健康,`/healthz` 仅表示存活。诊断入口受 `Sys.ops.read` 及相关对象 read/范围控制,`explain` 解释调用身份、能力、范围、状态与硬约束,不能预测 handler 的业务结果;新建对象的最终范围无法提前确定时返回 unknown。
|
|
96
|
+
|
|
97
|
+
## 审计保证
|
|
98
|
+
|
|
99
|
+
| 入口 | 保证与失败行为 |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| 命令成功 | 与业务变更、版本和 outbox 同事务提交;写审计失败整笔回滚 |
|
|
102
|
+
| 命令拒绝 | FORBIDDEN / NOT_FOUND / CONSTRAINT_VIOLATED 异步尽力记录;失败有日志,不宣称所有错误均已留痕 |
|
|
103
|
+
| 密码登录失败 | 等待尝试写审计;失败有日志,请求仍拒绝登录,属于尽力记录 |
|
|
104
|
+
| get / list / related 的潜在敏感明文 | 具备相应 unmask 能力时先完成可靠审计再交付;失败拒绝结果 |
|
|
105
|
+
| 自定义 query | 按 reads 保守审计潜在敏感明文;声明 audit.purpose 时另外可靠记录目的;任一可靠审计失败均拒绝交付 |
|
|
106
|
+
| 导出生成、下载 | 可靠审计;下载还复核当前权限与访问指纹;失败不交付文件 |
|
|
107
|
+
| 导入任务及成功行 | 任务提交与目标命令按各自事务审计;异步逐行/原子方式见任务协议 |
|
|
108
|
+
| 普通掩码读取、诊断元数据 | 默认无统一专门审计 |
|
|
109
|
+
|
|
110
|
+
成功登录、step-up 和退出目前没有统一专门审计。审计保证按入口区分,不能把“有审计”理解为每一种请求都可靠留痕。可靠读取失败使用 `CAGE-AUDIT-001`,凭 requestId 定位数据库与权限故障;默认日志只保留允许的执行元数据,错误文本、原始 payload 与外部响应不进入默认结构化日志。
|
|
111
|
+
|
|
87
112
|
## 数据库连接属于框架核心能力
|
|
88
113
|
|
|
89
114
|
项目提供连接配置,框架管理连接池、事务、上下文变量和 SQL。普通业务不需要自己编写 `pg.Pool`、表仓储或连接释放逻辑。
|
|
@@ -103,6 +128,7 @@ APP、READ、MIGRATE 指向**同一个已经存在的数据库**,用不同账
|
|
|
103
128
|
| `init` | 角色、schema、授权、随机凭证及 `.env` | 安装 PG、启动 Docker、创建数据库、创建业务表 |
|
|
104
129
|
| `gen` | 本地 contracts、SQL、状态图、迁移草稿 | 应用数据库迁移 |
|
|
105
130
|
| `migrate` | 已有库的表、索引、安全视图、迁移历史 | 每次启动新建数据库 |
|
|
131
|
+
| `bootstrap` | 显式初始化组织,将初始凭据交付到新的受限文件 | 自动授予业务能力、日常启动时重置密码 |
|
|
106
132
|
| `dev` | 连接已有库,启动 API、worker、Web,监听声明重新生成 | 自动迁移或内嵌临时数据库兜底 |
|
|
107
133
|
|
|
108
134
|
读路径使用 `safe.*`,业务表位于 `core.*`,组织和运行数据位于 `sys.*`。安全视图结合会话上下文执行范围过滤与掩码;手写报表也必须走这层。连接现有库不意味着自动把历史任意表变成 Cage 聚合,需要专门的映射与迁移方案。
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# 详细中文注释规范
|
|
2
|
+
|
|
3
|
+
[返回学习入口](README.md) · [工程目录](project-structure.md) · [开发步骤](workflow.md)
|
|
4
|
+
|
|
5
|
+
本规范同时适用于 Cage 框架源码、标准范例,以及通过脚手架创建后由 Codex 等 agent 编写和维护的应用源码。**详细中文注释是代码交付的一部分。** 新建或修改代码时,必须让后续开发者仅凭源码及其注释理解职责、输入输出、关键步骤、设计原因、调用关系和行为边界,不能只在聊天回复或外部设计文档中解释。
|
|
6
|
+
|
|
7
|
+
注释需要回答“做什么、为什么这样做、具体怎么做、在哪些条件下成立、失败后怎样处理”。按照下面的覆盖项写到足以理解和修改代码的程度,不用每行注释、字数、行数比例衡量质量。不允许以“代码自解释”“名字已经足够清楚”免除必要的职责和接口说明;也不要把 `if`、赋值、循环等语法逐句翻译成没有信息量的中文。
|
|
8
|
+
|
|
9
|
+
## 新建与修改时的执行范围
|
|
10
|
+
|
|
11
|
+
1. 新建手写源码文件时,同步完成文件头、导出声明、类型字段以及关键流程的中文注释,再交付代码。测试、脚本、入口文件、React 组件、hooks、样式和手写 SQL 也属于源码。
|
|
12
|
+
2. 修改已有文件时,核对并补齐文件职责说明;为本次涉及的声明、参数、字段和流程补足注释。沿实际调用链同步更新受到影响的调用方、消费者、测试和配置说明,不能只改当前一行而留下上下游过时描述。与本次修改无关的整个仓库不要求一次性重写。
|
|
13
|
+
3. 调整行为、默认值、错误、权限、单位、状态或事务边界时,在同一变更中更新对应注释。移动代码时同时修正职责归属与引用,删除失效注释,不留下两个相互矛盾的解释。
|
|
14
|
+
4. 手写源码使用该语言支持的注释形式:TypeScript/JavaScript 的文件与接口说明优先 JSDoc,关键步骤用块注释或行注释,CSS/SQL 使用各自合法注释。JSON 等不支持注释的配置保持合法语法,在相邻文档说明字段含义并给出明确文件入口。
|
|
15
|
+
5. 生成契约、自动 SQL、派生测试等从声明与生成器维护注释,不能直接编辑生成结果;已执行或已发布的历史迁移不可因补注释而重写。具体边界见下文“生成物与迁移”。
|
|
16
|
+
|
|
17
|
+
## 每个文件先说明它在系统中的位置
|
|
18
|
+
|
|
19
|
+
每个新增或涉及修改的手写源码文件,开头应有中文职责说明。保留必须位于首行的 shebang 或工具指令,职责说明放在它们之后、普通实现之前。内容至少覆盖:
|
|
20
|
+
|
|
21
|
+
- **负责什么**:对应业务对象或技术能力,处理的主要问题;指出不由本文件承担但容易混淆的责任。
|
|
22
|
+
- **谁调用、调用谁**:所属模块、公开入口、主要上游和下游。入口文件说明如何装配注册表、服务或 Provider;纯转导出的 `index.ts` 说明对外暴露哪些职责、为什么从这里导出。
|
|
23
|
+
- **关键流程**:按实际顺序概述输入经过哪些处理,得到什么输出或产生什么副作用。简单纯函数文件可合并成一段;持久化、异步或多阶段流程需逐阶段解释。
|
|
24
|
+
- **运行与边界**:运行在浏览器、API、worker、CLI 还是测试进程,权限、事务、资源生命周期及配置由谁保证。存在 IO、缓存、共享状态或初始化行为时必须指出。
|
|
25
|
+
|
|
26
|
+
文件头写稳定的模块名和符号名,不维护易过期的代码行号或完整依赖清单。详细规则靠近实际声明,文件头负责建立读代码的路线,不能把所有实现细节堆成一份长篇设计文档。
|
|
27
|
+
|
|
28
|
+
## 导出 API、函数、类、组件和类型
|
|
29
|
+
|
|
30
|
+
对新增或修改的导出函数、类及公开成员、常量、领域声明、React 组件、hooks、接口和类型别名,紧邻声明编写中文 JSDoc。模块转导出保留原声明的详细 JSDoc,入口说明其对外职责;不要为同一接口复制多份会独立漂移的说明。
|
|
31
|
+
|
|
32
|
+
| 对象 | 必须说明的内容 |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| 函数与方法 | 解决什么问题、适用调用阶段、参数语义与约束、返回值含义、是否修改输入、是否执行 IO、失败如何返回或抛出;关键算法和取舍放在实现附近 |
|
|
35
|
+
| 类与公开成员 | 实例由谁创建/持有/关闭、内部状态与生命周期、依赖要求、并发访问是否支持;构造参数、方法和可读写属性分别说明 |
|
|
36
|
+
| 导出常量与声明对象 | 表达的业务或协议含义、使用方、取值来源、单位/默认值、改变它影响哪些行为;声明对象与实际执行不能混为一谈 |
|
|
37
|
+
| 接口、类型与字段 | 整体用途及数据来源,每个字段的业务语义、单位/格式、是否可空/可省略、缺省含义、只读或可写边界;联合类型逐个说明分支含义 |
|
|
38
|
+
| React 组件与 props | 对应页面或交互、输入数据和事件回调、状态由谁持有、可见性与权限提示、成功/失败后的页面行为;组件返回的 UI 及副作用 |
|
|
39
|
+
| hooks 与返回字段 | 何时读取或订阅、依赖与触发条件、状态含义、返回操作的完成条件、取消/卸载清理、缓存刷新及错误处理责任 |
|
|
40
|
+
|
|
41
|
+
函数使用真实参数名填写 `@param`,返回值使用 `@returns`,确实会抛出的错误使用 `@throws`。标签写不下的调用、权限或事务条件用正文说明。没有返回值的函数应说明副作用和完成条件,不能为了填标签编造一个结果;领域声明是配置对象,不要把 `@param` 写成不存在的顶层函数参数。泛型参数影响调用约束时说明其关系,不重复 TypeScript 已表达的类型文本。
|
|
42
|
+
|
|
43
|
+
复杂私有函数和回调同样需要说明:包括多阶段计算、SQL 构建、缓存合并、递归、重试、并发协调、状态转换及非直观数据映射。靠近相应分支解释分支成立的条件、处理顺序和保证范围。简单局部表达式可以由所在函数的说明覆盖,但不能让影响行为的隐藏规则失去解释。
|
|
44
|
+
|
|
45
|
+
## 数据与领域声明要写清业务含义
|
|
46
|
+
|
|
47
|
+
领域代码既是运行规则,也是后续 agent 理解业务的主要依据。聚合、状态、命令、事件、审批、反应、查询、任务、连接器应有各自的中文说明;框架支持的 `description` 用于简短公开说明,详细 JSDoc 用于源码维护,二者需要保持一致。普通源码注释不会自动成为权限规则、运行时校验或图谱声明,仍要填写真实 API 支持的配置。
|
|
48
|
+
|
|
49
|
+
| 声明 | 注释覆盖项 |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| 聚合与业务字段 | 对象的业务边界;字段由谁填写/计算;金额的币种和精度、数量单位、时间的时区与格式;空字符串、null、undefined、空集合分别意味着什么;敏感性、可修改阶段及关系归属 |
|
|
52
|
+
| 状态与不变量 | 每个状态代表的业务事实、进入和退出条件、终态允许行为;不变量保护什么规则、何时校验、拒绝后的影响,不能仅写“检查金额” |
|
|
53
|
+
| 命令与输入 | 调用身份和能力点、数据范围、起始/目标状态;输入来源、必填/默认/空值语义、校验与规范化;读取依赖和用途;handler 返回哪些变化;事件、事务、副作用及失败语义 |
|
|
54
|
+
| 事件与反应 | 事件表示哪项已发生事实、载荷字段来源、旧值/新值区别、兼容要求;消费者调用哪个命令、映射与跳过条件、执行顺序、同事务或 outbox、失败后的资源状态 |
|
|
55
|
+
| 审批 | 启动/取消条件、分支依据、选人来源、顺序与会签规则、结论命令、退回或转人工路径;选人不等于授予能力,AI 判断不等于硬约束已满足 |
|
|
56
|
+
| 查询 | 使用的安全视图/reads、调用人的 read 能力和范围、参数绑定、联表与聚合含义、排序/分页/截断、空结果含义、敏感数据及审计目的 |
|
|
57
|
+
| 定时任务与连接器 | 触发条件、读取/调用清单、处理上限和运行顺序;外部请求/响应映射、超时、重试分类、幂等依据、回执与补偿;fake 能验证与不能验证的范围 |
|
|
58
|
+
|
|
59
|
+
命令的状态、版本、幂等、权限、事务与审计由内核落实时,要明确这一责任分配;handler 注释不能把返回草稿描述成“已写入数据库”。`reads` 是显式只读依赖,资源 `acquires/releases` 是静态配对标签,二者都不代替真实业务动作。已有记录 `to: null` 表示保留当前状态,不能注释成“不检查状态”。
|
|
60
|
+
|
|
61
|
+
下面沿用[原语指南](primitives.md)的 Note 公开 API,展示一个完整文件的注释层次。应用仍需导出组织模型,并将本模块逐层从 domain 入口导出。示例不添加自动授权、额外持久化或不存在的框架选项。
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
/**
|
|
65
|
+
* 部门便笺领域:声明便笺字段、状态和创建/改标题操作。
|
|
66
|
+
* 模块经 domain 入口进入注册表,生成契约供业务页面调用;HTTP 将写请求交给内核。
|
|
67
|
+
* 本文件只描述业务规则和字段变化,不启动服务或自行执行数据库/网络 IO。
|
|
68
|
+
* 内核处理授权、范围、版本、字段校验及审计;实际可见部门由角色授权决定。
|
|
69
|
+
*/
|
|
70
|
+
import { aggregate, command, ref, scope, states, text } from '@yss123/cage-kernel';
|
|
71
|
+
import { z } from 'zod';
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 部门便笺:标题与归属信息作为同一个聚合维护。
|
|
75
|
+
* active 表示可编辑,archived 表示归档终态;归档命令可按原语指南另行声明。
|
|
76
|
+
* 本示例只开放创建和改标题,不会因声明 archived 就自动生成归档操作。
|
|
77
|
+
*/
|
|
78
|
+
export const Note = aggregate('Note', {
|
|
79
|
+
description: '部门便笺',
|
|
80
|
+
fields: {
|
|
81
|
+
/** 便笺标题,最多 120 个字符;命令去除首尾空白后要求非空,不接受 null。 */
|
|
82
|
+
title: text(120),
|
|
83
|
+
/** 所属部门 UUID;创建输入不允许指定,内核从当前主体部门补入,用于范围判断。 */
|
|
84
|
+
deptId: ref('Dept'),
|
|
85
|
+
/** 创建人 UUID;内核在新建结果中填入操作者,已有记录更新时保留原值。 */
|
|
86
|
+
createdBy: ref('User'),
|
|
87
|
+
},
|
|
88
|
+
/** active 可改标题;archived 为终态,update 的 from 会拒绝对归档记录的修改。 */
|
|
89
|
+
states: states('active', 'archived', { terminal: ['archived'] }),
|
|
90
|
+
/** 声明部门范围字段和建议范围,实际授权由角色决定,并非自动授予部门可见权。 */
|
|
91
|
+
scope: scope.deptSubtree('deptId'),
|
|
92
|
+
invariants: {
|
|
93
|
+
/** 对合并后的对象再次保证标题非空,避免其他命令将便笺写成无标题记录。 */
|
|
94
|
+
titleNotBlank: (note) => note.title.trim().length > 0,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 创建便笺:user 身份调用 Note.create,由 new 进入 active。
|
|
100
|
+
* 输入仅接收标题并去除首尾空白,归属字段交由内核按主体补入,不能由页面选择他人。
|
|
101
|
+
* 没有 reads 或业务事件;handler 返回的草稿由内核继续校验和持久化。
|
|
102
|
+
* 输入、权限或最终对象校验失败时不提交业务变更;声明不会给角色自动增加能力。
|
|
103
|
+
*/
|
|
104
|
+
export const createNote = command(Note, {
|
|
105
|
+
name: 'create',
|
|
106
|
+
description: '创建部门便笺',
|
|
107
|
+
from: 'new',
|
|
108
|
+
to: 'active',
|
|
109
|
+
input: z.object({
|
|
110
|
+
/** 用户填写的标题;trim 发生在长度校验前,最终持久化的是规范化后的文字。 */
|
|
111
|
+
title: z.string().trim().min(1).max(120),
|
|
112
|
+
}),
|
|
113
|
+
// 新建草稿已带规范化输入和部门,返回它继续走内核流水线;这里不执行数据库写入。
|
|
114
|
+
handler: (draft) => draft,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 修改有效便笺的标题:user 身份调用 Note.update,只有 active 记录允许执行。
|
|
119
|
+
* 内核先按调用人范围加载并锁定记录;to: null 保留已加载状态,仍检查 from 和权限。
|
|
120
|
+
* 页面应传入读到的版本以检测并发修改;版本不匹配时重新加载并让用户核对内容。
|
|
121
|
+
* handler 只返回标题变化,归属、状态与系统版本由内核维护;不发布业务事件。
|
|
122
|
+
*/
|
|
123
|
+
export const updateNote = command(Note, {
|
|
124
|
+
name: 'update',
|
|
125
|
+
description: '修改便笺标题',
|
|
126
|
+
from: 'active',
|
|
127
|
+
to: null,
|
|
128
|
+
input: z.object({
|
|
129
|
+
/** 待修改便笺的 UUID;存在不代表当前调用人有权访问。 */
|
|
130
|
+
id: z.string().uuid(),
|
|
131
|
+
/** 完整替换原标题,不是追加文本;不允许空标题,也不改变部门或创建人。 */
|
|
132
|
+
title: z.string().trim().min(1).max(120),
|
|
133
|
+
}),
|
|
134
|
+
// 显式只返回标题,避免把前端传入的字段扩散为未经声明的其他业务变化。
|
|
135
|
+
handler: (_draft, input) => ({ title: input.title }),
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
公开函数或类型的说明可以按下面的方式写。这个应用辅助函数只处理失败前缀的展示计数,不是新增 Cage API;实际业务中应明确使用它的页面或诊断模块。
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
/** 回放页面中已观察到的失败前缀位置;用于显示,不代表全局最小反例。 */
|
|
143
|
+
export interface FailurePosition {
|
|
144
|
+
/** 失败动作在已观察序列中的零基索引;null 表示尚未执行到失败动作。 */
|
|
145
|
+
failedIndex: number | null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 将失败位置转换为页面显示的动作序号,避免把零基索引直接交给使用者。
|
|
150
|
+
* 不修改输入,也不发起回放或数据库访问;索引的合法性由创建该位置的诊断层保证。
|
|
151
|
+
* @param position 诊断层提供的位置,failedIndex 为非负整数或 null。
|
|
152
|
+
* @returns 一基动作序号;尚无失败位置时返回 null,让页面显示“未发生失败”。
|
|
153
|
+
*/
|
|
154
|
+
export function failureStepNumber(position: FailurePosition): number | null {
|
|
155
|
+
return position.failedIndex === null ? null : position.failedIndex + 1;
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 异步、并发和恢复流程必须解释保证范围
|
|
160
|
+
|
|
161
|
+
涉及异步任务、worker、事务、重试、锁、缓存、队列、流式响应及清理时,除函数说明外,还要在关键步骤前写清以下事实:
|
|
162
|
+
|
|
163
|
+
- 任务何时被接受、何时实际执行、何时持久化、何时可视为业务完成;各阶段状态由谁更新,调用方等待的 Promise 到底表示哪个阶段结束。
|
|
164
|
+
- 同事务部分和事务外 IO 的边界,执行顺序的原因,失败会回滚哪些变化、哪些已发生效果无法回滚;多个步骤共同提交还是分别提交。
|
|
165
|
+
- 并发控制依据:版本、行锁、租约、互斥或唯一键各保护什么,保护到哪个进程/数据库范围;排序是否稳定,是否可能重复领取或乱序到达。
|
|
166
|
+
- 幂等键对应哪一次业务动作、由谁生成并保存、有效期和去重边界;重试是否复用原输入,结果未知时如何核对,不能把超时写成“远端未执行”。
|
|
167
|
+
- 失败的分类、重试条件、次数/时间预算、死信和人工恢复入口;已经持久化的回执怎样避免再次提交。不存在的恢复接口不得出现在注释中。
|
|
168
|
+
- 取消、断连、进程退出及卸载分别取消什么、清理什么;浏览器取消等待不保证服务端事务被取消,清理失败不能用空 catch 描述为成功。
|
|
169
|
+
- 缓存的数据来源、有效期、失效时机、账号/租户隔离及旧请求回填处理;权限变化时不能把仍未验证的缓存当作当前授权事实。
|
|
170
|
+
|
|
171
|
+
注释中的“原子”“恰好一次”“线程安全”“永不重复”“一定可恢复”等表述必须有实际实现支持,并写明限定范围。无法保证时直接描述当前行为、已知限制和调用方责任,不承诺超出实现的效果。
|
|
172
|
+
|
|
173
|
+
## 页面、组件、hooks 与样式
|
|
174
|
+
|
|
175
|
+
页面文件说明 URL 与参数来源、数据通过哪个生成契约或客户端获取、登录守卫与模块入口的关系。列表解释筛选/分页如何进入查询参数;详情解释如何独立按 URL 加载,不能依赖先访问列表。组件和 props 说明职责、数据归属与回调时机,hooks 说明触发、状态与清理。
|
|
176
|
+
|
|
177
|
+
在实际处理位置解释加载、空数据、网络错误、401、403、404、版本冲突和提交中状态;只描述该页面实际实现的分支,不机械列出所有错误码。明确前端 `can/useCan` 控制交互提示,真正授权由服务端完成。表单需解释草稿与已保存数据的区别、前后端校验分工、提交幂等键的生命周期以及成功后刷新哪些缓存。
|
|
178
|
+
|
|
179
|
+
effect、订阅和流式回调解释依赖为何需要、何时启动/终止、怎样阻止旧会话结果覆盖新状态。复杂布局、响应式断点、层叠与滚动、无障碍交互的样式注释说明对应使用场景与约束,不能只写“这里设置颜色”。样式文件仍需要职责说明,简单规则组可统一解释。
|
|
180
|
+
|
|
181
|
+
## 测试与维护脚本
|
|
182
|
+
|
|
183
|
+
测试文件说明被保护的业务或框架保证、使用真实数据库还是 fake、夹具的来源与隔离方式、该组测试的覆盖边界。用例名使用明确的中文行为描述;涉及边界或回归时,在用例附近解释“这个数据为什么这样准备、触发了什么风险、断言排除了什么错误”。测试 helper、共享夹具及复杂 mock 需要函数与字段说明,不能只把断言翻译成注释;fake 成功不应被写成真实第三方联调通过。
|
|
184
|
+
|
|
185
|
+
脚本文件头说明执行目录、前置配置、输入参数/环境变量的用途、读取和写入哪些路径或外部系统、是否覆盖文件、能否重复执行、失败后保留什么、如何清理。导出函数和关键阶段继续遵守本规范;不因脚本短或只供维护使用而省略副作用说明。命令示例只写变量名、示例路径和无秘密的占位值,不写真实连接串、密钥、Cookie、令牌、个人数据或初始化凭据。新增或维护脚本使用 TypeScript,不新增 `.mjs`。
|
|
186
|
+
|
|
187
|
+
## 生成物与迁移
|
|
188
|
+
|
|
189
|
+
生成文件必须由生成器写明来源、用途、重新生成入口和编辑边界;需要详细接口注释时,优先从领域 `description`、输入 schema 和真实生成规则形成,框架维护者修改生成器并验证产物。业务项目使用已安装的框架生成器;发现生成注释缺失时说明缺口,不能手改 contracts 来维持表面一致。不要声称任意 JSDoc 都会自动复制到契约,实际支持以生成器为准。
|
|
190
|
+
|
|
191
|
+
新建或尚未执行的迁移草稿应说明结构变动目的、数据兼容性、回填顺序、锁/停机影响及验证方式;无法证明影响时注明需要核对的条件。**已执行或已发布的历史迁移保持原样。** 对历史迁移的补充解释写在新文档或后续变更说明中,不为了补注释更改校验和。新增结构和数据变更使用新的迁移,仍须审查。
|
|
192
|
+
|
|
193
|
+
## 交付前逐项核对
|
|
194
|
+
|
|
195
|
+
- 新建文件是否有中文职责、调用链和运行边界;涉及的导出 API、类型字段、组件和 hooks 是否有完整 JSDoc。
|
|
196
|
+
- 本次改动的数据单位、空值、默认值、状态和授权条件是否解释明确;handler、框架和下游消费者的责任是否分清。
|
|
197
|
+
- 复杂流程是否解释关键步骤、条件、设计原因、失败与恢复;注释中的事务、幂等、并发与性能承诺是否符合实现。
|
|
198
|
+
- 调用方、测试、样式和脚本的相关说明是否同步更新;是否存在过时描述、机械复述或只写在聊天记录里的关键信息。
|
|
199
|
+
- 生成物是否通过声明/生成器更新,历史迁移是否保持不变,注释和示例是否包含秘密或真实个人数据。
|
|
200
|
+
|
|
201
|
+
代码检查和文档链接检查不能证明注释准确完整,必须结合本次 diff 阅读核对。交付说明列出注释覆盖的主要职责与边界,以及真实未覆盖项;验证仍分别报告通过、跳过和未执行。只修改注释时执行适合的格式/文档检查即可,不需要为注释新增复述实现的测试或重复全套数据库回归。
|
|
202
|
+
|
|
203
|
+
框架维护者还需注意:`cage budget` 按 TypeScript 语法 token 所占的原始物理行统计内核体积,排除普通注释、JSDoc 和纯空白;字符串、正则与跨行模板中的内容仍属于代码。同一行只计一次,不因格式化重新排版。新增详细注释不会增加实现预算;真实代码超出 5000 行仍触发 `CAGE-BUDGET-001`。应如实报告检查结果,不为通过预算删除必要说明、提高阈值或把未通过写成通过。统计逻辑的修改属于功能改动,不能混入“只补注释”的任务。
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 能力发现与状态诊断
|
|
2
|
+
|
|
3
|
+
业务开发前可以先按问题查框架公开能力,再定位当前项目中的声明。两个查询回答不同问题:`capabilities` 读取当前安装版本的公开类型,`context` 分析当前项目实际注册的业务。
|
|
4
|
+
|
|
5
|
+
```powershell
|
|
6
|
+
pnpm exec cage capabilities 本人 --format json
|
|
7
|
+
pnpm exec cage capabilities reactionEach --format json
|
|
8
|
+
pnpm exec cage capabilities "AI审批" --format json
|
|
9
|
+
pnpm exec cage capabilities "页面上下文" --format json
|
|
10
|
+
pnpm exec cage capabilities "性格" --format json
|
|
11
|
+
pnpm exec cage context "设备归还" --format json
|
|
12
|
+
pnpm exec cage doctor --format json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
公开能力报告包含包版本、真实签名、公开导出名、声明位置与本地学习指南。未安装的包标为未检查;未命中关键词不能证明能力不存在。完整例子见 [原语](primitives.md) 和 [任务配方](recipes.md)。
|
|
16
|
+
|
|
17
|
+
原生智能化可用“AI审批”“业务助理”“随页助理”“模型管理”“性格”“Responses”“上下文预算”等关键词检索,结果指向[智能化指南](intelligence.md)。例如 AI 审批返回现有 `step` 的重载及 `AiStepOptions`,不是另造 `aiStep` 原语。公开能力可被检索,不代表本应用已经导出 `ai()`、执行迁移、配置模型或授予角色权限;接着核对项目启用状态,最后进行实际功能验证。
|
|
18
|
+
|
|
19
|
+
`doctor` 复用 `check`、`gen --check`,输出统一的 `schemaVersion / observedAt / checks / findings / registration / routes`。每个检查包含 `status / source / reason / next`。`pass` 表示相应证据通过,`fail` 表示已发现问题,`unknown` 表示未检查;`complete: false` 不能作为完整验收通过。注册报告列出声明位置、domain 入口、注册节点和对应路由,集合反应还包含上限、排序键、顺序和事务。
|
|
20
|
+
|
|
21
|
+
诊断命令默认输出 JSON,`--format md` 输出 Markdown;`--out` 可保存报告。doctor 退出码为 0 表示完整通过,1 表示发现失败,2 表示尚有未知证据。离线使用通常返回 2,仍会交付已完成检查的结果。
|
|
22
|
+
|
|
23
|
+
默认不连接数据库、不读取项目密钥、不执行迁移或测试。需要实际进程证据时显式指定运行地址和受控会话 Cookie 文件:
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
pnpm exec cage doctor --runtime-url http://127.0.0.1:3000 --cookie-file .cage/diagnostic-cookie.txt
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
此模式只调用受 `Sys.ops.read` 保护的诊断接口。证据缺失、服务未运行、没有权限或没有 worker 心跳时标记 `unknown`;接口显示已加载版本和注册指纹,不能仅凭磁盘源码推断进程已经更新。能力已配置给某个角色也不代表任意用户具备范围、额度或调用身份。完成修改后仍需运行 `verify` 和实际业务验收。
|
|
30
|
+
|
|
31
|
+
运行指纹优先使用项目标准 `src→dist` 的实际编译入口,并逐文件检查源码与对应产物的修改时间。缺少构建或使用非标准输出布局时标记未知;编译后还需要重启 API 和 worker。源码经不同转换器执行时的函数文本可能不同,因此不把源码指纹直接当作生产产物指纹。
|
|
32
|
+
|
|
33
|
+
指纹包含声明结构与函数文本,不能证明任意闭包、外部依赖或 JavaScript 行为等价。首阶段按同版本 API/worker 升级;既有在途出站应先排空并核对远端幂等键,本轮远端键带租户前缀,不能把旧请求直接当作使用新键的同一次重试。
|
|
34
|
+
|
|
35
|
+
## 解释授权与追踪异步执行
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
pnpm exec cage timeline --request-id 请求关联标识 --runtime-url http://127.0.0.1:3000 --cookie-file .cage/diagnostic-cookie.txt
|
|
39
|
+
pnpm exec cage timeline --aggregate RentalApplication --aggregate-id 对象UUID --runtime-url http://127.0.0.1:3000 --cookie-file .cage/diagnostic-cookie.txt
|
|
40
|
+
pnpm exec cage explain RentalApplication.allocate --input-file .cage/allocate-input.json --runtime-url http://127.0.0.1:3000 --cookie-file .cage/diagnostic-cookie.txt
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
时间线也可通过 `--outbox-id` 查询。`explain` 的 JSON 文件只包含目标命令输入,`--user-id` 可诊断指定用户;接口不会执行该命令。CLI 自动取得 CSRF 令牌并合并 Cookie 后提交解释请求,不在输出中显示令牌或 Cookie。
|
|
44
|
+
|
|
45
|
+
三个运行诊断入口都要求 `Sys.ops.read`。读取业务时间线还需要对应对象的 read 能力和数据范围;诊断他人还要求 User.read 及相应范围。服务器继续进行这些校验,CLI 不会替调用人扩大范围。时间线只展示实际 outbox、消费者处理、连接器和审计记录,不用静态关系推断某次任务已执行。没有记录时应继续核对身份、筛选范围和业务写入结果。
|
|
46
|
+
|
|
47
|
+
连接器结果为 `unknown` 时,普通死信重放仍会拒绝外呼。当前没有通用确认回执或解除未知状态入口,必须先核对远端,再按具体连接器制定受控恢复或业务补偿;时间线不能替代远端事实。
|
|
48
|
+
|
|
49
|
+
## 保管本体基线
|
|
50
|
+
|
|
51
|
+
```powershell
|
|
52
|
+
pnpm exec cage snapshot save before-rental-change
|
|
53
|
+
pnpm exec cage snapshot list
|
|
54
|
+
# 修改声明之后
|
|
55
|
+
pnpm exec cage impact --snapshot before-rental-change --format json
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
命名快照保存时间、框架版本、图指纹与本体图,写入 `.cage/snapshots`;同名不覆盖。`context` 和图谱查询不再写入当前图文件,也不会修改已保存基线。已有 `impact --base <Git提交>`、`--base-file <本体图或快照>` 继续可用。
|
|
59
|
+
|
|
60
|
+
## 显式初始化组织
|
|
61
|
+
|
|
62
|
+
`cage init` 准备已有数据库中的账号;审查并执行迁移后,用独立命令初始化组织:
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
pnpm exec cage bootstrap --credentials-file .cage/admin-credentials.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
目标必须是新文件,父目录需存在。CLI 在写入密码前限制文件权限;Windows 使用实际执行进程 SID 设置独占 ACL,适用于服务/沙箱账号,不信任环境中的用户名;其他系统使用 `0600`。凭证在组织事务提交前写入,交付失败使组织和账号一起回滚;文件本身不能替代命令成功结果。凭证不输出到普通控制台或服务日志。组织已有用户时不重置密码。此命令仅注册组织模型,不自动赋予业务权限;业务能力需管理员显式配置。凭证文件必须保密并在交付后移除。
|
|
69
|
+
|
|
70
|
+
## 前端校验和 SDK
|
|
71
|
+
|
|
72
|
+
生成契约保留可表达的 strict 对象、数值倍数与默认值。自定义 `refine/superRefine`、transform 等可执行规则不能完整复制到客户端;生成报告通过 `CAGE-GEN-003` 指出字段路径,OpenAPI 通过 `x-cage-server-validation` 标记。服务端校验始终决定写入是否接受。
|
|
73
|
+
|
|
74
|
+
SDK 的 `get/post` 返回 `CageResult`;断网、读取响应体失败、主动取消、超时分别返回可预测的结果。请求选项支持 `signal/timeoutMs`。网络失败不自动重发写请求;仅 CSRF 明确拒绝时,刷新令牌并保留同一幂等键重试一次。
|
|
75
|
+
|
|
76
|
+
主动取消和超时只取消客户端等待,不保证服务端尚未提交。需要重试写请求时保留同一业务输入及 `idempotencyKey`,先核对服务端结果;生成的命令方法也接受 `RequestOptions`。不要因为浏览器取消就把已发生的业务操作显示为已撤销。
|
|
77
|
+
|
|
78
|
+
`useCageCommand` 失败抛 `CageCommandError`,其 `result` 保存错误码、领域错误和请求标识;成功返回业务数据,mutation 的 `isSuccess` 表示业务成功。独立 `CageClient` 保存独立身份和能力;默认导出的 `loadMe/currentUser/can` 可指定实例。应用订阅 `client.subscribe` 的退出、401、账号切换事件,取消用户相关请求并清理自己的查询缓存;旧响应不会覆盖新的会话身份。
|
|
79
|
+
|
|
80
|
+
派生测试可通过 `DerivedOptions.seed/fixtures` 提供固定种子与合法业务夹具。`CAGE-TEST-002` 区分 fixture 与 execution 阶段,保留初始数据、准备序列、前置不变量与失败前缀;诊断中的敏感字段会遮盖。最短已观察失败前缀用于重放,不等于对任意业务程序求得全局最小反例。
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# 私有文件字段与断点续传
|
|
2
|
+
|
|
3
|
+
[返回学习入口](README.md) · [原语](primitives.md) · [权限与执行模型](architecture.md)
|
|
4
|
+
|
|
5
|
+
文件字节由 `@yss123/cage-files` 管理;业务字段只保存文件 ID。上传完成得到临时文件,业务命令成功后才正式绑定。不要把文件内容、Base64、存储路径或公开 URL 放进业务字段、事件或审计。
|
|
6
|
+
|
|
7
|
+
## 声明与命令
|
|
8
|
+
|
|
9
|
+
下面是声明片段,放入现有聚合的 fields:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { file, files } from '@yss123/cage-kernel';
|
|
13
|
+
|
|
14
|
+
// 单文件为 UUID 或 null;多文件为 UUID 数组,新建不传时初始化为 []。
|
|
15
|
+
contract: file({ maxBytes: 20 * 1024 * 1024, accept: ['application/pdf'] }).optional(),
|
|
16
|
+
attachments: files({ maxCount: 10, maxBytes: 2 * 1024 ** 3, accept: ['application/pdf', 'image/jpeg', 'image/png', 'text/plain'] }),
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
上传目标用户命令必须使用 `z.object`,在 input 中直接声明同名字段,例如 `attachments: z.array(z.string().uuid()).max(10).optional()`;修改已有对象还需 input.id。不支持由任意别名输入推测文件归属。上传请求的 `command/field/targetId` 必须与声明一致;新建命令不传 targetId,已有对象命令必须传。
|
|
20
|
+
|
|
21
|
+
`files` 允许 1–100 的 maxCount;accept 使用明确 MIME,不接受扩展名或 `*/*`。文件只能放在聚合顶层,不嵌入 list/事件,不作为范围字段,也不支持 hidden/sensitive/unique。事件传引用使用 id/list(id())。文件不可覆盖,替换需要新文件 ID。一个文件只绑定一个对象的一个字段,第一版不共享文件。
|
|
22
|
+
|
|
23
|
+
生成契约包括 UUID/数组读侧类型和 `<Aggregate>FileFields` 限制;本体字段记录 filePolicy。修改声明后执行 `pnpm gen`,审查新迁移,执行 `pnpm migrate`。给已有对象增加必填 files 时,需要在新迁移草稿中把新列回填为 `[]` 再设 NOT NULL;不要修改历史迁移。采购范例的附件迁移演示了这个步骤。
|
|
24
|
+
|
|
25
|
+
## 客户端上传
|
|
26
|
+
|
|
27
|
+
下面是页面逻辑片段,selectedFile 为用户选择的浏览器 File:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { client, purchaseOrder } from '@app/contracts';
|
|
31
|
+
|
|
32
|
+
const task = client.upload(selectedFile, {
|
|
33
|
+
command: 'PurchaseOrder.create', field: 'attachments',
|
|
34
|
+
}, { concurrency: 3 });
|
|
35
|
+
const unsubscribe = task.subscribe(() => renderProgress(task.getSnapshot()));
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const uploaded = await task.start();
|
|
39
|
+
// 这里仍需处理 result.ok;保存失败可继续使用有效期内的同一附件 ID。
|
|
40
|
+
const result = await purchaseOrder.create({
|
|
41
|
+
amount: '100.00', items: [{ sku: 'A-01', qty: 1 }], attachments: [uploaded.id],
|
|
42
|
+
});
|
|
43
|
+
} finally {
|
|
44
|
+
unsubscribe();
|
|
45
|
+
task.dispose();
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`renderProgress` 是页面自己的显示函数。task.start() 失败会抛 FileUploadError(网络/服务端错误)或文件身份校验错误;页面必须捕获。React 可用 `useFileUpload(task)` 订阅稳定快照,卸载时 dispose 暂停并解除订阅。
|
|
50
|
+
|
|
51
|
+
- `task.pause()` 中断当前请求,保留服务端确认分片;等待本次 start 结束后再次 start 继续。
|
|
52
|
+
- `task.cancel()` 标记取消,清理由后台执行;已绑定附件不能取消,必须通过业务命令移除。
|
|
53
|
+
- 刷新后通过 `client.uploadSessions({ command, field, targetId? })` 查找本人未过期会话。用户重新选择原文件,再调用 `client.upload(file, target, { uploadId })`。SDK 对每个已确认分片重新计算 SHA-256,内容不一致则拒绝恢复。普通浏览器不会自动恢复本地文件访问权。
|
|
54
|
+
- SDK 默认并发 3,允许 1–6;失败分片退避重试。合并重试仍使用同一会话,超时不代表服务端未完成。
|
|
55
|
+
- 进度 confirmedBytes 只统计服务端确认的内容;恢复核对、上传、校验合并分别显示。不是逐网络字节进度。
|
|
56
|
+
- 注销、401 或切换账号会暂停任务并取消请求。业务应用仍需按会话隔离和清除自己的页面/查询缓存。
|
|
57
|
+
|
|
58
|
+
底层方法为 beginUpload/uploadSession/uploadSessions/uploadPart/completeUpload/cancelUpload/fileInfo/fileDownloadUrl。下载链接只含文件 ID,仍依靠当前 Cookie 会话授权,不是永久 bearer 链接。
|
|
59
|
+
|
|
60
|
+
## 服务端配置与存储
|
|
61
|
+
|
|
62
|
+
`createServer({ domain })` 默认启用私有本地目录 `.cage-files`,也可通过 `CAGE_FILES_DIR` 或 `files.directory` 指定。这个目录不属于可再生的 `.cage`,不能被发布清理脚本删除或静态服务公开;已从模板分发和 Git/Docker 上下文中排除。容器必须给运行用户提供可写持久卷。数据库元数据和文件内容需要配套备份,不能只备份数据库。
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
createServer({ domain, files: {
|
|
66
|
+
directory: '/srv/cage/private-files',
|
|
67
|
+
partBytes: 16 * 1024 * 1024,
|
|
68
|
+
maxFileBytes: 2 * 1024 ** 3,
|
|
69
|
+
maxPendingBytesPerUser: 8 * 1024 ** 3,
|
|
70
|
+
maxStoredBytesPerTenant: 100 * 1024 ** 3,
|
|
71
|
+
maxPendingUploadsPerUser: 100,
|
|
72
|
+
retentionMs: 24 * 3600_000,
|
|
73
|
+
ioTimeoutMs: 30 * 60_000,
|
|
74
|
+
} });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
有效文件上限取字段和系统限制的较小值。配额按租户串行预留,跨 API 实例有效;租户总量包括待清理内容。磁盘峰值还要预留合并占用和失败 IO 的临时内容,逻辑配额不是物理磁盘容量保证。上传会话到期不自动续期,第一版有效期固定;修改 partBytes 不影响已有会话的协议参数,部署时不要把路由限制调低到小于未完成旧会话的分片大小。
|
|
78
|
+
|
|
79
|
+
`FileStorage` 是公开存储适配接口:name/limits、writePart、complete、read(含范围)、remove、prune。通过 `files.storage` 注入。适配器需遵守长度/校验和、不可变产物、token 隔离、取消、幂等删除和流式内存边界。name 必须稳定标识相同存储空间;本地 name 含目录指纹,改目录后旧文件不会被误清理,但不会自动迁移。
|
|
80
|
+
|
|
81
|
+
本地先流式写分片,校验长度及 SHA-256,fsync 后确认;完成时按序流式复核并合并,最终 rename 发布。数据库事务不跨字节 IO。分片和合并使用持久租约,进程重启后确认清单仍在;未结束租约最多等待约两分钟后可接管。对象存储适配器可映射原生 multipart,但第一版只内置本地实现,未提供 S3/OSS SDK、签名直传或真实云存储联调。
|
|
82
|
+
|
|
83
|
+
API 进程启动后及每分钟执行有界清理。先锁元数据认领,再在事务外删除;已绑定文件不因上传有效期删除。移除后重新获得 24 小时保留期。墓碑定期复查,完成文件的过期执行残留也会重试清理。没有运行 API 时不会清理;单独使用 FileService 的调用方需定期调用 cleanup 并在退出时 close。
|
|
84
|
+
|
|
85
|
+
## 权限、下载与部署
|
|
86
|
+
|
|
87
|
+
暂存、分片和完成需要本人登录、目标用户命令能力;修改已有对象还检查当前 read/范围及命令起始状态。硬约束及最终字段关联在业务命令提交时校验,上传预检查不表示命令必定成功。命令事务重新验证租户、上传者、目标字段、目标对象、文件状态、有效期、大小与类型;关联和业务记录、审计、outbox 同事务提交或回滚。旧附件保留不要求当前操作者是原上传者。
|
|
88
|
+
|
|
89
|
+
绑定后元数据和下载按所属对象当前 read/范围及字段引用授权;临时完成文件只对上传者开放且仍需目标命令能力。下载交付前写可靠审计,失败拒绝交付。响应使用 attachment、nosniff 和 no-store,支持单段 HTTP Range;第一版不提供匿名访问或在线 Office 预览。
|
|
90
|
+
|
|
91
|
+
服务端对已知二进制格式检查内容头;UTF-8 文本进行保守前缀校验;未知二进制只能显式允许 application/octet-stream。这不是病毒扫描、完整文件格式验证或所有 MIME 的识别保证。
|
|
92
|
+
|
|
93
|
+
代理必须允许至少一个分片的请求体,并关闭分片请求缓冲;采购部署 Nginx 示例提供默认 16 MiB 配置。合并可能持续较久,代理超时要与服务配置协调。本地模式的多个 API 必须共享同一个持久目录和配置;不同磁盘节点不能只共享数据库。新增加的 setAttachments 等业务能力仍需管理员显式授权,框架不会自动授给生产角色。
|