@yss123/cage-cli 0.1.0 → 0.3.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 +69 -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 +20 -2
- package/dist/analyze.js.map +1 -1
- 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 +133 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/config.d.ts +33 -4
- package/dist/config.js +22 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +86 -0
- package/dist/context.js +235 -0
- package/dist/context.js.map +1 -0
- package/dist/create-prompt.d.ts +12 -0
- package/dist/create-prompt.js +62 -0
- package/dist/create-prompt.js.map +1 -0
- package/dist/create.d.ts +38 -1
- package/dist/create.js +52 -13
- 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 +23 -51
- 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 +81 -20
- package/dist/gen/contracts.js.map +1 -1
- package/dist/gen/index.d.ts +26 -0
- package/dist/gen/index.js +112 -4
- package/dist/gen/index.js.map +1 -1
- package/dist/gen/zod-code.d.ts +43 -1
- package/dist/gen/zod-code.js +180 -16
- package/dist/gen/zod-code.js.map +1 -1
- package/dist/graph-approvals.d.ts +60 -0
- package/dist/graph-approvals.js +80 -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 +28 -0
- package/dist/graph-command.js +88 -0
- package/dist/graph-command.js.map +1 -0
- package/dist/graph-model.d.ts +65 -0
- package/dist/graph-model.js +134 -0
- package/dist/graph-model.js.map +1 -0
- package/dist/graph-presentation.d.ts +27 -0
- package/dist/graph-presentation.js +34 -0
- package/dist/graph-presentation.js.map +1 -0
- package/dist/graph-query.d.ts +266 -0
- package/dist/graph-query.js +304 -0
- package/dist/graph-query.js.map +1 -0
- package/dist/graph-relations.d.ts +34 -0
- package/dist/graph-relations.js +172 -0
- package/dist/graph-relations.js.map +1 -0
- package/dist/graph-search.d.ts +56 -0
- package/dist/graph-search.js +99 -0
- package/dist/graph-search.js.map +1 -0
- package/dist/graph-snapshot.d.ts +28 -4
- package/dist/graph-snapshot.js +32 -20
- package/dist/graph-snapshot.js.map +1 -1
- package/dist/graph.d.ts +13 -2
- package/dist/graph.js +78 -5
- package/dist/graph.js.map +1 -1
- package/dist/impact.d.ts +56 -0
- package/dist/impact.js +90 -18
- package/dist/impact.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +18 -0
- package/dist/init.js +146 -0
- package/dist/init.js.map +1 -0
- 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 +170 -37
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +15 -6
- package/dist/migrate.js +31 -53
- package/dist/migrate.js.map +1 -1
- package/dist/ontology.d.ts +69 -2
- package/dist/ontology.js +101 -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 +13 -0
- package/dist/project-structure.js +104 -0
- package/dist/project-structure.js.map +1 -0
- 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 +38 -5
- package/dist/static-check.js.map +1 -1
- package/dist/sync.d.ts +11 -0
- package/dist/sync.js +139 -10
- 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 +367 -35
- package/graph-ui/approval-flow.js +165 -0
- package/graph-ui/business.css +985 -0
- package/graph-ui/business.js +549 -0
- package/graph-ui/flowchart-interaction.js +177 -0
- package/graph-ui/flowchart.js +1059 -0
- package/graph-ui/graph-approvals.js +79 -0
- package/graph-ui/graph-business.js +403 -0
- package/graph-ui/graph-model.js +133 -0
- package/graph-ui/graph-relations.js +171 -0
- package/graph-ui/graph-search.js +98 -0
- package/graph-ui/index.html +26 -12
- package/graph-ui/model.js +47 -77
- package/graph-ui/relations.js +6 -125
- package/graph-ui/structure.js +48 -1
- package/graph-ui/style.css +33 -0
- package/package.json +10 -8
- package/templates/app/.dockerignore +2 -0
- package/templates/app/.env.example +68 -14
- package/templates/app/AGENTS.md +135 -12
- package/templates/app/Dockerfile +2 -0
- package/templates/app/README.md +49 -16
- package/templates/app/_gitignore +9 -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 +128 -0
- package/templates/app/apps/web/src/{style.css → 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 +109 -0
- package/templates/app/apps/web/src/main.tsx +9 -543
- package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
- package/templates/app/apps/web/src/modules/approval/index.ts +6 -0
- package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
- package/templates/app/apps/web/src/modules/auth/index.ts +5 -0
- package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
- package/templates/app/apps/web/src/modules/inventory/index.ts +5 -0
- package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
- package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
- package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -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 +82 -0
- package/templates/app/apps/web/src/modules/purchase/index.ts +7 -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 +15 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
- package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
- 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 +42 -0
- package/templates/app/apps/web/src/shared/lib/error-message.ts +24 -0
- package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -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 +20 -0
- package/templates/app/apps/web/src/shared/ui/page-heading.tsx +35 -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 +8 -0
- package/templates/app/cage.config.json +10 -1
- package/templates/app/db/migrations/0002_draft.sql +12 -0
- package/templates/app/db/migrations/0003_draft.sql +8 -0
- package/templates/app/deploy/nginx.conf +52 -0
- package/templates/app/docs/ai/README.md +98 -0
- package/templates/app/docs/ai/architecture.md +148 -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 +172 -0
- package/templates/app/docs/ai/primitives.md +282 -0
- package/templates/app/docs/ai/project-structure.md +128 -0
- package/templates/app/docs/ai/purchase-example.md +111 -0
- package/templates/app/docs/ai/recipes.md +89 -0
- package/templates/app/docs/ai/relations.md +160 -0
- package/templates/app/docs/ai/routing.md +86 -0
- package/templates/app/docs/ai/transfers.md +92 -0
- package/templates/app/docs/ai/troubleshooting.md +65 -0
- package/templates/app/docs/ai/workflow.md +152 -0
- package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/app/docs/errors/CAGE-APPR-001.md +48 -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 +53 -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-AUDIT-001.md +53 -0
- package/templates/app/docs/errors/CAGE-AUTH-001.md +47 -0
- 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 +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-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 +53 -0
- package/templates/app/docs/errors/CAGE-DECL-001.md +48 -0
- package/templates/app/docs/errors/CAGE-DECL-002.md +48 -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-DIAG-001.md +53 -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-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 +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-FILE-001.md +56 -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-GEN-003.md +53 -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 +48 -0
- package/templates/app/docs/errors/CAGE-IMPACT-001.md +48 -0
- package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -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-INIT-005.md +52 -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 +50 -0
- package/templates/app/docs/errors/CAGE-PAIR-002.md +51 -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 +50 -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-REACT-003.md +50 -0
- package/templates/app/docs/errors/CAGE-READS-001.md +50 -0
- package/templates/app/docs/errors/CAGE-REG-001.md +54 -0
- package/templates/app/docs/errors/CAGE-REG-002.md +49 -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 +48 -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 +49 -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 +49 -0
- package/templates/app/docs/errors/CAGE-TEST-001.md +47 -0
- 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 +49 -0
- package/templates/app/docs/errors/CAGE-UPGRADE-001.md +48 -0
- 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 +357 -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} +11 -11
- package/templates/app/packages/contracts/src/{inventory.ts → aggregates/inventory/index.ts} +6 -6
- package/templates/app/packages/contracts/src/{inventory-lock.ts → aggregates/inventory-lock/index.ts} +5 -5
- package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +86 -0
- package/templates/app/packages/contracts/src/{role.ts → aggregates/role/index.ts} +16 -16
- package/templates/app/packages/contracts/src/aggregates/user/index.ts +89 -0
- package/templates/app/packages/contracts/src/index.ts +20 -14
- package/templates/app/packages/contracts/src/{queries.ts → queries/index.ts} +2 -2
- package/templates/app/packages/domain/package.json +5 -4
- package/templates/app/packages/domain/src/index.ts +8 -7
- package/templates/app/packages/domain/src/{erp.ts → integrations/erp.ts} +16 -1
- package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
- package/templates/app/packages/domain/src/modules/inventory/index.ts +3 -0
- package/templates/app/packages/domain/src/{inventory.ts → modules/inventory/inventory.ts} +12 -0
- package/templates/app/packages/domain/src/modules/purchase/approvals.ts +39 -0
- package/templates/app/packages/domain/src/modules/purchase/index.ts +7 -0
- package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
- package/templates/app/packages/domain/src/{jobs.ts → modules/purchase/jobs.ts} +5 -0
- package/templates/app/packages/domain/src/{purchase-order.test.ts → modules/purchase/purchase-order.test.ts} +11 -2
- package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
- package/templates/app/packages/domain/src/{queries.ts → modules/purchase/queries.ts} +5 -0
- package/templates/app/packages/domain/src/{reactions.ts → workflows/purchase-inventory.ts} +8 -2
- package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
- package/templates/blank/.dockerignore +12 -0
- package/templates/blank/.env.example +71 -0
- package/templates/blank/.github/workflows/cage.yml +44 -0
- package/templates/blank/AGENTS.md +136 -0
- package/templates/blank/Dockerfile +25 -0
- package/templates/blank/README.md +40 -0
- package/templates/blank/_gitignore +9 -0
- package/templates/blank/apps/api/package.json +15 -0
- package/templates/blank/apps/api/src/main.ts +14 -0
- package/templates/blank/apps/api/src/worker.ts +10 -0
- package/templates/blank/apps/api/tsconfig.json +5 -0
- package/templates/blank/apps/web/index.html +14 -0
- package/templates/blank/apps/web/package.json +26 -0
- package/templates/blank/apps/web/src/app/app.tsx +106 -0
- package/templates/blank/apps/web/src/app/styles/global.css +606 -0
- package/templates/blank/apps/web/src/app/use-session.ts +43 -0
- package/templates/blank/apps/web/src/app/workspace-layout.tsx +95 -0
- package/templates/blank/apps/web/src/main.tsx +18 -0
- package/templates/blank/apps/web/src/modules/auth/index.ts +5 -0
- package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +104 -0
- 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 +5 -0
- package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +62 -0
- package/templates/blank/apps/web/src/shared/lib/error-message.ts +22 -0
- package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
- package/templates/blank/apps/web/src/shared/ui/brand.tsx +19 -0
- 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/tsconfig.json +11 -0
- package/templates/blank/apps/web/vite.config.ts +24 -0
- package/templates/blank/cage.config.json +14 -0
- package/templates/blank/db/migrations/0001_init.sql +63 -0
- package/templates/blank/deploy/nginx.conf +52 -0
- package/templates/blank/docs/ai/README.md +98 -0
- package/templates/blank/docs/ai/architecture.md +148 -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 +172 -0
- package/templates/blank/docs/ai/primitives.md +282 -0
- package/templates/blank/docs/ai/project-structure.md +128 -0
- package/templates/blank/docs/ai/purchase-example.md +111 -0
- package/templates/blank/docs/ai/recipes.md +89 -0
- package/templates/blank/docs/ai/relations.md +160 -0
- package/templates/blank/docs/ai/routing.md +86 -0
- package/templates/blank/docs/ai/transfers.md +92 -0
- package/templates/blank/docs/ai/troubleshooting.md +65 -0
- package/templates/blank/docs/ai/workflow.md +152 -0
- package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
- package/templates/blank/docs/errors/CAGE-APPR-001.md +48 -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 +53 -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-AUDIT-001.md +53 -0
- package/templates/blank/docs/errors/CAGE-AUTH-001.md +47 -0
- 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 +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-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 +53 -0
- package/templates/blank/docs/errors/CAGE-DECL-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-DECL-002.md +48 -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-DIAG-001.md +53 -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-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 +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-FILE-001.md +56 -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-GEN-003.md +53 -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 +48 -0
- package/templates/blank/docs/errors/CAGE-IMPACT-001.md +48 -0
- package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -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-INIT-005.md +52 -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 +50 -0
- package/templates/blank/docs/errors/CAGE-PAIR-002.md +51 -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 +50 -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-REACT-003.md +50 -0
- package/templates/blank/docs/errors/CAGE-READS-001.md +50 -0
- package/templates/blank/docs/errors/CAGE-REG-001.md +54 -0
- package/templates/blank/docs/errors/CAGE-REG-002.md +49 -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 +48 -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 +49 -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 +49 -0
- package/templates/blank/docs/errors/CAGE-TEST-001.md +47 -0
- 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 +49 -0
- package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +48 -0
- 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 +357 -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 +14 -0
- package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +17 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +128 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +743 -0
- 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 +109 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +18 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +6 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +5 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +32 -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/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 +82 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +7 -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 +15 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
- 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 +42 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +24 -0
- 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/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 +20 -0
- package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +35 -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 +123 -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 +86 -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 +87 -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 +10 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +51 -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 +3 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +55 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +39 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +7 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +18 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +146 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +15 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +30 -0
- package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -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 +24 -0
- package/templates/blank/packages/domain/src/index.ts +5 -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/packages/contracts/src/purchase-order.ts +0 -72
- package/templates/app/packages/contracts/src/user.ts +0 -89
- package/templates/app/packages/domain/src/approvals.ts +0 -18
- package/templates/app/packages/domain/src/purchase-order.ts +0 -122
package/templates/app/Dockerfile
CHANGED
|
@@ -16,6 +16,8 @@ FROM node:24-bookworm-slim AS runtime
|
|
|
16
16
|
WORKDIR /app
|
|
17
17
|
COPY --from=build --chown=node:node /out/api /app
|
|
18
18
|
COPY --from=build --chown=node:node /app/apps/web/dist /app/web
|
|
19
|
+
# 系统管理与图谱共享中文显示配置;运行时工作目录同样保持为 /app。
|
|
20
|
+
COPY --from=build --chown=node:node /app/cage.config.json /app/cage.config.json
|
|
19
21
|
ENV NODE_ENV=production PORT=3000 WEB_DIR=/app/web
|
|
20
22
|
USER node
|
|
21
23
|
EXPOSE 3000
|
package/templates/app/README.md
CHANGED
|
@@ -1,30 +1,61 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Cage 业务应用(含采购示例)
|
|
2
2
|
|
|
3
3
|
这是可启动的标准范例:组织管理、采购单、审批待办、库存台账、库存锁生命周期和 ERP 出入站映射。
|
|
4
4
|
|
|
5
|
+
## 让 AI 在本项目开发业务
|
|
6
|
+
|
|
7
|
+
把本目录交给 Codex 等编程工具时,先让它读 [AGENTS.md](AGENTS.md),再按[业务开发指南](docs/ai/README.md)和[任务配方](docs/ai/recipes.md)实现需求。普通业务不需要修改框架源码。
|
|
8
|
+
|
|
9
|
+
[采购全链路导读](docs/ai/purchase-example.md)说明每个文件和异步步骤;[原语与最小业务](docs/ai/primitives.md)提供可添加的普通管理对象;[错误码册](docs/errors/README.md)用于按码修复。脚手架会将这些资料放入生成项目本地的 `docs/ai` 与 `docs/errors`,无需再次克隆框架。
|
|
10
|
+
|
|
5
11
|
## 启动
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
在本项目根目录执行 `pnpm install`、`pnpm build:app`;无需克隆或构建框架仓库。
|
|
8
14
|
|
|
9
15
|
```powershell
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
#
|
|
13
|
-
pnpm cage
|
|
16
|
+
# 首次配置时复制,已有 .env 时直接编辑原文件。
|
|
17
|
+
Copy-Item .env.example .env
|
|
18
|
+
# 编辑 .env,只填写 CAGE_ADMIN_DATABASE_URL,连接已经存在的数据库。
|
|
19
|
+
pnpm exec cage init
|
|
20
|
+
# init 自动创建账号、生成密码和 Cookie 密钥,并写回 .env。
|
|
21
|
+
pnpm gen
|
|
22
|
+
# 审查 db/migrations 后执行表结构迁移。
|
|
23
|
+
pnpm migrate
|
|
24
|
+
pnpm exec cage bootstrap --credentials-file .cage/admin-credentials.json
|
|
14
25
|
pnpm dev
|
|
15
26
|
```
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
数据库配置位于本项目根目录的 `.env`,与 `package.json`、`cage.config.json` 同级。[`.env.example`](.env.example) 为每项提供中文注释、填写格式和是否必填。连接池和事务由框架提供,项目只需配置连接。
|
|
29
|
+
|
|
30
|
+
| 配置项 | 用途 |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `CAGE_APP_DATABASE_URL` | `cage_app` 账号:API/worker 业务读写 |
|
|
33
|
+
| `CAGE_READ_DATABASE_URL` | `cage_read` 账号:仅查询安全视图 |
|
|
34
|
+
| `CAGE_MIGRATE_DATABASE_URL` | `cage_migrate` 账号:手动执行表结构迁移 |
|
|
35
|
+
|
|
36
|
+
三个连接由 `cage init` 自动生成,指向**同一个已经存在的数据库**,主机、端口和库名一致。CLI 自动读取 `.env`,部署环境中的同名变量优先。修改后重启 `dev`。`migrate` 在下次执行时读取配置。
|
|
37
|
+
|
|
38
|
+
`pnpm migrate` 更新该库中的表、视图和索引;迁移历史记录在 `sys.schema_migrations`。`pnpm dev` 连接该库并启动 API、worker 和 Web,domain 变化后仅重新生成文件;表结构变更需审查迁移后手动执行。框架不创建数据库、不安装 PostgreSQL、不管理 Docker。
|
|
18
39
|
|
|
19
|
-
|
|
40
|
+
### 首次只提供管理员连接
|
|
41
|
+
|
|
42
|
+
在 `.env` 中填写 `CAGE_ADMIN_DATABASE_URL=postgresql://postgres:管理员密码@主机:端口/已有数据库名`。PostgreSQL 管理员通常叫 `postgres`,已有管理员叫 `root` 时使用实际账号名;连接串中的密码特殊字符需要 URL 编码。
|
|
43
|
+
|
|
44
|
+
执行 `pnpm exec cage init` 会创建框架账号和授权,生成三个独立随机密码及 Cookie 密钥,自动填写 `.env`,成功后移除文件中的管理员连接。业务端口、自定义配置和已有 Cookie 密钥会保留;失败会回滚数据库并保留原 `.env`。日常启动不需要管理员连接。
|
|
45
|
+
|
|
46
|
+
重复 `init` 会验证并复用已保存的三个账号,不更改密码。若集群已有 Cage 账号但本项目没有原连接,请先复用原凭证再运行 `init`;命令不会为了新项目重置其他项目的账号。部署时也可由平台直接提供三个账号连接,无需执行本地初始化。
|
|
47
|
+
|
|
48
|
+
数据库除三个登录账号外,还有不允许登录的 `cage_view_owner`,由 `init` 一并创建,用于持有安全视图,无需填写密码。角色名属于整个 PostgreSQL 集群,不能为另一个项目随意重置密码。业务表及系统表由后续 `pnpm migrate` 创建,`init` 只准备角色、schema 和授权。连接现有数据库不表示框架会自动识别、接管其中任意历史业务表;接入历史表需另行映射和审查迁移。
|
|
20
49
|
|
|
21
50
|
测试环境会初始化集群级角色,因此 `CAGE_TEST_DATABASE_URL` 必须指向独立测试集群。运行 `pnpm cage verify` 验证示例;框架仓库根目录的 `pnpm test:docker` 验证全部框架测试。
|
|
22
51
|
|
|
23
|
-
|
|
24
|
-
|
|
52
|
+
浏览器打开终端打印的 Web 地址;配置示例使用 <http://localhost:15173>。管理员凭证由显式 bootstrap 交付到新的受限文件,交付后移除。初始化仅授予系统管理能力,采购能力需要管理员明确配置。
|
|
53
|
+
`CAGE_WEB_PORT` 控制 Web 端口,`PORT` 控制 API 端口,Vite 代理同步使用它。缺少数据库配置时会给出错误,需填写 `.env` 后重新启动。
|
|
25
54
|
|
|
26
55
|
## 体验完整采购流程
|
|
27
56
|
|
|
57
|
+
前端使用 React Router:工作台 `/workspace`,采购列表 `/procurement/orders`,单据详情 `/procurement/orders/:id`,审批 `/approvals`,库存 `/inventory`,登录 `/login`。单号和审批待办可直接打开详情;刷新、前进后退和登录回跳保留页面地址。新增页面与部署按[路由和浏览器验收指南](docs/ai/routing.md)执行;Nginx 示例见 [deploy/nginx.conf](deploy/nginx.conf)。
|
|
58
|
+
|
|
28
59
|
1. 管理员在“库存台账”登记 `A-01` 等物料。
|
|
29
60
|
2. 进入 `/admin/` 创建采购员、经理,分别分配采购命令和审批能力;经理的 `PurchaseOrder.approve` 参数配置 `ceiling`。
|
|
30
61
|
3. 把经理设为采购员所在部门的负责人。提单人与审批人必须不同。
|
|
@@ -47,12 +78,14 @@ CLI 自动读取项目 `.env`,部署环境变量优先。`CAGE_APP_DATABASE_UR
|
|
|
47
78
|
|
|
48
79
|
图谱主标题显示中文业务名称,下面保留英文代码标识。框架会读取声明现有的 `description`;本项目在 `cage.config.json` 的 `graph.labels` 中补充状态、字段等名称,也可覆盖较长描述。例如 `"command:PurchaseOrder.approve": "通过审批"`。键为 `节点类型:本体节点 ID`,可从节点详情复制 ID;中文标题只用于显示,不改变命令、权限标识或数据库。新增业务声明时同时补上需要的名称,然后在图谱中点击“重新抽取”。
|
|
49
80
|
|
|
50
|
-
- `packages/domain/src/inventory
|
|
51
|
-
- `purchase
|
|
52
|
-
- `
|
|
53
|
-
- `
|
|
54
|
-
- `
|
|
81
|
+
- `packages/domain/src/modules/inventory`:最简聚合和库存锁。
|
|
82
|
+
- `packages/domain/src/modules/purchase`:采购状态、命令、约束、事件、审批、查询和任务。
|
|
83
|
+
- `packages/domain/src/workflows/purchase-inventory.ts`:同事务建锁与异步释放,包含资源配对标记。
|
|
84
|
+
- `packages/domain/src/integrations/erp.ts`:出站、入站映射和验签。
|
|
85
|
+
- `packages/contracts/src/aggregates/<聚合>`:生成的 SDK;页面统一从 `@app/contracts` 引入。
|
|
55
86
|
- `apps/api/src`:API 和 worker 的薄启动入口。
|
|
56
|
-
- `apps/web/src
|
|
87
|
+
- `apps/web/src/app`、`modules`、`shared`:应用组合、业务页面、共享基础组件;`main.tsx` 只挂载。
|
|
88
|
+
|
|
89
|
+
新增业务先读[工程目录与代码组织](docs/ai/project-structure.md),不要继续在 src 根目录平铺文件。模板已启用模块目录门禁,`cage check` 和 `verify` 会指出目录与依赖越界。
|
|
57
90
|
|
|
58
91
|
先运行 `pnpm cage gen` 再提交契约和迁移草稿;`pnpm cage verify` 检查完整工具链。派生测试遇到无法推断的业务输入会显示跳过,`purchase-order.test.ts` 另外准备真实业务数据覆盖成功审批和约束反例。
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
// 启动入口只装配框架:认证、业务路由和 /admin 都由 createServer 提供。
|
|
2
2
|
// WEB_DIR 在部署镜像中指向 Vite 构建产物;本地由 Vite 独立提供前端。
|
|
3
|
+
// 进程启动只建立服务,不迁移结构、不初始化账号;这些操作由受控 CLI 流程提前完成。
|
|
4
|
+
// 声明中启用的 AI、审批与文件接口由框架挂载,后台事件消费仍需要独立 worker 进程。
|
|
3
5
|
import { createServer } from '@yss123/cage-http';
|
|
4
6
|
import * as domain from '@app/domain';
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
// 默认不接受转发头;部署在代理后时,仅在这里填写实际可信代理的地址或网段。
|
|
9
|
+
const server = createServer({ domain, webDir: process.env.WEB_DIR, title: 'Cage 采购工作台', trustProxy: false });
|
|
10
|
+
// listen 先等待路由、扩展与授权通知初始化;失败直接拒绝顶层启动,不伪装为已就绪。
|
|
7
11
|
await server.listen();
|
|
8
12
|
// 退出时释放数据库池及 LISTEN 连接,部署滚动替换时不会留下旧连接。
|
|
9
13
|
process.once('SIGINT', () => void server.close());
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// API 与 worker 使用相同声明。worker 专门处理审批启动、异步反应和 ERP 推送。
|
|
2
|
+
// 两个进程部署同一版本,消费者依据声明发现工作;事件提交成功不等于这些后台动作已经完成。
|
|
2
3
|
import { startWorker } from '@yss123/cage-http/worker';
|
|
3
4
|
import { fakeConnector, stage } from '@yss123/cage-connectors';
|
|
4
5
|
import * as domain from '@app/domain';
|
|
@@ -9,6 +10,8 @@ if (stage() === 'fake') {
|
|
|
9
10
|
pushOrder: (request) => ({ erpNo: `DEMO-${request.externalId.slice(0, 8)}` }),
|
|
10
11
|
});
|
|
11
12
|
}
|
|
13
|
+
// 框架拥有轮询、重试、调度和连接生命周期;应用只注册本地 fake,不另建数据库池或业务重试循环。
|
|
12
14
|
const worker = await startWorker({ domain });
|
|
15
|
+
// 停止句柄等待框架在途工作收尾并释放连接,避免进程退出时留下仍在续租的消费者。
|
|
13
16
|
process.once('SIGINT', () => void worker.stop());
|
|
14
17
|
process.once('SIGTERM', () => void worker.stop());
|
|
@@ -10,13 +10,17 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@app/contracts": "workspace:*",
|
|
12
12
|
"@tanstack/react-query": "^5.87.1",
|
|
13
|
+
"@yss123/cage-client": "0.3.0",
|
|
13
14
|
"react": "^19.1.1",
|
|
14
|
-
"react-dom": "^19.1.1"
|
|
15
|
+
"react-dom": "^19.1.1",
|
|
16
|
+
"react-markdown": "^10.1.0",
|
|
17
|
+
"react-router-dom": "^7.18.5",
|
|
18
|
+
"remark-gfm": "^4.0.1"
|
|
15
19
|
},
|
|
16
20
|
"devDependencies": {
|
|
17
21
|
"@types/react": "^19.1.13",
|
|
18
22
|
"@types/react-dom": "^19.1.9",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
23
|
+
"typescript": "~5.9.3",
|
|
24
|
+
"vite": "^7.1.4"
|
|
21
25
|
}
|
|
22
26
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 采购应用的路由组合层,集中连接认证、工作台、采购、库存和审批模块的公开入口。
|
|
3
|
+
* 会话先恢复,再决定展示页面、跳转登录或保留原地址提示网络故障。
|
|
4
|
+
* 页面身份来自 URL,模块间导航通过 app 注入;前端能力守卫不能代替服务端授权。
|
|
5
|
+
*/
|
|
6
|
+
// URL 是页面身份;应用壳只组合路由、会话与模块,不用组件状态模拟多页面导航。
|
|
7
|
+
import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom';
|
|
8
|
+
import { LoginPage } from '../modules/auth';
|
|
9
|
+
import { HomePage } from '../modules/workspace';
|
|
10
|
+
import { PurchaseOrdersPage, PurchaseOrderDetailPage } from '../modules/purchase';
|
|
11
|
+
import { InventoryPage } from '../modules/inventory';
|
|
12
|
+
import { ApprovalTasksPage, useApprovalTasks } from '../modules/approval';
|
|
13
|
+
import { PageState } from '../shared/ui/page-state';
|
|
14
|
+
import { RequireCapability } from '../shared/ui/require-capability';
|
|
15
|
+
import { loginReturnTo } from '../shared/lib/navigation';
|
|
16
|
+
import { useSession } from './use-session';
|
|
17
|
+
import { WorkspaceLayout } from './workspace-layout';
|
|
18
|
+
|
|
19
|
+
const home = '/workspace';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 安装 BrowserRouter 并渲染路由树。部署方需为业务深链接提供 SPA 回退,/api 和 /admin 由各自服务处理。
|
|
23
|
+
*/
|
|
24
|
+
export function App() {
|
|
25
|
+
return (
|
|
26
|
+
<BrowserRouter>
|
|
27
|
+
<AppRoutes />
|
|
28
|
+
</BrowserRouter>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 在组合层读取审批待办数量并传给采购列表,使采购模块不依赖审批页面的内部实现。
|
|
34
|
+
* 待办尚未加载或失败时允许数量缺省,页面显示未知而不伪造零。
|
|
35
|
+
*/
|
|
36
|
+
function OrdersRoute() {
|
|
37
|
+
const tasks = useApprovalTasks();
|
|
38
|
+
return <PurchaseOrdersPage pendingTasks={tasks.data?.length} />;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 根据 useSession 的 loading/guest/ready/error 状态组装路由。
|
|
43
|
+
* guest 使用完整路径、查询参数和 hash 构造 returnTo;ready 经 loginReturnTo 校验后回跳。
|
|
44
|
+
* 网络错误保持当前地址以便重试;未知业务地址展示 404 页面,记录读取错误由各页面处理。
|
|
45
|
+
*/
|
|
46
|
+
function AppRoutes() {
|
|
47
|
+
const { session, restore, onLogin, onLogout } = useSession();
|
|
48
|
+
const location = useLocation();
|
|
49
|
+
if (session === 'loading')
|
|
50
|
+
return (
|
|
51
|
+
<div className="loading" role="status">
|
|
52
|
+
正在连接工作台…
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
if (session === 'error')
|
|
56
|
+
return (
|
|
57
|
+
<PageState
|
|
58
|
+
title="暂时无法连接工作台"
|
|
59
|
+
description="请检查网络和 API 服务,重试后继续访问当前地址。"
|
|
60
|
+
to={home}
|
|
61
|
+
label="返回工作台"
|
|
62
|
+
>
|
|
63
|
+
<button onClick={restore}>重新连接</button>
|
|
64
|
+
</PageState>
|
|
65
|
+
);
|
|
66
|
+
const login = `/login?returnTo=${encodeURIComponent(location.pathname + location.search + location.hash)}`;
|
|
67
|
+
return (
|
|
68
|
+
<Routes>
|
|
69
|
+
<Route
|
|
70
|
+
path="/login"
|
|
71
|
+
element={
|
|
72
|
+
session === 'ready' ? (
|
|
73
|
+
<Navigate to={loginReturnTo(location.search, home)} replace />
|
|
74
|
+
) : (
|
|
75
|
+
<LoginPage onLogin={onLogin} />
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
/>
|
|
79
|
+
<Route
|
|
80
|
+
element={
|
|
81
|
+
session === 'ready' ? <WorkspaceLayout onLogout={onLogout} /> : <Navigate to={login} replace />
|
|
82
|
+
}
|
|
83
|
+
>
|
|
84
|
+
<Route index element={<Navigate to={home} replace />} />
|
|
85
|
+
<Route path="workspace" element={<HomePage />} />
|
|
86
|
+
<Route
|
|
87
|
+
path="procurement/orders"
|
|
88
|
+
element={
|
|
89
|
+
<RequireCapability capability="PurchaseOrder.read" home={home}>
|
|
90
|
+
<OrdersRoute />
|
|
91
|
+
</RequireCapability>
|
|
92
|
+
}
|
|
93
|
+
/>
|
|
94
|
+
<Route
|
|
95
|
+
path="procurement/orders/:id"
|
|
96
|
+
element={
|
|
97
|
+
<RequireCapability capability="PurchaseOrder.read" home={home}>
|
|
98
|
+
<PurchaseOrderDetailPage />
|
|
99
|
+
</RequireCapability>
|
|
100
|
+
}
|
|
101
|
+
/>
|
|
102
|
+
<Route
|
|
103
|
+
path="inventory"
|
|
104
|
+
element={
|
|
105
|
+
<RequireCapability capability="Inventory.read" home={home}>
|
|
106
|
+
<InventoryPage />
|
|
107
|
+
</RequireCapability>
|
|
108
|
+
}
|
|
109
|
+
/>
|
|
110
|
+
<Route
|
|
111
|
+
path="approvals"
|
|
112
|
+
element={<ApprovalTasksPage orderUrl={(id) => `/procurement/orders/${encodeURIComponent(id)}`} />}
|
|
113
|
+
/>
|
|
114
|
+
<Route
|
|
115
|
+
path="*"
|
|
116
|
+
element={
|
|
117
|
+
<PageState
|
|
118
|
+
title="页面不存在"
|
|
119
|
+
description="请检查地址,或从工作台导航进入已有页面。"
|
|
120
|
+
to={home}
|
|
121
|
+
label="返回工作台"
|
|
122
|
+
/>
|
|
123
|
+
}
|
|
124
|
+
/>
|
|
125
|
+
</Route>
|
|
126
|
+
</Routes>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 采购应用的全局视觉与布局基础,随浏览器入口加载;依次定义主题、工作台、业务表格、表单及登录页。
|
|
3
|
+
* 模块专用样式在模块附近维护。状态类只映射已有 UI 状态,不承担权限、审批或数据计算。
|
|
4
|
+
*/
|
|
1
5
|
/* 暖白纸面配墨绿导航;用边线、字重和留白建立信息层次,避免装饰压过业务数据。 */
|
|
2
6
|
:root {
|
|
3
7
|
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
|
@@ -83,6 +87,9 @@ h3 {
|
|
|
83
87
|
font-family: Consolas, 'Courier New', monospace;
|
|
84
88
|
font-size: 12px;
|
|
85
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* 固定侧栏与主内容区的桌面组合;窄屏规则在文件后部覆盖布局,保留导航可达性。
|
|
92
|
+
*/
|
|
86
93
|
.workspace {
|
|
87
94
|
display: flex;
|
|
88
95
|
min-height: 100vh;
|
|
@@ -124,7 +131,7 @@ nav {
|
|
|
124
131
|
display: grid;
|
|
125
132
|
gap: 7px;
|
|
126
133
|
}
|
|
127
|
-
nav
|
|
134
|
+
nav a {
|
|
128
135
|
display: flex;
|
|
129
136
|
align-items: center;
|
|
130
137
|
gap: 16px;
|
|
@@ -134,22 +141,22 @@ nav button {
|
|
|
134
141
|
text-align: left;
|
|
135
142
|
padding: 14px 13px;
|
|
136
143
|
}
|
|
137
|
-
nav
|
|
144
|
+
nav a span {
|
|
138
145
|
font-size: 10px;
|
|
139
146
|
opacity: 0.6;
|
|
140
147
|
}
|
|
141
|
-
nav
|
|
148
|
+
nav a b {
|
|
142
149
|
margin-left: auto;
|
|
143
150
|
font-size: 11px;
|
|
144
151
|
}
|
|
145
|
-
nav
|
|
152
|
+
nav a.selected {
|
|
146
153
|
background: var(--accent);
|
|
147
154
|
color: var(--green);
|
|
148
155
|
}
|
|
149
|
-
nav
|
|
156
|
+
nav a:hover {
|
|
150
157
|
background: #31594e;
|
|
151
158
|
}
|
|
152
|
-
nav
|
|
159
|
+
nav a.selected:hover {
|
|
153
160
|
background: #d9efa9;
|
|
154
161
|
}
|
|
155
162
|
.aside-bottom {
|
|
@@ -301,6 +308,9 @@ header {
|
|
|
301
308
|
.toolbar > button {
|
|
302
309
|
font-size: 11px;
|
|
303
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* 宽表格在容器中横向滚动,避免列内容把页面宽度撑出视口。
|
|
313
|
+
*/
|
|
304
314
|
.table-wrap {
|
|
305
315
|
overflow: auto;
|
|
306
316
|
}
|
|
@@ -470,6 +480,9 @@ input {
|
|
|
470
480
|
input:focus {
|
|
471
481
|
outline: 2px solid #b2cb8b;
|
|
472
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* 创建弹窗的遮罩与居中层;具体采购弹窗高度及内部滚动由模块样式补充。
|
|
485
|
+
*/
|
|
473
486
|
.modal-backdrop {
|
|
474
487
|
position: fixed;
|
|
475
488
|
inset: 0;
|
|
@@ -560,6 +573,9 @@ input:focus {
|
|
|
560
573
|
color: var(--muted);
|
|
561
574
|
}
|
|
562
575
|
/* 窄屏将导航转成横向工具栏,表格保留横向滚动,操作列不会挤成不可点击的小按钮。 */
|
|
576
|
+
/**
|
|
577
|
+
* 在九百像素及以下调整导航与表单布局,减少桌面侧栏对内容宽度的挤占。
|
|
578
|
+
*/
|
|
563
579
|
@media (max-width: 900px) {
|
|
564
580
|
aside {
|
|
565
581
|
position: static;
|
|
@@ -581,11 +597,11 @@ input:focus {
|
|
|
581
597
|
display: flex;
|
|
582
598
|
margin-top: 20px;
|
|
583
599
|
}
|
|
584
|
-
nav
|
|
600
|
+
nav a {
|
|
585
601
|
flex: 1;
|
|
586
602
|
padding: 10px;
|
|
587
603
|
}
|
|
588
|
-
nav
|
|
604
|
+
nav a span {
|
|
589
605
|
display: none;
|
|
590
606
|
}
|
|
591
607
|
.aside-bottom {
|
|
@@ -656,8 +672,72 @@ input:focus {
|
|
|
656
672
|
padding: 10px;
|
|
657
673
|
}
|
|
658
674
|
}
|
|
675
|
+
/**
|
|
676
|
+
* 尊重系统减少动画偏好,避免将过渡效果作为理解操作反馈的唯一依据。
|
|
677
|
+
*/
|
|
659
678
|
@media (prefers-reduced-motion: reduce) {
|
|
660
679
|
* {
|
|
661
680
|
transition: none !important;
|
|
662
681
|
}
|
|
663
682
|
}
|
|
683
|
+
|
|
684
|
+
/* 链接保持原生导航语义,单据编号可复制地址或在新标签页打开。 */
|
|
685
|
+
.record-link {
|
|
686
|
+
color: var(--green);
|
|
687
|
+
font-weight: 600;
|
|
688
|
+
text-decoration: underline;
|
|
689
|
+
text-decoration-color: #c6d5b5;
|
|
690
|
+
text-underline-offset: 4px;
|
|
691
|
+
}
|
|
692
|
+
.record-link:hover {
|
|
693
|
+
text-decoration-color: var(--green);
|
|
694
|
+
}
|
|
695
|
+
.record-facts {
|
|
696
|
+
display: grid;
|
|
697
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
698
|
+
margin: 0;
|
|
699
|
+
padding: 8px 24px;
|
|
700
|
+
gap: 0 36px;
|
|
701
|
+
}
|
|
702
|
+
.record-facts > div {
|
|
703
|
+
padding: 22px 0;
|
|
704
|
+
border-bottom: 1px solid var(--line);
|
|
705
|
+
}
|
|
706
|
+
.record-facts dt {
|
|
707
|
+
color: var(--muted);
|
|
708
|
+
font-size: 11px;
|
|
709
|
+
margin-bottom: 11px;
|
|
710
|
+
}
|
|
711
|
+
.record-facts dd {
|
|
712
|
+
margin: 0;
|
|
713
|
+
font-size: 14px;
|
|
714
|
+
overflow-wrap: anywhere;
|
|
715
|
+
}
|
|
716
|
+
.entry-grid {
|
|
717
|
+
display: grid;
|
|
718
|
+
grid-template-columns: repeat(3, 1fr);
|
|
719
|
+
gap: 18px;
|
|
720
|
+
}
|
|
721
|
+
.entry-grid > a {
|
|
722
|
+
padding: 30px 25px;
|
|
723
|
+
background: #fff;
|
|
724
|
+
border: 1px solid var(--line);
|
|
725
|
+
border-radius: 6px;
|
|
726
|
+
}
|
|
727
|
+
.entry-grid > a:hover {
|
|
728
|
+
border-color: #99b47f;
|
|
729
|
+
background: #fafdf6;
|
|
730
|
+
}
|
|
731
|
+
.entry-grid small {
|
|
732
|
+
color: var(--muted);
|
|
733
|
+
font-size: 10px;
|
|
734
|
+
letter-spacing: 1px;
|
|
735
|
+
}
|
|
736
|
+
.entry-grid h2 {
|
|
737
|
+
margin: 24px 0 14px;
|
|
738
|
+
}
|
|
739
|
+
.entry-grid p {
|
|
740
|
+
font-size: 12px;
|
|
741
|
+
color: var(--muted);
|
|
742
|
+
line-height: 1.8;
|
|
743
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 应用会话生命周期:首次加载 /me,并把 SDK 的账号退出或失效通知同步到路由状态。
|
|
3
|
+
* 与 URL 路由分离,网络故障不会被误判成未登录;查询缓存不能跨账号继续使用。
|
|
4
|
+
*/
|
|
5
|
+
// 应用会话与 URL 导航分别管理:401 才进入登录,网络故障保留原地址并允许重试。
|
|
6
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
7
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
8
|
+
import { client, loadMe } from '@app/contracts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 在 QueryClientProvider 内使用。挂载时恢复用户,卸载时解除 SDK 订阅。
|
|
12
|
+
* 返回 session:loading 为恢复中,guest 为未认证,ready 为已加载身份,error 为其他恢复失败。
|
|
13
|
+
* restore 可重试恢复;onLogin/onLogout 由已完成认证动作的页面调用,只更新应用状态。
|
|
14
|
+
* 账号失效时发起取消查询并清空缓存;这里不负责服务端退出操作,也不保证取消已提交的业务命令。
|
|
15
|
+
*/
|
|
16
|
+
export function useSession() {
|
|
17
|
+
const [session, setSession] = useState<'loading' | 'guest' | 'ready' | 'error'>('loading');
|
|
18
|
+
const cache = useQueryClient();
|
|
19
|
+
/**
|
|
20
|
+
* 每次恢复先显示 loading,再按 loadMe 的明确结果分类;只有 UNAUTHENTICATED 进入 guest。
|
|
21
|
+
*/
|
|
22
|
+
const restore = useCallback(async () => {
|
|
23
|
+
setSession('loading');
|
|
24
|
+
const result = await loadMe();
|
|
25
|
+
setSession(result.ok ? 'ready' : result.code === 'UNAUTHENTICATED' ? 'guest' : 'error');
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const unsubscribe = client.subscribe((_snapshot, reason) => {
|
|
30
|
+
if (reason === 'loaded') return;
|
|
31
|
+
// 先取消在途查询,再清除上一账号的缓存;路由守卫保留 URL 并决定登录回跳。
|
|
32
|
+
void cache.cancelQueries();
|
|
33
|
+
cache.clear();
|
|
34
|
+
setSession('guest');
|
|
35
|
+
});
|
|
36
|
+
void restore();
|
|
37
|
+
return () => {
|
|
38
|
+
unsubscribe();
|
|
39
|
+
};
|
|
40
|
+
}, [cache, restore]);
|
|
41
|
+
|
|
42
|
+
return { session, restore, onLogin: () => setSession('ready'), onLogout: () => setSession('guest') };
|
|
43
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 已登录工作台的公共外壳:导航、当前账号、退出登录、Outlet 和唯一的业务助理。
|
|
3
|
+
* 业务页面经路由模块入口进入 Outlet;系统管理使用独立链接。
|
|
4
|
+
* 助理随页面更新语义快照,账号退出成功后清空查询缓存。
|
|
5
|
+
*/
|
|
6
|
+
// 应用壳组合模块公开入口,只持有导航和会话;表单、筛选、命令留在各业务模块。
|
|
7
|
+
import { useState } from 'react';
|
|
8
|
+
import { Link, NavLink, Outlet, useLocation } from 'react-router-dom';
|
|
9
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
10
|
+
import { client, currentUser } from '@app/contracts';
|
|
11
|
+
import { useApprovalTasks } from '../modules/approval';
|
|
12
|
+
import { errorMessage } from '../shared/lib/error-message';
|
|
13
|
+
import { AssistantScope } from '../shared/ui/assistant-scope';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 渲染工作台公共区域并把子路由放入内容区。
|
|
17
|
+
* @param onLogout SDK 退出成功后通知 app 切换会话状态的回调。
|
|
18
|
+
* 本壳提供固定导航入口;目标路由和服务端分别处理页面访问与真实请求的权限。
|
|
19
|
+
* location.key 标识一次页面导航,用于防止新页面沿用上一张单据的助理上下文。
|
|
20
|
+
*/
|
|
21
|
+
export function WorkspaceLayout({ onLogout }: { onLogout: () => void }) {
|
|
22
|
+
const [error, setError] = useState('');
|
|
23
|
+
const [busy, setBusy] = useState(false);
|
|
24
|
+
const location = useLocation();
|
|
25
|
+
const page = location.pathname.startsWith('/procurement/orders/')
|
|
26
|
+
? '采购单详情'
|
|
27
|
+
: location.pathname === '/procurement/orders'
|
|
28
|
+
? '采购单'
|
|
29
|
+
: location.pathname === '/approvals'
|
|
30
|
+
? '审批待办'
|
|
31
|
+
: location.pathname === '/inventory'
|
|
32
|
+
? '库存台账'
|
|
33
|
+
: location.pathname === '/workspace'
|
|
34
|
+
? '工作台'
|
|
35
|
+
: '页面';
|
|
36
|
+
const tasks = useApprovalTasks();
|
|
37
|
+
const cache = useQueryClient();
|
|
38
|
+
return (
|
|
39
|
+
<AssistantScope pageKey={location.key} fallback={{
|
|
40
|
+
context: { page: { id: 'workspace-page', title: page, kind: 'custom', route: location.pathname + location.search } },
|
|
41
|
+
suggestions: ['我在当前页面可以做什么?', '帮我查看待处理的审批'],
|
|
42
|
+
}}>
|
|
43
|
+
<div className="workspace">
|
|
44
|
+
<aside>
|
|
45
|
+
<Link className="brand" to="/workspace">
|
|
46
|
+
cage<span>采购工作台</span>
|
|
47
|
+
</Link>
|
|
48
|
+
<span className="nav-caption">工作空间</span>
|
|
49
|
+
<nav>
|
|
50
|
+
{(
|
|
51
|
+
[
|
|
52
|
+
['/workspace', '00', '工作台'],
|
|
53
|
+
['/procurement/orders', '01', '采购单'],
|
|
54
|
+
['/approvals', '02', '审批待办'],
|
|
55
|
+
['/inventory', '03', '库存台账'],
|
|
56
|
+
] as const
|
|
57
|
+
).map(([key, no, label]) => (
|
|
58
|
+
<NavLink key={key} to={key} className={({ isActive }) => (isActive ? 'selected' : '')}>
|
|
59
|
+
<span>{no}</span>
|
|
60
|
+
{label}
|
|
61
|
+
{key === '/approvals' && <b>{tasks.data?.length ?? 0}</b>}
|
|
62
|
+
</NavLink>
|
|
63
|
+
))}
|
|
64
|
+
</nav>
|
|
65
|
+
<div className="aside-bottom">
|
|
66
|
+
<a href="/admin/">系统管理 ↗</a>
|
|
67
|
+
<div className="user">
|
|
68
|
+
<span className="avatar">{currentUser()?.name?.slice(0, 1) ?? '用'}</span>
|
|
69
|
+
<div>
|
|
70
|
+
{currentUser()?.name}
|
|
71
|
+
<small>已登录</small>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<button
|
|
75
|
+
className="logout"
|
|
76
|
+
disabled={busy}
|
|
77
|
+
onClick={async () => {
|
|
78
|
+
setBusy(true);
|
|
79
|
+
const result = await client.logout();
|
|
80
|
+
setBusy(false);
|
|
81
|
+
if (result.ok) {
|
|
82
|
+
cache.clear();
|
|
83
|
+
onLogout();
|
|
84
|
+
} else setError(errorMessage(result));
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
退出登录
|
|
88
|
+
</button>
|
|
89
|
+
</div>
|
|
90
|
+
</aside>
|
|
91
|
+
<main className="content">
|
|
92
|
+
<header>
|
|
93
|
+
<span>采购管理 / {page}</span>
|
|
94
|
+
<span className="live-dot">团队工作空间</span>
|
|
95
|
+
</header>
|
|
96
|
+
{error && (
|
|
97
|
+
<p className="error" role="alert">
|
|
98
|
+
{error}
|
|
99
|
+
</p>
|
|
100
|
+
)}
|
|
101
|
+
<Outlet />
|
|
102
|
+
<div className="page-footer">
|
|
103
|
+
CAGE / PROCUREMENT WORKSPACE<span>业务操作均受权限与数据范围约束</span>
|
|
104
|
+
</div>
|
|
105
|
+
</main>
|
|
106
|
+
</div>
|
|
107
|
+
</AssistantScope>
|
|
108
|
+
);
|
|
109
|
+
}
|