create-windy 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -0
- package/assets/LICENSE-Apache-2.0.txt +201 -0
- package/dist/cli.js +1662 -0
- package/package.json +37 -0
- package/template/.dockerignore +11 -0
- package/template/.oxfmtrc.json +9 -0
- package/template/.oxlintrc.json +119 -0
- package/template/.windy-template.json +71 -0
- package/template/AGENTS.md +87 -0
- package/template/README.md +128 -0
- package/template/apps/server/Dockerfile +34 -0
- package/template/apps/server/package.json +30 -0
- package/template/apps/server/src/access-guards.ts +112 -0
- package/template/apps/server/src/admin/routes.test.ts +105 -0
- package/template/apps/server/src/admin/routes.ts +95 -0
- package/template/apps/server/src/agent/data-scope-routes.test.ts +143 -0
- package/template/apps/server/src/agent/routes.test.ts +244 -0
- package/template/apps/server/src/agent/routes.ts +257 -0
- package/template/apps/server/src/api-app.ts +32 -0
- package/template/apps/server/src/application-services.ts +154 -0
- package/template/apps/server/src/audit/contracts.ts +21 -0
- package/template/apps/server/src/audit/drizzle-log-store.ts +150 -0
- package/template/apps/server/src/audit/policy.ts +18 -0
- package/template/apps/server/src/audit/recovery-queue.test.ts +42 -0
- package/template/apps/server/src/audit/recovery-queue.ts +63 -0
- package/template/apps/server/src/audit/redaction.ts +55 -0
- package/template/apps/server/src/audit/reliable-writer.test.ts +200 -0
- package/template/apps/server/src/audit/reliable-writer.ts +201 -0
- package/template/apps/server/src/audit/search-summary.ts +32 -0
- package/template/apps/server/src/auth/actor-resolver.test.ts +138 -0
- package/template/apps/server/src/auth/actor-resolver.ts +109 -0
- package/template/apps/server/src/auth/authentication-provider.test.ts +180 -0
- package/template/apps/server/src/auth/authentication-provider.ts +117 -0
- package/template/apps/server/src/auth/authorization-snapshot.test.ts +117 -0
- package/template/apps/server/src/auth/authorization-snapshot.ts +98 -0
- package/template/apps/server/src/auth/bearer-token.ts +5 -0
- package/template/apps/server/src/auth/bootstrap-admin.ts +33 -0
- package/template/apps/server/src/auth/credential-restriction.ts +29 -0
- package/template/apps/server/src/auth/credential-routes.test.ts +190 -0
- package/template/apps/server/src/auth/credential-service.ts +165 -0
- package/template/apps/server/src/auth/development-bypass.ts +22 -0
- package/template/apps/server/src/auth/drizzle-repository.ts +315 -0
- package/template/apps/server/src/auth/drizzle-session-operations.ts +119 -0
- package/template/apps/server/src/auth/login-routes.ts +121 -0
- package/template/apps/server/src/auth/own-session-routes.test.ts +248 -0
- package/template/apps/server/src/auth/own-session-routes.ts +110 -0
- package/template/apps/server/src/auth/password.test.ts +30 -0
- package/template/apps/server/src/auth/password.ts +46 -0
- package/template/apps/server/src/auth/repository.test.ts +61 -0
- package/template/apps/server/src/auth/repository.ts +305 -0
- package/template/apps/server/src/auth/routes.test.ts +350 -0
- package/template/apps/server/src/auth/routes.ts +237 -0
- package/template/apps/server/src/auth/runtime.ts +20 -0
- package/template/apps/server/src/auth/service.ts +329 -0
- package/template/apps/server/src/auth/session-service.ts +123 -0
- package/template/apps/server/src/background/task-guard.test.ts +66 -0
- package/template/apps/server/src/background/task-guard.ts +49 -0
- package/template/apps/server/src/bulk-data/artifact-store.ts +82 -0
- package/template/apps/server/src/bulk-data/dictionary-handler.ts +122 -0
- package/template/apps/server/src/bulk-data/drizzle-repository.integration.test.ts +156 -0
- package/template/apps/server/src/bulk-data/drizzle-repository.ts +298 -0
- package/template/apps/server/src/bulk-data/helpers.ts +36 -0
- package/template/apps/server/src/bulk-data/input-validation.ts +99 -0
- package/template/apps/server/src/bulk-data/repository.ts +246 -0
- package/template/apps/server/src/bulk-data/resource-handler.ts +27 -0
- package/template/apps/server/src/bulk-data/routes.test.ts +169 -0
- package/template/apps/server/src/bulk-data/routes.ts +248 -0
- package/template/apps/server/src/bulk-data/scheduler-integration.test.ts +142 -0
- package/template/apps/server/src/bulk-data/service.test.ts +347 -0
- package/template/apps/server/src/bulk-data/service.ts +319 -0
- package/template/apps/server/src/bulk-data/types.ts +73 -0
- package/template/apps/server/src/configuration/bootstrap.ts +59 -0
- package/template/apps/server/src/configuration/definition.ts +89 -0
- package/template/apps/server/src/configuration/drizzle-repository.ts +166 -0
- package/template/apps/server/src/configuration/repository.ts +138 -0
- package/template/apps/server/src/configuration/routes.test.ts +178 -0
- package/template/apps/server/src/configuration/routes.ts +260 -0
- package/template/apps/server/src/configuration/service.test.ts +128 -0
- package/template/apps/server/src/configuration/service.ts +187 -0
- package/template/apps/server/src/data-access/context.ts +162 -0
- package/template/apps/server/src/data-access/department-tree.ts +27 -0
- package/template/apps/server/src/data-access/drizzle-predicate.test.ts +86 -0
- package/template/apps/server/src/data-access/drizzle-predicate.ts +50 -0
- package/template/apps/server/src/data-access/errors.ts +5 -0
- package/template/apps/server/src/data-access/platform-actor.ts +25 -0
- package/template/apps/server/src/data-access/query-specification.test.ts +82 -0
- package/template/apps/server/src/data-access/query-specification.ts +77 -0
- package/template/apps/server/src/data-access/scoped-repository.integration.test.ts +203 -0
- package/template/apps/server/src/data-access/scoped-repository.ts +268 -0
- package/template/apps/server/src/data-access/scoped-resource.test.ts +158 -0
- package/template/apps/server/src/data-access/scoped-resource.ts +141 -0
- package/template/apps/server/src/data-governance/export/approval-port.ts +84 -0
- package/template/apps/server/src/data-governance/export/authorization-port.test.ts +103 -0
- package/template/apps/server/src/data-governance/export/authorization-port.ts +69 -0
- package/template/apps/server/src/data-governance/export/drizzle-repository.integration.test.ts +88 -0
- package/template/apps/server/src/data-governance/export/drizzle-repository.ts +97 -0
- package/template/apps/server/src/data-governance/export/job-runtime.test.ts +339 -0
- package/template/apps/server/src/data-governance/export/job-runtime.ts +242 -0
- package/template/apps/server/src/data-governance/export/ndjson-stream.ts +62 -0
- package/template/apps/server/src/data-governance/export/postgres-api-actors.ts +140 -0
- package/template/apps/server/src/data-governance/export/postgres-api-assertions.ts +76 -0
- package/template/apps/server/src/data-governance/export/postgres-api-fixture.ts +265 -0
- package/template/apps/server/src/data-governance/export/postgres-api.integration.test.ts +298 -0
- package/template/apps/server/src/data-governance/export/postgres-recovery.integration.test.ts +344 -0
- package/template/apps/server/src/data-governance/export/repository.test.ts +55 -0
- package/template/apps/server/src/data-governance/export/repository.ts +83 -0
- package/template/apps/server/src/data-governance/export/request-fingerprint.test.ts +51 -0
- package/template/apps/server/src/data-governance/export/request-fingerprint.ts +45 -0
- package/template/apps/server/src/data-governance/export/routes-integrity.test.ts +90 -0
- package/template/apps/server/src/data-governance/export/routes-test-fixture.ts +239 -0
- package/template/apps/server/src/data-governance/export/routes.test.ts +182 -0
- package/template/apps/server/src/data-governance/export/routes.ts +215 -0
- package/template/apps/server/src/data-governance/export/scope-snapshot.test.ts +45 -0
- package/template/apps/server/src/data-governance/export/scope-snapshot.ts +27 -0
- package/template/apps/server/src/data-governance/export/service.ts +337 -0
- package/template/apps/server/src/data-governance/export/source.ts +69 -0
- package/template/apps/server/src/data-governance/export/types.ts +55 -0
- package/template/apps/server/src/data-governance/plaintext-access.test.ts +70 -0
- package/template/apps/server/src/data-governance/plaintext-access.ts +88 -0
- package/template/apps/server/src/data-governance/plaintext-postgres.integration.test.ts +223 -0
- package/template/apps/server/src/data-governance/user-plaintext-routes.test.ts +287 -0
- package/template/apps/server/src/data-governance/user-plaintext-routes.ts +181 -0
- package/template/apps/server/src/data-governance/user-projection.ts +54 -0
- package/template/apps/server/src/data-governance/user-sensitive-read-service.ts +54 -0
- package/template/apps/server/src/example-modules.ts +62 -0
- package/template/apps/server/src/example-permissions.ts +5 -0
- package/template/apps/server/src/feature/manifest-feature-repository.test.ts +187 -0
- package/template/apps/server/src/feature/manifest-feature-repository.ts +200 -0
- package/template/apps/server/src/feature/routes.authorization.test.ts +199 -0
- package/template/apps/server/src/feature/routes.ts +193 -0
- package/template/apps/server/src/foundation-access.test.ts +50 -0
- package/template/apps/server/src/foundation-access.ts +34 -0
- package/template/apps/server/src/foundation-route.ts +55 -0
- package/template/apps/server/src/foundation.ts +85 -0
- package/template/apps/server/src/guards.test.ts +74 -0
- package/template/apps/server/src/guards.ts +214 -0
- package/template/apps/server/src/http-app.test.ts +77 -0
- package/template/apps/server/src/http-app.ts +51 -0
- package/template/apps/server/src/index.ts +374 -0
- package/template/apps/server/src/jobs/artifact-service.test.ts +78 -0
- package/template/apps/server/src/jobs/artifact-service.ts +94 -0
- package/template/apps/server/src/jobs/drizzle-artifact.ts +63 -0
- package/template/apps/server/src/jobs/drizzle-claim.ts +111 -0
- package/template/apps/server/src/jobs/drizzle-execution-repository.ts +299 -0
- package/template/apps/server/src/jobs/drizzle-execution.integration.test.ts +232 -0
- package/template/apps/server/src/jobs/drizzle-lease.ts +21 -0
- package/template/apps/server/src/jobs/drizzle-mappers.ts +121 -0
- package/template/apps/server/src/jobs/drizzle-recovery-repository.ts +214 -0
- package/template/apps/server/src/jobs/drizzle-repository.integration.test.ts +135 -0
- package/template/apps/server/src/jobs/drizzle-repository.ts +268 -0
- package/template/apps/server/src/jobs/execution-repository.ts +72 -0
- package/template/apps/server/src/jobs/execution.test.ts +303 -0
- package/template/apps/server/src/jobs/handler-registry.ts +81 -0
- package/template/apps/server/src/jobs/in-memory-claim.ts +96 -0
- package/template/apps/server/src/jobs/in-memory-execution.ts +336 -0
- package/template/apps/server/src/jobs/in-memory-lease.ts +66 -0
- package/template/apps/server/src/jobs/legacy-adapter.integration.test.ts +177 -0
- package/template/apps/server/src/jobs/legacy-adapter.test.ts +199 -0
- package/template/apps/server/src/jobs/legacy-adapter.ts +109 -0
- package/template/apps/server/src/jobs/legacy-service-runtime.ts +95 -0
- package/template/apps/server/src/jobs/repository.ts +141 -0
- package/template/apps/server/src/jobs/service.test.ts +64 -0
- package/template/apps/server/src/jobs/service.ts +44 -0
- package/template/apps/server/src/jobs/types.ts +180 -0
- package/template/apps/server/src/jobs/worker.ts +258 -0
- package/template/apps/server/src/license/legacy-license-resolver.ts +23 -0
- package/template/apps/server/src/license/license-resolver.test.ts +55 -0
- package/template/apps/server/src/license/license-resolver.ts +122 -0
- package/template/apps/server/src/license/reminder.test.ts +61 -0
- package/template/apps/server/src/license/reminder.ts +33 -0
- package/template/apps/server/src/license/restriction.test.ts +54 -0
- package/template/apps/server/src/license/restriction.ts +80 -0
- package/template/apps/server/src/license/routes-offline-code.test.ts +173 -0
- package/template/apps/server/src/license/routes.ts +99 -0
- package/template/apps/server/src/license/runtime-audit-reliability.test.ts +96 -0
- package/template/apps/server/src/license/runtime-reminder.test.ts +147 -0
- package/template/apps/server/src/license/runtime-service-test-http.ts +28 -0
- package/template/apps/server/src/license/runtime-service.test.ts +334 -0
- package/template/apps/server/src/license/runtime-service.ts +308 -0
- package/template/apps/server/src/module-composition.test.ts +70 -0
- package/template/apps/server/src/module-composition.ts +28 -0
- package/template/apps/server/src/notification/drizzle-repository.ts +233 -0
- package/template/apps/server/src/notification/repository.ts +160 -0
- package/template/apps/server/src/notification/routes.test.ts +151 -0
- package/template/apps/server/src/notification/routes.ts +185 -0
- package/template/apps/server/src/observability/bootstrap.ts +56 -0
- package/template/apps/server/src/observability/http-observability.test.ts +53 -0
- package/template/apps/server/src/observability/http-observability.ts +54 -0
- package/template/apps/server/src/observability/metrics.test.ts +36 -0
- package/template/apps/server/src/observability/metrics.ts +105 -0
- package/template/apps/server/src/observability/readiness.test.ts +36 -0
- package/template/apps/server/src/observability/readiness.ts +43 -0
- package/template/apps/server/src/observability/routes.test.ts +61 -0
- package/template/apps/server/src/observability/routes.ts +44 -0
- package/template/apps/server/src/pagination.ts +31 -0
- package/template/apps/server/src/persistence.integration.test.ts +54 -0
- package/template/apps/server/src/persistence.ts +118 -0
- package/template/apps/server/src/profile/routes.test.ts +190 -0
- package/template/apps/server/src/profile/routes.ts +173 -0
- package/template/apps/server/src/request-restriction.ts +29 -0
- package/template/apps/server/src/route-guards.test.ts +148 -0
- package/template/apps/server/src/route-guards.ts +63 -0
- package/template/apps/server/src/runtime-audit-list.test.ts +98 -0
- package/template/apps/server/src/runtime-config.ts +11 -0
- package/template/apps/server/src/runtime-development.ts +68 -0
- package/template/apps/server/src/runtime-license.ts +50 -0
- package/template/apps/server/src/runtime.test.ts +264 -0
- package/template/apps/server/src/runtime.ts +324 -0
- package/template/apps/server/src/scheduler/audit.ts +38 -0
- package/template/apps/server/src/scheduler/definitions.test.ts +35 -0
- package/template/apps/server/src/scheduler/definitions.ts +79 -0
- package/template/apps/server/src/scheduler/drizzle-durable-links.ts +52 -0
- package/template/apps/server/src/scheduler/drizzle-mappers.ts +36 -0
- package/template/apps/server/src/scheduler/drizzle-repository.integration.test.ts +174 -0
- package/template/apps/server/src/scheduler/drizzle-repository.ts +348 -0
- package/template/apps/server/src/scheduler/execution-context.ts +24 -0
- package/template/apps/server/src/scheduler/execution-recorder.ts +101 -0
- package/template/apps/server/src/scheduler/feature-preflight.ts +40 -0
- package/template/apps/server/src/scheduler/history.ts +22 -0
- package/template/apps/server/src/scheduler/overview.test.ts +89 -0
- package/template/apps/server/src/scheduler/overview.ts +125 -0
- package/template/apps/server/src/scheduler/recovery-conflict.ts +19 -0
- package/template/apps/server/src/scheduler/recovery-service.test.ts +238 -0
- package/template/apps/server/src/scheduler/recovery-service.ts +152 -0
- package/template/apps/server/src/scheduler/repository.ts +274 -0
- package/template/apps/server/src/scheduler/routes.test.ts +347 -0
- package/template/apps/server/src/scheduler/routes.ts +222 -0
- package/template/apps/server/src/scheduler/sensitive-text.ts +20 -0
- package/template/apps/server/src/scheduler/service-idle.test.ts +73 -0
- package/template/apps/server/src/scheduler/service.test.ts +330 -0
- package/template/apps/server/src/scheduler/service.ts +339 -0
- package/template/apps/server/src/scheduler/types.ts +103 -0
- package/template/apps/server/src/scheduler/worker.ts +38 -0
- package/template/apps/server/src/search/config.test.ts +43 -0
- package/template/apps/server/src/search/config.ts +62 -0
- package/template/apps/server/src/search/contracts.ts +127 -0
- package/template/apps/server/src/search/cursor.ts +39 -0
- package/template/apps/server/src/search/errors.ts +11 -0
- package/template/apps/server/src/search/host.ts +36 -0
- package/template/apps/server/src/search/masking.ts +6 -0
- package/template/apps/server/src/search/provider-execution.ts +195 -0
- package/template/apps/server/src/search/rate-limiter.ts +23 -0
- package/template/apps/server/src/search/registry.ts +105 -0
- package/template/apps/server/src/search/routes.test.ts +156 -0
- package/template/apps/server/src/search/routes.ts +95 -0
- package/template/apps/server/src/search/service.test.ts +314 -0
- package/template/apps/server/src/search/service.ts +257 -0
- package/template/apps/server/src/search/test-support.ts +122 -0
- package/template/apps/server/src/session/routes.test.ts +111 -0
- package/template/apps/server/src/session/routes.ts +56 -0
- package/template/apps/server/src/settings/drizzle-repository.ts +66 -0
- package/template/apps/server/src/settings/repository.ts +29 -0
- package/template/apps/server/src/settings/routes.test.ts +250 -0
- package/template/apps/server/src/settings/routes.ts +175 -0
- package/template/apps/server/src/settings/runtime.ts +13 -0
- package/template/apps/server/src/storage/blob-reference-registry.test.ts +25 -0
- package/template/apps/server/src/storage/blob-reference-registry.ts +15 -0
- package/template/apps/server/src/storage/drizzle-upload-repository.integration.test.ts +136 -0
- package/template/apps/server/src/storage/drizzle-upload-repository.ts +248 -0
- package/template/apps/server/src/storage/route-support.ts +84 -0
- package/template/apps/server/src/storage/routes.test.ts +288 -0
- package/template/apps/server/src/storage/routes.ts +297 -0
- package/template/apps/server/src/storage/runtime.ts +86 -0
- package/template/apps/server/src/system/audit-query.ts +17 -0
- package/template/apps/server/src/system/audit-routes.test.ts +139 -0
- package/template/apps/server/src/system/audit-routes.ts +113 -0
- package/template/apps/server/src/system/built-in-roles.ts +116 -0
- package/template/apps/server/src/system/department-routes.test.ts +80 -0
- package/template/apps/server/src/system/department-routes.ts +90 -0
- package/template/apps/server/src/system/drizzle-mapping.ts +53 -0
- package/template/apps/server/src/system/drizzle-repository.ts +298 -0
- package/template/apps/server/src/system/drizzle-scoped-repository.ts +235 -0
- package/template/apps/server/src/system/drizzle-system.ts +361 -0
- package/template/apps/server/src/system/entities.ts +78 -0
- package/template/apps/server/src/system/feature-routes.test.ts +55 -0
- package/template/apps/server/src/system/identity-route-config.ts +73 -0
- package/template/apps/server/src/system/interface-catalog.test.ts +103 -0
- package/template/apps/server/src/system/interface-catalog.ts +82 -0
- package/template/apps/server/src/system/menu-registry.test.ts +125 -0
- package/template/apps/server/src/system/menu-registry.ts +259 -0
- package/template/apps/server/src/system/menu-routes.test.ts +68 -0
- package/template/apps/server/src/system/menu-routes.ts +200 -0
- package/template/apps/server/src/system/mutation-runner.ts +33 -0
- package/template/apps/server/src/system/operation-monitoring.test.ts +78 -0
- package/template/apps/server/src/system/operation-monitoring.ts +233 -0
- package/template/apps/server/src/system/operations.test.ts +269 -0
- package/template/apps/server/src/system/operations.ts +155 -0
- package/template/apps/server/src/system/postgres-monitoring.ts +31 -0
- package/template/apps/server/src/system/redis-health.test.ts +116 -0
- package/template/apps/server/src/system/redis-health.ts +230 -0
- package/template/apps/server/src/system/repository.ts +234 -0
- package/template/apps/server/src/system/resource-access-response.ts +47 -0
- package/template/apps/server/src/system/resource-export-route.ts +64 -0
- package/template/apps/server/src/system/resource-route-support.ts +50 -0
- package/template/apps/server/src/system/response-projection.ts +24 -0
- package/template/apps/server/src/system/route-helpers.ts +104 -0
- package/template/apps/server/src/system/route-test-app.ts +27 -0
- package/template/apps/server/src/system/route-types.ts +52 -0
- package/template/apps/server/src/system/routes-validation.test.ts +61 -0
- package/template/apps/server/src/system/routes.test.ts +311 -0
- package/template/apps/server/src/system/routes.ts +354 -0
- package/template/apps/server/src/system/seed.test.ts +129 -0
- package/template/apps/server/src/system/seed.ts +237 -0
- package/template/apps/server/src/system/user-account-policy.test.ts +158 -0
- package/template/apps/server/src/system/user-account-policy.ts +103 -0
- package/template/apps/server/src/system/user-data-scope.ts +10 -0
- package/template/apps/server/src/system/user-department-validation.ts +17 -0
- package/template/apps/server/src/system/user-projection.test.ts +40 -0
- package/template/apps/server/src/system/user-projection.ts +35 -0
- package/template/apps/server/src/work-order/data-scope.integration.test.ts +171 -0
- package/template/apps/server/src/work-order/drizzle-repository.integration.test.ts +78 -0
- package/template/apps/server/src/work-order/drizzle-repository.ts +67 -0
- package/template/apps/server/src/work-order/foundation-modules.test.ts +85 -0
- package/template/apps/server/src/work-order/repository.ts +46 -0
- package/template/apps/server/src/work-order/routes.test.ts +209 -0
- package/template/apps/server/src/work-order/routes.ts +159 -0
- package/template/apps/server/src/work-order/search-api.test.ts +121 -0
- package/template/apps/server/src/work-order/search-provider.test.ts +201 -0
- package/template/apps/server/src/work-order/search-provider.ts +59 -0
- package/template/apps/server/src/work-order/service.ts +82 -0
- package/template/apps/server/src/work-order/task.test.ts +79 -0
- package/template/apps/server/src/work-order/task.ts +30 -0
- package/template/apps/server/src/workflow/assignee-directory.ts +23 -0
- package/template/apps/server/src/workflow/drizzle-repository.integration.test.ts +213 -0
- package/template/apps/server/src/workflow/drizzle-repository.ts +299 -0
- package/template/apps/server/src/workflow/effects.test.ts +64 -0
- package/template/apps/server/src/workflow/effects.ts +112 -0
- package/template/apps/server/src/workflow/repository.ts +160 -0
- package/template/apps/server/src/workflow/routes.test.ts +256 -0
- package/template/apps/server/src/workflow/routes.ts +249 -0
- package/template/apps/server/src/workflow/service.ts +196 -0
- package/template/apps/server/src/workflow/timeout-runtime.test.ts +96 -0
- package/template/apps/server/src/workflow/timeout-runtime.ts +66 -0
- package/template/apps/server/tsconfig.json +17 -0
- package/template/apps/web/Dockerfile +41 -0
- package/template/apps/web/components.json +24 -0
- package/template/apps/web/dev/dev-identity.ts +58 -0
- package/template/apps/web/dev/dev-port.test.ts +53 -0
- package/template/apps/web/dev/dev-port.ts +68 -0
- package/template/apps/web/dev/start.ts +37 -0
- package/template/apps/web/index.html +14 -0
- package/template/apps/web/package.json +44 -0
- package/template/apps/web/runtime-server.test.ts +86 -0
- package/template/apps/web/runtime-server.ts +143 -0
- package/template/apps/web/server.ts +21 -0
- package/template/apps/web/src/App.vue +22 -0
- package/template/apps/web/src/app/home/HomePage.vue +75 -0
- package/template/apps/web/src/app/home/HomeWelcome.vue +85 -0
- package/template/apps/web/src/app/home/HomeWelcome.webtest.ts +32 -0
- package/template/apps/web/src/app/layouts/AppLayout.vue +10 -0
- package/template/apps/web/src/components/auth/DevelopmentAuthWarning.vue +15 -0
- package/template/apps/web/src/components/auth/LoginForm.vue +80 -0
- package/template/apps/web/src/components/auth/LoginForm.webtest.ts +33 -0
- package/template/apps/web/src/components/auth/PasswordChangeForm.vue +90 -0
- package/template/apps/web/src/components/auth/UserSessionMenu.vue +60 -0
- package/template/apps/web/src/components/auth/UserSessionMenu.webtest.ts +45 -0
- package/template/apps/web/src/components/common/ConfirmDialog.vue +75 -0
- package/template/apps/web/src/components/common/DataPagination.vue +79 -0
- package/template/apps/web/src/components/common/DataPagination.webtest.ts +28 -0
- package/template/apps/web/src/components/common/EmptyState.vue +43 -0
- package/template/apps/web/src/components/common/FormDialog.vue +86 -0
- package/template/apps/web/src/components/common/ModalBody.vue +19 -0
- package/template/apps/web/src/components/common/ModalLayout.webtest.ts +54 -0
- package/template/apps/web/src/components/common/PageError.vue +46 -0
- package/template/apps/web/src/components/common/PageLoading.vue +41 -0
- package/template/apps/web/src/components/common/StatusSummary.vue +37 -0
- package/template/apps/web/src/components/common/UnsavedChangesDialog.vue +60 -0
- package/template/apps/web/src/components/common/UnsavedChangesDialog.webtest.ts +60 -0
- package/template/apps/web/src/components/license/LicenseActivationCodeForm.vue +80 -0
- package/template/apps/web/src/components/license/LicenseExpiryBanner.vue +54 -0
- package/template/apps/web/src/components/license/LicenseFlow.webtest.ts +170 -0
- package/template/apps/web/src/components/license/LicenseStatusCard.vue +95 -0
- package/template/apps/web/src/components/license/LicenseUploadForm.vue +79 -0
- package/template/apps/web/src/components/license/license-display.ts +12 -0
- package/template/apps/web/src/components/ui/alert/Alert.vue +21 -0
- package/template/apps/web/src/components/ui/alert/AlertAction.vue +17 -0
- package/template/apps/web/src/components/ui/alert/AlertDescription.vue +22 -0
- package/template/apps/web/src/components/ui/alert/AlertTitle.vue +22 -0
- package/template/apps/web/src/components/ui/alert/index.ts +25 -0
- package/template/apps/web/src/components/ui/badge/Badge.vue +29 -0
- package/template/apps/web/src/components/ui/badge/index.ts +28 -0
- package/template/apps/web/src/components/ui/breadcrumb/Breadcrumb.vue +18 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +26 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbLink.vue +24 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbList.vue +22 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
- package/template/apps/web/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +23 -0
- package/template/apps/web/src/components/ui/breadcrumb/index.ts +7 -0
- package/template/apps/web/src/components/ui/button/Button.vue +31 -0
- package/template/apps/web/src/components/ui/button/index.ts +42 -0
- package/template/apps/web/src/components/ui/card/Card.vue +29 -0
- package/template/apps/web/src/components/ui/card/CardAction.vue +22 -0
- package/template/apps/web/src/components/ui/card/CardContent.vue +17 -0
- package/template/apps/web/src/components/ui/card/CardDescription.vue +17 -0
- package/template/apps/web/src/components/ui/card/CardFooter.vue +22 -0
- package/template/apps/web/src/components/ui/card/CardHeader.vue +22 -0
- package/template/apps/web/src/components/ui/card/CardTitle.vue +22 -0
- package/template/apps/web/src/components/ui/card/index.ts +7 -0
- package/template/apps/web/src/components/ui/checkbox/Checkbox.vue +41 -0
- package/template/apps/web/src/components/ui/checkbox/index.ts +1 -0
- package/template/apps/web/src/components/ui/dialog/Dialog.vue +15 -0
- package/template/apps/web/src/components/ui/dialog/DialogClose.vue +12 -0
- package/template/apps/web/src/components/ui/dialog/DialogContent.vue +62 -0
- package/template/apps/web/src/components/ui/dialog/DialogDescription.vue +30 -0
- package/template/apps/web/src/components/ui/dialog/DialogFooter.vue +33 -0
- package/template/apps/web/src/components/ui/dialog/DialogHeader.vue +17 -0
- package/template/apps/web/src/components/ui/dialog/DialogOverlay.vue +28 -0
- package/template/apps/web/src/components/ui/dialog/DialogScrollContent.vue +67 -0
- package/template/apps/web/src/components/ui/dialog/DialogTitle.vue +27 -0
- package/template/apps/web/src/components/ui/dialog/DialogTrigger.vue +12 -0
- package/template/apps/web/src/components/ui/dialog/index.ts +10 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +50 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuContent.vue +48 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +30 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +51 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +22 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +34 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +36 -0
- package/template/apps/web/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
- package/template/apps/web/src/components/ui/dropdown-menu/index.ts +16 -0
- package/template/apps/web/src/components/ui/input/Input.vue +33 -0
- package/template/apps/web/src/components/ui/input/index.ts +1 -0
- package/template/apps/web/src/components/ui/select/Select.vue +15 -0
- package/template/apps/web/src/components/ui/select/SelectContent.vue +61 -0
- package/template/apps/web/src/components/ui/select/SelectGroup.vue +23 -0
- package/template/apps/web/src/components/ui/select/SelectItem.vue +49 -0
- package/template/apps/web/src/components/ui/select/SelectItemText.vue +12 -0
- package/template/apps/web/src/components/ui/select/SelectLabel.vue +19 -0
- package/template/apps/web/src/components/ui/select/SelectScrollDownButton.vue +34 -0
- package/template/apps/web/src/components/ui/select/SelectScrollUpButton.vue +34 -0
- package/template/apps/web/src/components/ui/select/SelectSeparator.vue +21 -0
- package/template/apps/web/src/components/ui/select/SelectTrigger.vue +43 -0
- package/template/apps/web/src/components/ui/select/SelectValue.vue +12 -0
- package/template/apps/web/src/components/ui/select/index.ts +11 -0
- package/template/apps/web/src/components/ui/separator/Separator.vue +30 -0
- package/template/apps/web/src/components/ui/separator/index.ts +1 -0
- package/template/apps/web/src/components/ui/sheet/Sheet.vue +15 -0
- package/template/apps/web/src/components/ui/sheet/SheetClose.vue +12 -0
- package/template/apps/web/src/components/ui/sheet/SheetContent.vue +62 -0
- package/template/apps/web/src/components/ui/sheet/SheetDescription.vue +23 -0
- package/template/apps/web/src/components/ui/sheet/SheetFooter.vue +15 -0
- package/template/apps/web/src/components/ui/sheet/SheetHeader.vue +15 -0
- package/template/apps/web/src/components/ui/sheet/SheetOverlay.vue +28 -0
- package/template/apps/web/src/components/ui/sheet/SheetTitle.vue +25 -0
- package/template/apps/web/src/components/ui/sheet/SheetTrigger.vue +12 -0
- package/template/apps/web/src/components/ui/sheet/index.ts +8 -0
- package/template/apps/web/src/components/ui/sidebar/Sidebar.vue +114 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarContent.vue +23 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarFooter.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarGroup.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarGroupAction.vue +29 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarGroupContent.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarGroupLabel.vue +29 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarHeader.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarInput.vue +19 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarInset.vue +22 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenu.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuAction.vue +37 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuBadge.vue +23 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuButton.vue +60 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuItem.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuSub.vue +23 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuSubButton.vue +39 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarProvider.vue +128 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarRail.vue +94 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarSeparator.vue +19 -0
- package/template/apps/web/src/components/ui/sidebar/SidebarTrigger.vue +28 -0
- package/template/apps/web/src/components/ui/sidebar/index.ts +62 -0
- package/template/apps/web/src/components/ui/sidebar/sidebar-width.ts +29 -0
- package/template/apps/web/src/components/ui/sidebar/sidebar-width.webtest.ts +28 -0
- package/template/apps/web/src/components/ui/sidebar/utils.ts +26 -0
- package/template/apps/web/src/components/ui/skeleton/Skeleton.vue +17 -0
- package/template/apps/web/src/components/ui/skeleton/index.ts +1 -0
- package/template/apps/web/src/components/ui/sonner/Sonner.vue +70 -0
- package/template/apps/web/src/components/ui/sonner/index.ts +1 -0
- package/template/apps/web/src/components/ui/switch/Switch.vue +47 -0
- package/template/apps/web/src/components/ui/switch/Switch.webtest.ts +23 -0
- package/template/apps/web/src/components/ui/switch/index.ts +1 -0
- package/template/apps/web/src/components/ui/table/Table.vue +19 -0
- package/template/apps/web/src/components/ui/table/TableBody.vue +17 -0
- package/template/apps/web/src/components/ui/table/TableCaption.vue +17 -0
- package/template/apps/web/src/components/ui/table/TableCell.vue +22 -0
- package/template/apps/web/src/components/ui/table/TableEmpty.vue +37 -0
- package/template/apps/web/src/components/ui/table/TableFooter.vue +19 -0
- package/template/apps/web/src/components/ui/table/TableHead.vue +22 -0
- package/template/apps/web/src/components/ui/table/TableHeader.vue +14 -0
- package/template/apps/web/src/components/ui/table/TableRow.vue +22 -0
- package/template/apps/web/src/components/ui/table/index.ts +9 -0
- package/template/apps/web/src/components/ui/table/utils.ts +10 -0
- package/template/apps/web/src/components/ui/tabs/Tabs.vue +27 -0
- package/template/apps/web/src/components/ui/tabs/TabsContent.vue +23 -0
- package/template/apps/web/src/components/ui/tabs/TabsList.vue +34 -0
- package/template/apps/web/src/components/ui/tabs/TabsTrigger.vue +33 -0
- package/template/apps/web/src/components/ui/tabs/index.ts +24 -0
- package/template/apps/web/src/components/ui/tooltip/Tooltip.vue +15 -0
- package/template/apps/web/src/components/ui/tooltip/TooltipContent.vue +49 -0
- package/template/apps/web/src/components/ui/tooltip/TooltipProvider.vue +14 -0
- package/template/apps/web/src/components/ui/tooltip/TooltipTrigger.vue +12 -0
- package/template/apps/web/src/components/ui/tooltip/index.ts +4 -0
- package/template/apps/web/src/composables/useAccessSnapshot.ts +55 -0
- package/template/apps/web/src/composables/useAccessSnapshot.webtest.ts +39 -0
- package/template/apps/web/src/composables/useAppToast.ts +30 -0
- package/template/apps/web/src/composables/useAuthSession.ts +127 -0
- package/template/apps/web/src/composables/useAuthSession.webtest.ts +48 -0
- package/template/apps/web/src/composables/useLicenseReminderRefresh.ts +27 -0
- package/template/apps/web/src/composables/useLicenseReminderRefresh.webtest.ts +30 -0
- package/template/apps/web/src/composables/useLicenseRuntime.ts +90 -0
- package/template/apps/web/src/composables/useLoginFlow.ts +39 -0
- package/template/apps/web/src/composables/useModuleConfigurations.ts +116 -0
- package/template/apps/web/src/composables/usePasswordChange.ts +31 -0
- package/template/apps/web/src/composables/usePlatformSettings.ts +90 -0
- package/template/apps/web/src/composables/useSessionContext.ts +56 -0
- package/template/apps/web/src/composables/useTheme.ts +123 -0
- package/template/apps/web/src/composables/useUnsavedChangesConfirmation.ts +55 -0
- package/template/apps/web/src/composables/useWatermarkSettings.ts +56 -0
- package/template/apps/web/src/composables/watermark-settings.ts +45 -0
- package/template/apps/web/src/composables/watermark-settings.webtest.ts +38 -0
- package/template/apps/web/src/env.d.ts +17 -0
- package/template/apps/web/src/layout/AppHeader.vue +107 -0
- package/template/apps/web/src/layout/AppShell.vue +55 -0
- package/template/apps/web/src/layout/AppShell.webtest.ts +75 -0
- package/template/apps/web/src/layout/AppSidebar.vue +262 -0
- package/template/apps/web/src/layout/AppSidebar.webtest.ts +167 -0
- package/template/apps/web/src/layout/GlobalWatermark.vue +38 -0
- package/template/apps/web/src/layout/NavigationSearchDialog.vue +166 -0
- package/template/apps/web/src/layout/NavigationSearchDialog.webtest.ts +84 -0
- package/template/apps/web/src/layout/NotificationMenu.vue +174 -0
- package/template/apps/web/src/layout/NotificationMenu.webtest.ts +102 -0
- package/template/apps/web/src/layout/ThemeToggle.vue +44 -0
- package/template/apps/web/src/layout/navigation.ts +103 -0
- package/template/apps/web/src/layout/navigation.webtest.ts +99 -0
- package/template/apps/web/src/lib/date-time.ts +21 -0
- package/template/apps/web/src/lib/date-time.webtest.ts +14 -0
- package/template/apps/web/src/lib/utils.ts +7 -0
- package/template/apps/web/src/main.ts +11 -0
- package/template/apps/web/src/pages/AccessDeniedPage.vue +61 -0
- package/template/apps/web/src/pages/auth/ChangePasswordPage.vue +46 -0
- package/template/apps/web/src/pages/auth/LoginPage.vue +63 -0
- package/template/apps/web/src/pages/configuration/ModuleConfigurationPage.vue +15 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigRollbackDialog.vue +51 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigVersionList.vue +116 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.vue +126 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.webtest.ts +73 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationWorkbench.vue +236 -0
- package/template/apps/web/src/pages/dashboard/DashboardPage.vue +39 -0
- package/template/apps/web/src/pages/dashboard/DashboardPage.webtest.ts +37 -0
- package/template/apps/web/src/pages/dashboard/components/DashboardAttention.vue +36 -0
- package/template/apps/web/src/pages/dashboard/components/DashboardMetricCards.vue +28 -0
- package/template/apps/web/src/pages/dashboard/dashboard-presenter.ts +115 -0
- package/template/apps/web/src/pages/dashboard/dashboard-presenter.webtest.ts +92 -0
- package/template/apps/web/src/pages/license/LicensePage.vue +65 -0
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.vue +177 -0
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.webtest.ts +78 -0
- package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +198 -0
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.vue +195 -0
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.webtest.ts +314 -0
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +115 -0
- package/template/apps/web/src/pages/settings/logo-file.ts +23 -0
- package/template/apps/web/src/pages/settings/logo-file.webtest.ts +14 -0
- package/template/apps/web/src/pages/system/SystemNotificationsPage.vue +262 -0
- package/template/apps/web/src/pages/system/SystemNotificationsPage.webtest.ts +88 -0
- package/template/apps/web/src/pages/system/SystemOperationsPage.vue +151 -0
- package/template/apps/web/src/pages/system/SystemOperationsPage.webtest.ts +146 -0
- package/template/apps/web/src/pages/system/SystemResourceRoutePage.vue +80 -0
- package/template/apps/web/src/pages/system/SystemResourceRoutePage.webtest.ts +100 -0
- package/template/apps/web/src/pages/system/components/AuditActionCell.vue +87 -0
- package/template/apps/web/src/pages/system/components/AuditActionCell.webtest.ts +66 -0
- package/template/apps/web/src/pages/system/components/AuditLogFilters.vue +119 -0
- package/template/apps/web/src/pages/system/components/AuditLogFilters.webtest.ts +59 -0
- package/template/apps/web/src/pages/system/components/DiskUsageChart.vue +62 -0
- package/template/apps/web/src/pages/system/components/FeatureLicensePolicyDialog.vue +136 -0
- package/template/apps/web/src/pages/system/components/FeatureLicensePolicyDialog.webtest.ts +67 -0
- package/template/apps/web/src/pages/system/components/NotificationPublishForm.vue +57 -0
- package/template/apps/web/src/pages/system/components/OperationCacheMonitor.vue +73 -0
- package/template/apps/web/src/pages/system/components/OperationOnlineUsers.vue +60 -0
- package/template/apps/web/src/pages/system/components/OperationOnlineUsers.webtest.ts +35 -0
- package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +118 -0
- package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +64 -0
- package/template/apps/web/src/pages/system/components/SchedulerOperationsPanel.vue +297 -0
- package/template/apps/web/src/pages/system/components/SchedulerOperationsPanel.webtest.ts +145 -0
- package/template/apps/web/src/pages/system/components/SchedulerRunTable.vue +127 -0
- package/template/apps/web/src/pages/system/components/SchedulerRunTable.webtest.ts +75 -0
- package/template/apps/web/src/pages/system/components/SchedulerStaleRecoveryForm.vue +125 -0
- package/template/apps/web/src/pages/system/components/SchedulerStaleRecoveryForm.webtest.ts +84 -0
- package/template/apps/web/src/pages/system/components/SystemResourceFilters.vue +64 -0
- package/template/apps/web/src/pages/system/components/SystemResourceForm.vue +102 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +360 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +263 -0
- package/template/apps/web/src/pages/system/components/SystemResourceTable.vue +242 -0
- package/template/apps/web/src/pages/system/components/SystemResourceTable.webtest.ts +196 -0
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkActions.vue +142 -0
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobDetail.vue +109 -0
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobList.vue +127 -0
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkPanel.vue +72 -0
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkPanel.webtest.ts +255 -0
- package/template/apps/web/src/pages/system/components/feature-license-policy.ts +12 -0
- package/template/apps/web/src/pages/system/components/menu-management/MenuManagementPage.vue +131 -0
- package/template/apps/web/src/pages/system/components/menu-management/MenuManagementPage.webtest.ts +228 -0
- package/template/apps/web/src/pages/system/components/menu-management/MenuStructureTable.vue +230 -0
- package/template/apps/web/src/pages/system/components/menu-management/menu-model.ts +161 -0
- package/template/apps/web/src/pages/system/components/menu-management/menu-model.webtest.ts +133 -0
- package/template/apps/web/src/pages/system/components/menu-management/useMenuManagement.ts +117 -0
- package/template/apps/web/src/pages/system/components/role-policy/RolePermissionTree.vue +144 -0
- package/template/apps/web/src/pages/system/components/role-policy/RolePermissionTree.webtest.ts +55 -0
- package/template/apps/web/src/pages/system/components/role-policy/RolePolicyForm.vue +134 -0
- package/template/apps/web/src/pages/system/components/role-policy/permission-tree.ts +58 -0
- package/template/apps/web/src/pages/system/components/role-policy/permission-tree.webtest.ts +80 -0
- package/template/apps/web/src/pages/system/components/user-account/UserAccountForm.vue +307 -0
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.vue +111 -0
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.webtest.ts +45 -0
- package/template/apps/web/src/pages/system/components/user-account/save-user-account.ts +47 -0
- package/template/apps/web/src/pages/system/composables/useDictionaryBulkJobs.ts +152 -0
- package/template/apps/web/src/pages/system/composables/useFeatureLicenseEditor.ts +38 -0
- package/template/apps/web/src/pages/system/composables/useSchedulerOperations.ts +141 -0
- package/template/apps/web/src/pages/system/composables/useSchedulerOperations.webtest.ts +224 -0
- package/template/apps/web/src/pages/system/composables/useSystemResource.ts +269 -0
- package/template/apps/web/src/pages/system/composables/useSystemResource.webtest.ts +51 -0
- package/template/apps/web/src/pages/system/dictionary-bulk-presenter.ts +126 -0
- package/template/apps/web/src/pages/system/resource-config.ts +233 -0
- package/template/apps/web/src/router/auth-navigation.ts +76 -0
- package/template/apps/web/src/router/index.ts +246 -0
- package/template/apps/web/src/router/index.webtest.ts +396 -0
- package/template/apps/web/src/router/manifest-routes.ts +59 -0
- package/template/apps/web/src/services/access-api.ts +26 -0
- package/template/apps/web/src/services/auth-api.ts +72 -0
- package/template/apps/web/src/services/bulk-data-api.ts +105 -0
- package/template/apps/web/src/services/configuration-api.ts +43 -0
- package/template/apps/web/src/services/http.ts +145 -0
- package/template/apps/web/src/services/http.webtest.ts +73 -0
- package/template/apps/web/src/services/license-api.ts +53 -0
- package/template/apps/web/src/services/notification-api.ts +51 -0
- package/template/apps/web/src/services/operations-api.ts +128 -0
- package/template/apps/web/src/services/platform-settings-api.ts +21 -0
- package/template/apps/web/src/services/profile-api.ts +17 -0
- package/template/apps/web/src/services/session-context-api.ts +20 -0
- package/template/apps/web/src/services/system-api.ts +156 -0
- package/template/apps/web/src/style.css +142 -0
- package/template/apps/web/src/style.webtest.ts +18 -0
- package/template/apps/web/tsconfig.json +23 -0
- package/template/apps/web/vite.config.ts +26 -0
- package/template/apps/web/vitest.config.ts +14 -0
- package/template/bunfig.toml +2 -0
- package/template/docker-compose.yml +74 -0
- package/template/docs/adapters/ruoyi-vue-compatibility.md +93 -0
- package/template/docs/architecture/admin-surface-boundary.md +24 -0
- package/template/docs/architecture/data-scope-query-enforcement.md +26 -0
- package/template/docs/architecture/durable-jobs.md +101 -0
- package/template/docs/architecture/minimal-approval-workflow.md +60 -0
- package/template/docs/architecture/module-manifest-composition.md +47 -0
- package/template/docs/architecture/object-storage.md +65 -0
- package/template/docs/architecture/search-provider-protocol.md +59 -0
- package/template/docs/development/crud-generator.md +57 -0
- package/template/docs/license/license-offline-activation-code.md +67 -0
- package/template/docs/operations/observability.md +50 -0
- package/template/docs/platform/agent-tools.md +37 -0
- package/template/docs/platform/audit-reliability.md +95 -0
- package/template/docs/platform/bulk-data-jobs.md +156 -0
- package/template/docs/platform/data-access-control.md +62 -0
- package/template/docs/platform/module-configuration.md +98 -0
- package/template/docs/platform/navigation-registry.md +36 -0
- package/template/docs/platform/notifications.md +33 -0
- package/template/docs/platform/operations-overview.md +35 -0
- package/template/docs/platform/organization-membership.md +31 -0
- package/template/docs/platform/platform-authentication.md +127 -0
- package/template/docs/platform/platform-shell-settings.md +88 -0
- package/template/docs/platform/scheduled-task-executor.md +89 -0
- package/template/docs/platform/system-crud-api.md +100 -0
- package/template/docs/platform/web-system-crud.md +96 -0
- package/template/docs/product/built-in-roles.md +26 -0
- package/template/drizzle.config.ts +16 -0
- package/template/examples/inventory-item.crud.json +55 -0
- package/template/package.json +55 -0
- package/template/packages/config/index.test.ts +114 -0
- package/template/packages/config/index.ts +4 -0
- package/template/packages/config/package.json +13 -0
- package/template/packages/config/src/definition.ts +109 -0
- package/template/packages/config/src/environment-loader.ts +240 -0
- package/template/packages/config/src/platform.ts +185 -0
- package/template/packages/config/src/secrets.ts +69 -0
- package/template/packages/crud-generator/index.ts +3 -0
- package/template/packages/crud-generator/package.json +12 -0
- package/template/packages/crud-generator/src/cli.ts +31 -0
- package/template/packages/crud-generator/src/definition.ts +48 -0
- package/template/packages/crud-generator/src/generator.test.ts +180 -0
- package/template/packages/crud-generator/src/generator.ts +99 -0
- package/template/packages/crud-generator/src/template-helpers.ts +72 -0
- package/template/packages/crud-generator/src/templates/domain.ts +27 -0
- package/template/packages/crud-generator/src/templates/drizzle-repository.ts +126 -0
- package/template/packages/crud-generator/src/templates/dto.ts +19 -0
- package/template/packages/crud-generator/src/templates/index.ts +8 -0
- package/template/packages/crud-generator/src/templates/manifest.ts +69 -0
- package/template/packages/crud-generator/src/templates/project.ts +161 -0
- package/template/packages/crud-generator/src/templates/repository.ts +23 -0
- package/template/packages/crud-generator/src/templates/routes.ts +158 -0
- package/template/packages/crud-generator/src/templates/schema.ts +45 -0
- package/template/packages/crud-generator/src/templates/service.ts +32 -0
- package/template/packages/crud-generator/src/validation.ts +205 -0
- package/template/packages/crud-generator/tsconfig.json +15 -0
- package/template/packages/database/drizzle/0000_organic_madame_web.sql +136 -0
- package/template/packages/database/drizzle/0001_flawless_senator_kelly.sql +80 -0
- package/template/packages/database/drizzle/0002_woozy_squadron_supreme.sql +53 -0
- package/template/packages/database/drizzle/0003_far_carnage.sql +17 -0
- package/template/packages/database/drizzle/0004_flat_bastion.sql +2 -0
- package/template/packages/database/drizzle/0005_fixed_enchantress.sql +6 -0
- package/template/packages/database/drizzle/0006_groovy_overlord.sql +146 -0
- package/template/packages/database/drizzle/0007_chubby_may_parker.sql +9 -0
- package/template/packages/database/drizzle/0008_secret_toxin.sql +21 -0
- package/template/packages/database/drizzle/0009_ambiguous_adam_warlock.sql +46 -0
- package/template/packages/database/drizzle/0010_complex_orphan.sql +42 -0
- package/template/packages/database/drizzle/0011_lowly_maria_hill.sql +42 -0
- package/template/packages/database/drizzle/0012_serious_marvex.sql +11 -0
- package/template/packages/database/drizzle/0013_mysterious_miek.sql +48 -0
- package/template/packages/database/drizzle/0014_graceful_husk.sql +1 -0
- package/template/packages/database/drizzle/0015_illegal_jazinda.sql +29 -0
- package/template/packages/database/drizzle/0016_seed_platform_roles.sql +21 -0
- package/template/packages/database/drizzle/0017_silly_thunderbolt.sql +35 -0
- package/template/packages/database/drizzle/0018_cheerful_alex_power.sql +22 -0
- package/template/packages/database/drizzle/0019_omniscient_luckman.sql +3 -0
- package/template/packages/database/drizzle/0020_handy_vertigo.sql +18 -0
- package/template/packages/database/drizzle/0021_plain_paladin.sql +51 -0
- package/template/packages/database/drizzle/0022_icy_rhodey.sql +2 -0
- package/template/packages/database/drizzle/0023_fresh_thunderbolt_ross.sql +138 -0
- package/template/packages/database/drizzle/0024_misty_lizard.sql +13 -0
- package/template/packages/database/drizzle/0025_premium_songbird.sql +6 -0
- package/template/packages/database/drizzle/0026_aberrant_doctor_octopus.sql +42 -0
- package/template/packages/database/drizzle/0027_tiny_diamondback.sql +5 -0
- package/template/packages/database/drizzle/0028_condemned_ulik.sql +27 -0
- package/template/packages/database/drizzle/0029_clean_nightshade.sql +5 -0
- package/template/packages/database/drizzle/0030_governed_export_constraints.sql +84 -0
- package/template/packages/database/drizzle/meta/0000_snapshot.json +973 -0
- package/template/packages/database/drizzle/meta/0001_snapshot.json +1559 -0
- package/template/packages/database/drizzle/meta/0002_snapshot.json +1911 -0
- package/template/packages/database/drizzle/meta/0003_snapshot.json +2047 -0
- package/template/packages/database/drizzle/meta/0004_snapshot.json +2059 -0
- package/template/packages/database/drizzle/meta/0005_snapshot.json +2084 -0
- package/template/packages/database/drizzle/meta/0006_snapshot.json +3192 -0
- package/template/packages/database/drizzle/meta/0007_snapshot.json +3208 -0
- package/template/packages/database/drizzle/meta/0008_snapshot.json +3367 -0
- package/template/packages/database/drizzle/meta/0009_snapshot.json +3629 -0
- package/template/packages/database/drizzle/meta/0010_snapshot.json +3955 -0
- package/template/packages/database/drizzle/meta/0011_snapshot.json +4299 -0
- package/template/packages/database/drizzle/meta/0012_snapshot.json +4368 -0
- package/template/packages/database/drizzle/meta/0013_snapshot.json +4483 -0
- package/template/packages/database/drizzle/meta/0014_snapshot.json +4489 -0
- package/template/packages/database/drizzle/meta/0015_snapshot.json +4771 -0
- package/template/packages/database/drizzle/meta/0016_snapshot.json +4694 -0
- package/template/packages/database/drizzle/meta/0017_snapshot.json +4731 -0
- package/template/packages/database/drizzle/meta/0018_snapshot.json +4978 -0
- package/template/packages/database/drizzle/meta/0019_snapshot.json +4996 -0
- package/template/packages/database/drizzle/meta/0020_snapshot.json +5140 -0
- package/template/packages/database/drizzle/meta/0021_snapshot.json +5535 -0
- package/template/packages/database/drizzle/meta/0022_snapshot.json +5541 -0
- package/template/packages/database/drizzle/meta/0023_snapshot.json +6667 -0
- package/template/packages/database/drizzle/meta/0024_snapshot.json +6780 -0
- package/template/packages/database/drizzle/meta/0025_snapshot.json +6849 -0
- package/template/packages/database/drizzle/meta/0026_snapshot.json +7185 -0
- package/template/packages/database/drizzle/meta/0027_snapshot.json +7225 -0
- package/template/packages/database/drizzle/meta/0028_snapshot.json +7454 -0
- package/template/packages/database/drizzle/meta/0029_snapshot.json +7460 -0
- package/template/packages/database/drizzle/meta/0030_snapshot.json +7473 -0
- package/template/packages/database/drizzle/meta/_journal.json +223 -0
- package/template/packages/database/index.ts +5 -0
- package/template/packages/database/package.json +17 -0
- package/template/packages/database/src/dialects.test.ts +33 -0
- package/template/packages/database/src/dialects.ts +139 -0
- package/template/packages/database/src/runner.test.ts +96 -0
- package/template/packages/database/src/runner.ts +175 -0
- package/template/packages/database/src/schema/bulk-data.ts +87 -0
- package/template/packages/database/src/schema/common.ts +33 -0
- package/template/packages/database/src/schema/durable-jobs.ts +266 -0
- package/template/packages/database/src/schema/file-storage.ts +94 -0
- package/template/packages/database/src/schema/governance.ts +195 -0
- package/template/packages/database/src/schema/governed-exports.ts +90 -0
- package/template/packages/database/src/schema/identity.ts +169 -0
- package/template/packages/database/src/schema/index.ts +33 -0
- package/template/packages/database/src/schema/license-legacy.ts +93 -0
- package/template/packages/database/src/schema/license-v1.ts +246 -0
- package/template/packages/database/src/schema/migration-history.ts +30 -0
- package/template/packages/database/src/schema/notifications.ts +60 -0
- package/template/packages/database/src/schema/platform-settings.ts +55 -0
- package/template/packages/database/src/schema/scheduler.ts +89 -0
- package/template/packages/database/src/schema/work-orders.ts +23 -0
- package/template/packages/database/src/schema/workflow.ts +86 -0
- package/template/packages/database/src/schema-durable-links.test.ts +27 -0
- package/template/packages/database/src/schema-governed-exports.test.ts +49 -0
- package/template/packages/database/src/schema-workflow-notification.test.ts +63 -0
- package/template/packages/database/src/schema.test.ts +343 -0
- package/template/packages/database/src/sql-store.test.ts +92 -0
- package/template/packages/database/src/sql-store.ts +101 -0
- package/template/packages/database/src/store.ts +32 -0
- package/template/packages/database/tsconfig.json +17 -0
- package/template/packages/example-work-order/index.ts +3 -0
- package/template/packages/example-work-order/package.json +13 -0
- package/template/packages/example-work-order/src/contract.ts +50 -0
- package/template/packages/example-work-order/src/manifest.test.ts +54 -0
- package/template/packages/example-work-order/src/manifest.ts +120 -0
- package/template/packages/example-work-order/src/schema.ts +27 -0
- package/template/packages/license-sdk/index.ts +13 -0
- package/template/packages/license-sdk/package.json +18 -0
- package/template/packages/license-sdk/src/bounded-json-body.test.ts +65 -0
- package/template/packages/license-sdk/src/bounded-json-body.ts +135 -0
- package/template/packages/license-sdk/src/canonical-json.test.ts +28 -0
- package/template/packages/license-sdk/src/canonical-json.ts +104 -0
- package/template/packages/license-sdk/src/client.test.ts +82 -0
- package/template/packages/license-sdk/src/client.ts +86 -0
- package/template/packages/license-sdk/src/device.ts +46 -0
- package/template/packages/license-sdk/src/file-storage.test.ts +80 -0
- package/template/packages/license-sdk/src/file-storage.ts +77 -0
- package/template/packages/license-sdk/src/installation.test.ts +241 -0
- package/template/packages/license-sdk/src/installation.ts +150 -0
- package/template/packages/license-sdk/src/license-parser.ts +56 -0
- package/template/packages/license-sdk/src/offline-code-base32.ts +57 -0
- package/template/packages/license-sdk/src/offline-code-decompression.ts +55 -0
- package/template/packages/license-sdk/src/offline-code-limits.ts +10 -0
- package/template/packages/license-sdk/src/offline-code-wire.ts +72 -0
- package/template/packages/license-sdk/src/offline-code.test.ts +172 -0
- package/template/packages/license-sdk/src/offline-code.ts +319 -0
- package/template/packages/license-sdk/src/payload.test.ts +72 -0
- package/template/packages/license-sdk/src/payload.ts +201 -0
- package/template/packages/license-sdk/src/storage.ts +64 -0
- package/template/packages/license-sdk/src/test-fixtures.ts +59 -0
- package/template/packages/license-sdk/src/v1-test-vector.ts +49 -0
- package/template/packages/license-sdk/src/validation.test.ts +62 -0
- package/template/packages/license-sdk/src/validation.ts +143 -0
- package/template/packages/license-sdk/src/verification.test.ts +97 -0
- package/template/packages/license-sdk/src/verification.ts +199 -0
- package/template/packages/license-sdk/tsconfig.json +17 -0
- package/template/packages/modules/index.ts +8 -0
- package/template/packages/modules/package.json +13 -0
- package/template/packages/modules/src/composition.test.ts +267 -0
- package/template/packages/modules/src/composition.ts +342 -0
- package/template/packages/modules/src/installed-business-modules.ts +10 -0
- package/template/packages/modules/src/manifest.ts +97 -0
- package/template/packages/modules/src/menu-composition.test.ts +64 -0
- package/template/packages/modules/src/menu-composition.ts +54 -0
- package/template/packages/modules/src/registry.ts +53 -0
- package/template/packages/modules/src/system-admin-routes.ts +134 -0
- package/template/packages/modules/src/system-agent-tools.ts +28 -0
- package/template/packages/modules/src/system-api-binding.ts +37 -0
- package/template/packages/modules/src/system-api-data-governance.ts +21 -0
- package/template/packages/modules/src/system-api-permissions.ts +344 -0
- package/template/packages/modules/src/system-audit-actions.ts +70 -0
- package/template/packages/modules/src/system-data-governance.ts +30 -0
- package/template/packages/modules/src/system-features.ts +143 -0
- package/template/packages/modules/src/system-governed-export-bindings.ts +31 -0
- package/template/packages/modules/src/system-module-catalog.test.ts +145 -0
- package/template/packages/modules/src/system-module-catalog.ts +250 -0
- package/template/packages/modules/src/system-modules.test.ts +344 -0
- package/template/packages/modules/src/system-modules.ts +335 -0
- package/template/packages/modules/src/system-permissions.ts +142 -0
- package/template/packages/modules/user/module.ts +72 -0
- package/template/packages/shared/index.ts +16 -0
- package/template/packages/shared/package.json +9 -0
- package/template/packages/shared/src/audit.test.ts +17 -0
- package/template/packages/shared/src/audit.ts +237 -0
- package/template/packages/shared/src/correlation.test.ts +10 -0
- package/template/packages/shared/src/correlation.ts +11 -0
- package/template/packages/shared/src/data-governance.test.ts +44 -0
- package/template/packages/shared/src/data-governance.ts +89 -0
- package/template/packages/shared/src/database.ts +67 -0
- package/template/packages/shared/src/feature.test.ts +54 -0
- package/template/packages/shared/src/feature.ts +104 -0
- package/template/packages/shared/src/license-legacy.ts +153 -0
- package/template/packages/shared/src/license.test.ts +63 -0
- package/template/packages/shared/src/license.ts +267 -0
- package/template/packages/shared/src/module-configuration.ts +50 -0
- package/template/packages/shared/src/notification.ts +46 -0
- package/template/packages/shared/src/platform-settings.ts +5 -0
- package/template/packages/shared/src/primitives.ts +47 -0
- package/template/packages/shared/src/profile.ts +13 -0
- package/template/packages/shared/src/rbac.ts +117 -0
- package/template/packages/shared/src/ruoyi.ts +98 -0
- package/template/packages/shared/src/scheduler.ts +108 -0
- package/template/packages/shared/src/search-provider.ts +24 -0
- package/template/packages/shared/src/workflow.test.ts +225 -0
- package/template/packages/shared/src/workflow.ts +307 -0
- package/template/packages/storage/index.ts +11 -0
- package/template/packages/storage/package.json +12 -0
- package/template/packages/storage/src/blob-store.ts +64 -0
- package/template/packages/storage/src/content-hash.ts +24 -0
- package/template/packages/storage/src/file-service.test.ts +100 -0
- package/template/packages/storage/src/file-service.ts +59 -0
- package/template/packages/storage/src/in-memory-upload-repository.ts +154 -0
- package/template/packages/storage/src/local-file-blob-store.test.ts +175 -0
- package/template/packages/storage/src/local-file-blob-store.ts +344 -0
- package/template/packages/storage/src/local-file-maintenance.ts +133 -0
- package/template/packages/storage/src/memory-blob-store.test.ts +16 -0
- package/template/packages/storage/src/memory-blob-store.ts +100 -0
- package/template/packages/storage/src/upload-repository.ts +43 -0
- package/template/packages/storage/src/upload-service.test.ts +246 -0
- package/template/packages/storage/src/upload-service.ts +334 -0
- package/template/packages/storage/src/upload-streams.ts +123 -0
- package/template/packages/storage/src/upload-types.ts +110 -0
- package/template/packages/storage/tsconfig.json +16 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# 平台外壳、品牌设置与水印
|
|
2
|
+
|
|
3
|
+
## 定位
|
|
4
|
+
|
|
5
|
+
平台外壳负责所有业务模块共用的导航、搜索、品牌和身份水印。入口必须来自 Module Manifest,并同时经过 Feature、RBAC 与 License 有效态裁剪,不能在 Header、Sidebar 和路由中各维护一套权限判断。
|
|
6
|
+
|
|
7
|
+
## 导航与搜索
|
|
8
|
+
|
|
9
|
+
- Sidebar 保留 Manifest 的目录层级,当前默认分为“组织与权限”“平台配置”“安全与合规”“运维”。分组可独立折叠,展开状态保存在当前浏览器。
|
|
10
|
+
- 菜单管理只持久化父目录、同级顺序和显隐;路由、权限、Feature 和标题仍由 Manifest 注册。启动同步会软删除旧水印、按钮型和已经撤销注册的历史菜单行,细节见 [Manifest 菜单注册与导航结构](./navigation-registry.md)。
|
|
11
|
+
- 平台 Logo 和软件名称区域始终跳转工作台首页。
|
|
12
|
+
- 桌面端外壳固定为视口高度,Sidebar 与右侧内容区各自滚动;Header 位于内容滚动容器之外,页面上下滚动时保持固定。
|
|
13
|
+
- Header 搜索以 `system.search` 为能力基础 Key,并由 `system.search.read` 权限控制;它只索引当前用户可访问的菜单,支持点击打开、`Ctrl/Command + K`、关键词过滤和 Enter 打开首项。
|
|
14
|
+
- 系统通用资源页使用 `resourceKey` 作为实例 Key。资源切换必须重建请求与表格状态,禁止把功能开关响应继续渲染为角色数据。
|
|
15
|
+
- 字典批量任务只有在 `system.bulk-data` 最终有效且当前用户具有字典读取权限时才挂载;未获 License Entitlement 时显示说明,不发出必然失败的请求。
|
|
16
|
+
|
|
17
|
+
## 全局品牌设置
|
|
18
|
+
|
|
19
|
+
能力基础 Key 为 `system.settings`:
|
|
20
|
+
|
|
21
|
+
- Feature:`system.settings`
|
|
22
|
+
- 权限:`system.settings.read`、`system.settings.manage`
|
|
23
|
+
- Sidebar 入口:侧边栏底部 / 全局设置
|
|
24
|
+
- 审计动作:`config.update`
|
|
25
|
+
|
|
26
|
+
公开接口 `GET /api/platform/branding` 只返回非敏感的 `softwareName`、可选 `logoUrl` 和可选 `description`,供登录页和应用外壳使用。管理接口 `GET/PUT /api/system/settings/branding` 经过 Feature 与 RBAC Guard。全局设置使用独立 `/settings` 页面,不使用 Modal;Sidebar 从授权后的 Manifest 菜单中提取该入口并固定在底部。页面使用 shadcn-vue Tabs 组织“基本信息”和“水印设置”;水印 Tab 仍独立经过 Feature 与权限裁剪,后续邮件、存储、安全等设置应按同一方式增加类型化分类。
|
|
27
|
+
|
|
28
|
+
全局设置的 Tab 必须反映在 URL hash 中:基本信息使用 `/settings#basic`,水印设置使用 `/settings#watermark`。直接访问、刷新、浏览器前进后退和复制链接都应恢复到对应 Tab;缺失或未知 hash 回退到 `#basic`。由代码切换 Tab 时先完成未保存编辑确认,确认完成前不能提前修改 hash。
|
|
29
|
+
|
|
30
|
+
配置 PostgreSQL 时,品牌信息写入 `platform_branding_settings` 单例记录;未配置数据库的开发环境使用内存 Repository。未保存运营配置时回退到 `PLATFORM_NAME`、`PLATFORM_LOGO_URL`。Logo 可以使用 HTTP、HTTPS、以 `/` 开头的站内路径,或由页面读取本地 PNG、JPEG、WebP 后生成的不超过 1 MiB 的受限图片数据;拒绝 SVG、任意 `data:`、`javascript:` 等可能执行内容的协议。
|
|
31
|
+
|
|
32
|
+
数据库连接、Cookie Secret、License 公钥、Vault 和签发凭据不属于运营品牌设置,不能加入这个运营设置页面。
|
|
33
|
+
|
|
34
|
+
## 未保存编辑保护
|
|
35
|
+
|
|
36
|
+
该规则适用于全局设置,也适用于所有具有编辑状态的页面、抽屉、Modal 和 Dialog:
|
|
37
|
+
|
|
38
|
+
- 各编辑区以最近一次成功加载或保存的数据作为基线,使用规范化后的当前值与基线比较得到 `dirty` 状态。不能仅在首次输入时把状态永久设为脏,也不能因 Tab 暂时卸载而丢失编辑内容。
|
|
39
|
+
- 当 `dirty` 为真时,关闭抽屉、Modal 或 Dialog,切换页面、设置 Tab、菜单或路由都必须先打开统一确认 Dialog。文案需明确说明当前修改尚未保存,继续离开不会保存这些修改。
|
|
40
|
+
- 确认 Dialog 提供“取消”和“保存”两个主要动作。取消会关闭确认框并留在当前编辑态;保存使用原编辑区相同的校验和提交函数,按钮显示 loading、禁止重复提交,成功后更新基线并继续之前被拦截的动作。
|
|
41
|
+
- 校验或保存失败时不得关闭编辑容器、切换 Tab、修改 URL 或跳转路由;保留用户输入,恢复按钮可操作状态,并在当前编辑区显示错误。
|
|
42
|
+
- 应用内跳转由统一的组件关闭拦截和 Vue Router Guard 处理。受保护的 Tab 切换也视为导航,包含 `/settings#basic` 与 `/settings#watermark` 之间的 hash 变化;确认流程应保存一个待继续动作,避免保存成功后再次触发确认。
|
|
43
|
+
- 浏览器刷新、关闭标签页或窗口使用原生 `beforeunload`。仅在 `dirty` 且未处于已确认的成功保存流程时注册或触发提示;浏览器决定提示文案,应用不依赖自定义文本。
|
|
44
|
+
- 保存成功、用户明确重置或服务端数据重新加载后才清除 `dirty`。禁止用路由卸载、组件销毁或切换 Tab 的副作用静默清除未保存状态。
|
|
45
|
+
|
|
46
|
+
通用实现应沉淀为可复用的未保存编辑保护 composable 和确认 Dialog,而不是在各页面复制路由判断。新增可编辑页面至少覆盖:无修改直接离开、取消后保留输入、保存 loading、防重复提交、保存成功后继续、保存失败后停留、hash/路由切换拦截和 `beforeunload` 注册清理测试。
|
|
47
|
+
|
|
48
|
+
## 水印
|
|
49
|
+
|
|
50
|
+
能力基础 Key 为 `system.watermark`:
|
|
51
|
+
|
|
52
|
+
- Feature:`system.watermark`
|
|
53
|
+
- 权限:`system.watermark.read`、`system.watermark.manage`
|
|
54
|
+
- 页面入口:全局设置 / 页面水印,不注册独立 Sidebar 菜单
|
|
55
|
+
|
|
56
|
+
只有 Feature 最终有效且当前用户具有读取权限时才渲染水印及全局设置中的水印区块。当前版本的显示开关与自定义内容是用户在当前浏览器的偏好;默认内容从当前 Actor 派生,顺序为用户名加手机、邮箱或姓名。
|
|
57
|
+
|
|
58
|
+
后续若引入平台强制水印策略,应由服务端持久化并审计,生效关系为:Feature 开启,且平台强制显示,或平台允许用户控制且个人偏好开启。普通用户不能覆盖“强制显示”。
|
|
59
|
+
|
|
60
|
+
## 个人设置
|
|
61
|
+
|
|
62
|
+
- 右上角账号头像菜单提供“个人设置”入口,路由为 `/profile`;该入口不会重复出现在 Sidebar 导航中。
|
|
63
|
+
- 当前用户可查看账号名,并在拥有 `system.profile.manage` 权限时修改姓名、邮箱和手机。账号名仍由管理员在用户管理中维护。
|
|
64
|
+
- `system.profile` 同时注册 Feature Flag、`system.profile.read/manage` 权限、页面入口和 API 绑定。功能关闭或权限缺失时,页面路由和服务端 API 都会拒绝访问。
|
|
65
|
+
- `PUT /api/system/profile` 只修改当前会话对应的用户,不接受目标用户 ID;成功后写入 `user.profile.update` 审计事件,Web 端会刷新会话和授权快照,使 Header 中的姓名立即更新。
|
|
66
|
+
|
|
67
|
+
## Feature 开关交互
|
|
68
|
+
|
|
69
|
+
开关使用 Reka UI 的 `data-state="checked|unchecked"` 状态选择器。切换时先乐观显示目标状态,只锁定当前行;服务端失败时恢复原状态并显示原因。管理资格只由 `system.feature.manage` 决定,不再硬编码 `developer`、`super-admin` 等角色名称。
|
|
70
|
+
|
|
71
|
+
内置 `developer` 角色在启动时会补充 Manifest 新增的权限和菜单 Key,避免模板升级后管理员因为旧数据库角色快照而看不到新控制面;已有自定义授权不会被删除。
|
|
72
|
+
|
|
73
|
+
## 权限中文元数据
|
|
74
|
+
|
|
75
|
+
角色权限树的模块与资源标题直接读取 Module Manifest 中必填的 `moduleLabel` 和 `resourceLabel`,不在前端维护 License、notification、profile 等英文 key 的翻译表。新能力缺少中文分组元数据会在 TypeScript 类型检查阶段失败;CRUD 生成器也会同步生成这两个字段。
|
|
76
|
+
|
|
77
|
+
## 运维验证
|
|
78
|
+
|
|
79
|
+
修改这些能力时至少执行:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bun run typecheck
|
|
83
|
+
bun test apps/server/src/settings apps/server/src/system/seed.test.ts
|
|
84
|
+
bun run --cwd apps/web test -- NavigationSearchDialog.webtest.ts SystemResourceRoutePage.webtest.ts Switch.webtest.ts
|
|
85
|
+
bun run build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
涉及 schema 时还需运行 `bun run test:db:migrations`,确认全量迁移和二次执行均通过。
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# 平台定时任务执行器
|
|
2
|
+
|
|
3
|
+
## 目标与边界
|
|
4
|
+
|
|
5
|
+
平台定时任务由服务端代码注册,数据库保存当前调度状态和执行历史。控制台或 API 不能创建任意可执行代码,避免把数据库配置变成远程代码执行入口。
|
|
6
|
+
|
|
7
|
+
本期支持:
|
|
8
|
+
|
|
9
|
+
- 固定间隔调度;
|
|
10
|
+
- 单任务并发控制;
|
|
11
|
+
- 手动触发;
|
|
12
|
+
- 有上限的失败重试;
|
|
13
|
+
- 疑似停滞执行的受控人工恢复;
|
|
14
|
+
- 执行结果、错误和重试链路查询;
|
|
15
|
+
- Permission、动态 Feature Flag、Entitlement Guard;
|
|
16
|
+
- 读取、触发、执行和拒绝事件审计。
|
|
17
|
+
|
|
18
|
+
本期不实现 Cron 表达式、分布式工作流编排、任务代码在线编辑和 RuoYi 旧库任务写入。
|
|
19
|
+
|
|
20
|
+
## 定义与注册
|
|
21
|
+
|
|
22
|
+
任务定义位于 `apps/server/src/scheduler/definitions.ts`。每个定义必须提供稳定且唯一的 `key`,并声明:
|
|
23
|
+
|
|
24
|
+
- 中文名称与说明;
|
|
25
|
+
- 执行间隔;
|
|
26
|
+
- 最大尝试次数与重试延迟;
|
|
27
|
+
- 所需权限;
|
|
28
|
+
- 所属 Feature;
|
|
29
|
+
- 服务端 handler。
|
|
30
|
+
|
|
31
|
+
服务启动时会幂等同步定义元数据。已移除的定义会归档并停用,历史执行记录仍保留;重新加入代码注册表后恢复为活跃定义。
|
|
32
|
+
|
|
33
|
+
## Guard 模型
|
|
34
|
+
|
|
35
|
+
调度器使用 `system.scheduler` Feature,其商业授权标识是 `capability.scheduler`。每次定时执行、失败重试、手动触发和人工恢复都按以下顺序重新判定:
|
|
36
|
+
|
|
37
|
+
1. License 是否处于允许业务运行的状态;
|
|
38
|
+
2. License 是否包含 `capability.scheduler`;
|
|
39
|
+
3. 数据库中的 `system.scheduler` 动态 Feature 是否启用且可见;
|
|
40
|
+
4. 执行身份是否具备 `system.scheduler.manage`。
|
|
41
|
+
|
|
42
|
+
查询定义和历史还要求 `system.scheduler.read`。Feature 停用后,不需要重启服务;新的调度、重试和手动触发都不会进入 handler。已领取但在 Guard 阶段被拒绝的后台执行记录为 `blocked`,用于解释为什么到期任务没有运行。
|
|
43
|
+
|
|
44
|
+
## 并发与调度
|
|
45
|
+
|
|
46
|
+
`scheduled_tasks` 保存下一次执行时间。领取到期任务时,Repository 在 PostgreSQL 事务中取得任务级 advisory lock,确认任务仍然到期、活跃且没有运行中的实例,再推进下一次执行时间并创建执行记录。
|
|
47
|
+
|
|
48
|
+
`scheduled_task_runs` 还有一个条件唯一索引:同一 `task_key` 在 `status = 'running'` 时最多存在一行。事务锁负责正常竞争,唯一索引作为数据库最终防线。因此同一进程的重复 tick、多个 Server 实例以及手动触发和调度竞争,都不能让同一任务并发失控。
|
|
49
|
+
|
|
50
|
+
进程内 worker 同样禁止 tick 重入。轮询间隔由 `SCHEDULER_POLL_INTERVAL_MS` 设置,默认一秒;任务自己的执行间隔仍以持久化定义为准。
|
|
51
|
+
|
|
52
|
+
## 重试与历史
|
|
53
|
+
|
|
54
|
+
handler 抛出错误后,本次记录进入 `retry-pending`,并保存经过长度限制的错误消息和 `nextAttemptAt`。到达重试时间后,调度器原子地把旧记录固定为 `failed`,创建 `trigger = 'retry'` 的下一次记录,并递增 `attempt`。
|
|
55
|
+
|
|
56
|
+
达到 `maxAttempts` 后不再重试。成功记录为 `succeeded`;Guard 拒绝为 `blocked`。每次尝试都是独立历史行,`retryOfRunId` 保留重试链路,不覆盖之前的错误。
|
|
57
|
+
|
|
58
|
+
## API
|
|
59
|
+
|
|
60
|
+
- `GET /api/system/scheduled-tasks`:查询已注册任务和下一次执行时间;
|
|
61
|
+
- `GET /api/system/scheduled-task-runs?page=1&pageSize=10`:分页查询执行历史,默认每页 10 条,单页最大 100 条;
|
|
62
|
+
- `GET /api/system/operations/scheduler`:查询运维总览使用的代码注册定义、持久状态、最近历史和运行/重试/stale 派生状态;
|
|
63
|
+
- `POST /api/system/scheduled-tasks/:id/trigger`:手动触发任务;
|
|
64
|
+
- `POST /api/system/scheduled-tasks/:id/runs/:runId/recover`:人工确认并解除一条疑似停滞执行对后续调度的占用。
|
|
65
|
+
|
|
66
|
+
以上 GET 与 POST 均登记在 System Module Manifest:总览要求 `system.scheduler.read`,手动触发和人工恢复要求 `system.scheduler.manage`,并完整执行 `License → Entitlement → Feature → RBAC` 顺序。同一任务正在运行时,手动触发返回 `409 TASK_ALREADY_RUNNING`;未知任务返回 `404 TASK_NOT_FOUND`;Guard 拒绝返回 `403 FORBIDDEN`。handler 业务失败会形成可查询、可重试的执行记录,不伪装成并发或权限错误。
|
|
67
|
+
|
|
68
|
+
手动触发属于关键审计事件,使用 AUDIT-01 的可靠写入与恢复队列。只有 `task.trigger` 成功持久化或进入可恢复队列后才会调用 handler;两者均不可用时,本次 run 会落为 `blocked` 并返回 `503 AUDIT_UNAVAILABLE`,不会遗留 `running`。
|
|
69
|
+
|
|
70
|
+
## 运维总览与 stale 语义
|
|
71
|
+
|
|
72
|
+
Web `/system/operations` 通过独立 typed composable 读取调度总览,不再展示硬编码的 `planned` 占位任务。页面展示代码注册定义、数据库中的启用/归档和下次执行状态、每个任务的最近执行、等待重试数量和脱敏限长的错误摘要,并在手动触发前二次确认。
|
|
73
|
+
|
|
74
|
+
最近执行历史使用独立的服务端分页表格,默认每页 10 条,允许输入 1 至 100 的任意页大小;首页和末页的翻页按钮按状态禁用。表格直接显示中文任务名称、触发方式、结果、执行次数和开始时间,稳定任务 key 只在零延迟组件库 Tooltip 中显示。手动触发或人工恢复成功后同时刷新任务概览和当前历史页。
|
|
75
|
+
|
|
76
|
+
`stale` 本身仍是纯观察状态:当一条 `running` 记录持续至少 15 分钟,总览将其派生为“疑似停滞”。派生判断不会修改 `scheduled_task_runs`,不会自动领取、终止或重试任务。该阈值是没有 heartbeat/lease 之前的告警启发式,不等同于任务已经失败。
|
|
77
|
+
|
|
78
|
+
只有总览中满足上述条件的记录才显示“人工确认恢复”。操作员必须先确认旧 Server 进程和 handler 已停止、核查可能已经产生的业务副作用,再填写 8 至 500 字且包含中文的处置原因并勾选二次确认。普通 `running` 记录不显示恢复按钮。
|
|
79
|
+
|
|
80
|
+
恢复请求必须同时提交当前页面观察到的 `runId`、`taskKey` 和 `expectedStartedAt`。Repository 使用原子 compare-and-set,只有目标记录仍为 `running`、`startedAt` 与预期完全一致且仍超过 15 分钟阈值时,才把原历史行终结为 `blocked`,写入恢复编号、操作者、脱敏限长原因和 `automaticRetry: false` 元数据,并释放同任务单 `running` 条件唯一索引。任何状态变化、时间版本变化或未达到阈值都返回 `409`;不会调用 handler,也不会创建重试执行。历史行不会删除或覆盖成成功,后续正常调度仅按原任务计划重新领取。
|
|
81
|
+
|
|
82
|
+
`task.recover` 采用两阶段审计边界:原子恢复前先可靠写入关键 intent 事件,包含恢复编号、run、预期开始时间、操作者和脱敏原因摘要;数据库与恢复队列都不可用时返回 `503 AUDIT_UNAVAILABLE`,且不改变 run。CAS 成功或冲突后再写普通 outcome 事件。由于审计与 scheduler Repository 不是同一事务,竞争冲突可能留下 intent 但不会留下未经关键 intent 的状态变更;CAS 后普通 outcome 写入失败按 AUDIT-01 降级状态和告警处理。
|
|
83
|
+
|
|
84
|
+
## 运维注意事项
|
|
85
|
+
|
|
86
|
+
- 正式环境应配置 PostgreSQL;未配置数据库时只使用开发态内存 Repository,重启后不保留历史。
|
|
87
|
+
- 任务 handler 应保持幂等,因为数据库可以保证领取不重入,但无法回滚 handler 已经提交到外部系统的副作用。
|
|
88
|
+
- 当前没有运行中任务的租约和强制中断。人工恢复只是经确认后终结 stale 调度记录并释放后续调度,不会停止仍存活的旧 handler,也不会补偿它已经产生的外部副作用;在没有可靠心跳和业务幂等证明前绝不自动抢占或重跑。
|
|
89
|
+
- 总览不返回 handler `result`,错误摘要会对常见凭据字段和 Bearer token 脱敏并限制为 240 字符;handler 仍不得把密钥或完整外部凭据写入异常消息。
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# 系统基础模块 CRUD API
|
|
2
|
+
|
|
3
|
+
## 当前状态
|
|
4
|
+
|
|
5
|
+
Server 端已提供系统基础模块 Repository API,用于打通权限、查询、分页、排序、过滤、软删除和审计事件闭环。
|
|
6
|
+
资源 API 已支持 JSON 导入和导出,用于客户单机部署时快速迁移基础配置或生成现场备份。
|
|
7
|
+
|
|
8
|
+
默认无数据库时使用内存 Repository;配置 `DATABASE_URL` 后,系统资源 CRUD 会切换为 Drizzle Repository,并把用户、角色、部门、菜单、字典和功能开关持久化到 PostgreSQL。
|
|
9
|
+
|
|
10
|
+
<!-- @windy-module system.license begin -->
|
|
11
|
+
选择离线 License 模块时,原型 License 兼容记录也会持久化到 PostgreSQL。
|
|
12
|
+
<!-- @windy-module system.license end -->
|
|
13
|
+
|
|
14
|
+
当前覆盖资源:
|
|
15
|
+
|
|
16
|
+
- `users`:用户。
|
|
17
|
+
- `roles`:角色。
|
|
18
|
+
- `departments`:部门。
|
|
19
|
+
- `menus`:菜单。
|
|
20
|
+
- `dictionaries`:字典。
|
|
21
|
+
- `features`:功能开关。
|
|
22
|
+
<!-- @windy-module system.license begin -->
|
|
23
|
+
- `licenses`:License 记录。
|
|
24
|
+
<!-- @windy-module system.license end -->
|
|
25
|
+
- `audit-logs`:审计日志查询。
|
|
26
|
+
|
|
27
|
+
## 路由
|
|
28
|
+
|
|
29
|
+
资源路由统一挂在 `/api/system` 下。
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
GET /api/system/:resource
|
|
33
|
+
GET /api/system/:resource/export
|
|
34
|
+
GET /api/system/:resource/:id
|
|
35
|
+
POST /api/system/:resource
|
|
36
|
+
POST /api/system/departments/quick
|
|
37
|
+
POST /api/system/:resource/import
|
|
38
|
+
PUT /api/system/:resource/:id
|
|
39
|
+
DELETE /api/system/:resource/:id
|
|
40
|
+
GET /api/system/audit-logs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
其中 `audit-logs` 目前只提供查询;配置 `DATABASE_URL` 后优先读取 PostgreSQL `audit_logs`,未配置时读取当前进程内存审计事件。
|
|
44
|
+
|
|
45
|
+
## 导入导出
|
|
46
|
+
|
|
47
|
+
- 导出:`GET /api/system/:resource/export`,复用 `q`、`status`、`includeDeleted`、`sort` 查询参数,返回 JSON 快照。
|
|
48
|
+
- 导入:`POST /api/system/:resource/import`,请求体支持 `{ "mode": "create" | "upsert", "items": [...] }`。
|
|
49
|
+
- `create` 模式遇到已有 `id` 会跳过,`upsert` 模式遇到已有 `id` 会更新。
|
|
50
|
+
- 导入成功写入 `data.import` 审计事件,导出成功写入 `data.export` 审计事件。
|
|
51
|
+
|
|
52
|
+
## 查询参数
|
|
53
|
+
|
|
54
|
+
- `page`:页码,默认 `1`。
|
|
55
|
+
- `pageSize`:每页条数,默认 `10`。Web 端允许直接输入 `1` 至 `100` 的任意整数,不限于固定档位。
|
|
56
|
+
- `q`:关键词,按资源配置的字段模糊匹配。
|
|
57
|
+
- `status`:状态过滤。
|
|
58
|
+
- `includeDeleted=true`:包含软删除数据。
|
|
59
|
+
- `sort`:排序字段,逗号分隔;前缀 `-` 表示倒序,例如 `-updatedAt,name`。
|
|
60
|
+
|
|
61
|
+
`audit-logs` 额外支持 `actorId`、`action`、`resource`、`resourceId` 过滤。
|
|
62
|
+
|
|
63
|
+
`page` 必须是正整数,`pageSize` 必须是 `1` 至 `100` 的整数;越界或非整数请求返回 `400 INVALID_PAGINATION`,响应同时给出 `maxPageSize`,不会静默截断。通用数据表首列使用 `(page - 1) * pageSize + rowIndex + 1` 显示跨页连续序号;没有服务端分页的短列表只显示本地序号,不伪造总数和页码。
|
|
64
|
+
|
|
65
|
+
## 权限
|
|
66
|
+
|
|
67
|
+
路由使用统一 Guard:
|
|
68
|
+
|
|
69
|
+
- 读操作:`system.<resource>.read`。
|
|
70
|
+
- 用户表单快捷创建部门:`system.department.create`;既有通用部门创建仍要求 `system.department.manage`。
|
|
71
|
+
- 写操作:`system.<resource>.manage`。
|
|
72
|
+
- 审计日志:`system.audit.read`。
|
|
73
|
+
- 系统资源默认绑定 `system.rbac` Feature,审计日志绑定 `system.audit`。
|
|
74
|
+
<!-- @windy-module system.license begin -->
|
|
75
|
+
- License 资源绑定 `system.license`。
|
|
76
|
+
<!-- @windy-module system.license end -->
|
|
77
|
+
- Guard 固定按 Entitlement、动态 Feature Flag、RBAC 顺序判定。Feature 声明了 `requiredEntitlement` 但 License 快照缺失该能力、开关关闭/隐藏或用户缺少权限时,路由返回带稳定 `reason` 的 `403`,并记录 `security.denied`。
|
|
78
|
+
|
|
79
|
+
配置 `DATABASE_URL` 后,Admin Web 使用 `/api/auth/login` 签发的 `windy.sid` HttpOnly Cookie;明确的非浏览器集成使用 `/api/auth/api/login` 独立签发的 Bearer Token。Server 只用 Token hash 查询未过期、未吊销的服务端会话,再从数据库活跃用户和角色聚合权限。开发 Token 必须显式配置,且 `NODE_ENV=production` 时强制关闭;完整说明见 [客户业务平台认证与会话](./platform-authentication.md)。
|
|
80
|
+
|
|
81
|
+
## 当前边界
|
|
82
|
+
|
|
83
|
+
- 未配置 `DATABASE_URL` 时仍使用内存 Repository,服务重启后数据会丢失。
|
|
84
|
+
- 配置 `DATABASE_URL` 后,系统资源使用 Drizzle Repository,启动时会按 `id` / `key` 幂等写入默认种子数据,不覆盖已有记录。
|
|
85
|
+
- Feature Flag 是受控资源:Key 和元数据由 Module Manifest 幂等同步,API 只允许修改 `enabled` / `visible`,不提供创建、导入或删除入口。Manifest 移除的 Key 会归档保留历史状态。
|
|
86
|
+
- Feature Guard 在配置数据库时按请求、按 Key 读取运行态;同一请求缓存结果,下一请求重新读取。开发无数据库时回退 Manifest,生产无数据库或读取失败时 fail closed。
|
|
87
|
+
- CRUD 成功和权限拒绝会先进入进程内审计 sink;配置 `DATABASE_URL` 后由可靠写入器写入 PostgreSQL `audit_logs`。普通事件持续失败时业务继续并告警;用户、角色、License 与 Feature Flag 等关键变更必须落库或进入本地原子恢复队列。策略、状态和恢复步骤见 [平台审计可靠写入](./audit-reliability.md)。
|
|
88
|
+
- 密码登录、服务端会话、退出和吊销已闭环;通用用户 CRUD 不读写或返回密码 hash,密码更新走受权限保护的认证 API。
|
|
89
|
+
<!-- @windy-module system.license begin -->
|
|
90
|
+
- 正式运行时 License 通过 `/api/license/runtime` 查看,并通过 `/api/license/runtime/install` 复用 SDK 验签和单槽原子替换;通用 `legacy_licenses` CRUD 只保留为显式原型兼容面,不能提供生产授权。
|
|
91
|
+
- License 限制模式只对显式列举的系统资源 JSON 导出放行,导出仍需通过原有 Feature 与 RBAC Guard;其它 API、Agent Tool 和后台任务先由 License Guard 阻断。
|
|
92
|
+
<!-- @windy-module system.license end -->
|
|
93
|
+
- `feature_flags` 的 Drizzle 路径已补齐完整审计字段和软删除列;`0005` migration 会回填既有数据的 `created_by` 后再设置非空约束。
|
|
94
|
+
- 通用系统资源仍保留同步 JSON 文件能力;字典已额外接入后台 NDJSON 任务、本人进度查询、失败明细和结果留存,Web 字典页默认使用后台工作流。其它实体尚未注册批量处理器。
|
|
95
|
+
|
|
96
|
+
## 已完成补强与后续边界
|
|
97
|
+
|
|
98
|
+
- 审计写入已有有界重试、失败/丢弃/排队计数、健康状态、结构化告警和关键事件恢复队列;关键业务写入与审计仍不是同一数据库/文件事务,失败重试前必须先查询业务状态。
|
|
99
|
+
- Web 菜单、路由和按钮已经使用服务端 Feature/权限快照;Feature 修改同时要求 `system.feature.manage` 和 `super-admin` / `developer` 角色,Server 继续执行最终强制校验。
|
|
100
|
+
- 按真实资源处理器继续扩展后台任务;当前不能用字典批量接口处理其它实体。现有 PostgreSQL artifact 仅适用于 10 MiB、50,000 行和 256 KiB 单行上限,扩大容量前应增加对象存储 Adapter。
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Web 系统基础模块页面
|
|
2
|
+
|
|
3
|
+
## 当前状态
|
|
4
|
+
|
|
5
|
+
Web 端已从单页静态首页推进为带真实会话的 Router 应用壳:
|
|
6
|
+
|
|
7
|
+
- `App.vue` 按 route meta 切换登录布局与 `AppShell`,未认证用户不会先看到业务壳。
|
|
8
|
+
- 首页内容迁移到 `pages/dashboard/DashboardPage.vue`,只展示平台状态指标和需要处理的提醒;导航入口统一由 Sidebar 和 Header 搜索提供,账号信息与个人设置统一由 Header 头像菜单提供。
|
|
9
|
+
- 侧边栏菜单可点击跳转,并按当前路由高亮。
|
|
10
|
+
- 顶部面包屑读取 route meta 标题。
|
|
11
|
+
- 顶部账号菜单展示当前 Actor 并提供服务端退出;401 会全局清理会话并返回登录页。
|
|
12
|
+
- 顶部通知入口读取服务端通知收件箱,可打开正文并跨设备保存当前用户已读回执;无 `system.notification.read` 权限或 Feature 关闭时不显示入口,也不会请求通知 API。
|
|
13
|
+
|
|
14
|
+
## 页面范围
|
|
15
|
+
|
|
16
|
+
当前已接入以下系统页面:
|
|
17
|
+
|
|
18
|
+
- `/system/users`:用户体系。
|
|
19
|
+
- `/system/roles`:权限策略。
|
|
20
|
+
- `/system/departments`:部门组织。
|
|
21
|
+
- `/system/menus`:菜单管理。
|
|
22
|
+
- `/system/dictionaries`:字典管理。
|
|
23
|
+
- `/system/features`:功能开关。
|
|
24
|
+
- `/system/license`:License。
|
|
25
|
+
- `/system/audit`:审计日志。
|
|
26
|
+
- `/system/operations`:在线会话、应用与数据库资源、Redis 探活和定时任务。
|
|
27
|
+
- `/system/notifications`:通知发布、历史管理和归档。
|
|
28
|
+
|
|
29
|
+
用户、角色、部门、字典、功能开关和审计日志等通用资源页面共享 `SystemResourcePage`、`SystemResourceTable`、`SystemResourceForm` 和 `useSystemResource`,资源差异通过 `resource-config.ts` 声明。菜单管理是 Manifest 驱动的专用导航结构页,只允许调整父目录、同级顺序和显隐;License 和运维总览也使用各自的专用页面与 composable。
|
|
30
|
+
|
|
31
|
+
权限策略使用 `/api/foundation` 返回的 Manifest 权限目录,按模块、资源和操作三级级联勾选。数据范围使用受控枚举下拉框;不在当前 Manifest 中的历史权限会明确列出,管理员可以保留或取消,不会在编辑时静默丢失。`roles.permission_keys` 是运行时唯一权限事实来源,因此取消勾选后不会被旧关系表重新授予。
|
|
32
|
+
|
|
33
|
+
用户新增和编辑表单使用启用部门下拉和启用角色多选,并由 Server 校验 `departmentId`、`roleIds` 和角色状态。创建账号必须填写一次性初始密码,编辑时可按需重置;密码只发送到专用认证接口。具有 `system.department.create` 或既有 `system.department.manage` 权限时,表单提供新建部门快捷入口,创建成功后自动选中。停用账号会吊销全部活跃会话,最后一个超级管理员受到服务端保护;组织模型和数据范围见 [部门组织与用户归属](./organization-membership.md) 与 [数据访问范围](./data-access-control.md)。
|
|
34
|
+
|
|
35
|
+
## API 对接
|
|
36
|
+
|
|
37
|
+
Web 通过 `services/` 下的资源、License、运维和批量任务 API service 复用统一同源 HTTP 客户端访问 Server:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
GET /api/system/:resource
|
|
41
|
+
POST /api/system/:resource
|
|
42
|
+
POST /api/system/departments/quick
|
|
43
|
+
POST /api/auth/users/:id/password
|
|
44
|
+
PUT /api/system/:resource/:id
|
|
45
|
+
DELETE /api/system/:resource/:id
|
|
46
|
+
PUT /api/system/menus/:id/placement
|
|
47
|
+
GET /api/system/:resource/export
|
|
48
|
+
POST /api/system/:resource/import
|
|
49
|
+
GET /api/system/audit-logs
|
|
50
|
+
GET /api/license/runtime
|
|
51
|
+
POST /api/license/runtime/install
|
|
52
|
+
GET /api/system/operations
|
|
53
|
+
GET /api/system/operations/scheduler
|
|
54
|
+
POST /api/system/scheduled-tasks/:id/trigger
|
|
55
|
+
GET /api/system/bulk-data/jobs
|
|
56
|
+
GET /api/system/bulk-data/jobs/:id
|
|
57
|
+
GET /api/system/bulk-data/jobs/:id/artifacts/:kind
|
|
58
|
+
POST /api/system/bulk-data/dictionaries/import
|
|
59
|
+
POST /api/system/bulk-data/dictionaries/export
|
|
60
|
+
GET /api/notifications
|
|
61
|
+
POST /api/notifications/:id/read
|
|
62
|
+
GET /api/system/notifications
|
|
63
|
+
POST /api/system/notifications
|
|
64
|
+
DELETE /api/system/notifications/:id
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
开发服务把 `/api` 代理到 `http://localhost:3000`。默认不携带开发 Token;需要调试直通时必须同时显式设置:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
VITE_API_BASE=/api
|
|
71
|
+
VITE_DEV_AUTH_BYPASS=1
|
|
72
|
+
VITE_DEV_ADMIN_TOKEN=<显式开发 Token>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
该直通只在 Vite 开发模式生效并持续显示警告。生产构建使用相对 `/api`,由 Bun Web 服务通过 `API_UPSTREAM` 转发到内部 Server;浏览器只使用同源 HttpOnly Cookie,不持久化 Bearer Token。
|
|
76
|
+
|
|
77
|
+
## 当前边界
|
|
78
|
+
|
|
79
|
+
- 当前页面对接 Server 端系统资源 Repository;未配置 `DATABASE_URL` 时刷新后服务端数据不持久,配置后由 Drizzle Repository 持久化。正式部署必须配置数据库,不能把内存 Repository 当作生产权威。
|
|
80
|
+
- 审计日志页面只读,不提供删除入口;可按动作精确筛选,并提供“功能开关变更”等常用快捷筛选。时间统一按 `Asia/Shanghai` 显示为 `yyyy-mm-dd HH:mm:ss`。
|
|
81
|
+
- `/system/license` 已从原型记录 CRUD 切换为所有已认证用户可用的运行状态和文件上传入口;它只安装厂商内部 `apps/license` 签发服务生成的文件,不在客户现场提供签发能力。普通用户只看到必要状态、到期时间和联系管理员提示,具备 `system.license.manage` 的维护人员才看到完整 License 与设备详情。页面提供 60/30/7 天分级提醒,并在限制模式下收敛导航。
|
|
82
|
+
- Web 导航源于 `/api/foundation` 返回的 Module Manifest 菜单声明,并按当前 Actor 权限和服务端 Feature 有效状态过滤;Router Guard 会重新获取快照阻断直接访问,按钮使用同一快照。Feature 管理页只允许修改 `enabled` / `visible`,编辑能力同时要求 `system.feature.manage` 和 `super-admin` / `developer` 角色;Server 仍是最终授权边界。
|
|
83
|
+
- Feature 管理页在列表最右侧操作栏直接显示启停开关,不再打开通用编辑弹窗;修改仍调用受 Guard 和关键审计保护的 Server API。
|
|
84
|
+
- Feature 开关成功修改会写入 `feature.update`,可在审计日志页通过“功能开关变更”直接查看。
|
|
85
|
+
- 系统资源表和字典后台任务表加载时保留表头与列宽,并显示带 `animate-pulse` 的骨架行;加载失败和空数据仍使用各自独立状态。
|
|
86
|
+
- 全局水印默认开启,内容按“用户名 + 手机号 / 邮箱 / 姓名”的顺序从当前会话 Actor 派生。`system.watermark` Feature 和 `system.watermark.read` 权限共同控制渲染及“全局设置”页内的水印区块;水印不注册独立 Sidebar 入口。用户可关闭或写入最多 80 个字符的自定义内容,偏好只保存在当前浏览器,不是平台级强制策略。服务端只向当前用户自己的会话响应补充这些身份字段。
|
|
87
|
+
- 站内通知由 PostgreSQL `platform_notifications` 和 `notification_reads` 持久化;管理人员可在 `/system/notifications` 广播发布和归档,用户从 Header 收件箱阅读正文并幂等写入已读回执。归档是生命周期操作,不物理删除通知或回执。当前发布范围是全体有阅读权限的用户,尚未提供组织、角色、用户定向和外部渠道投递。
|
|
88
|
+
- 字典页已切换为后台 NDJSON 导入导出,展示本人任务状态、进度、重试和终态文件下载;其它系统资源仍保留小数据同步 JSON 入口。详细契约见 [批量导入导出后台任务](./bulk-data-jobs.md)。当前 artifact 存在 10 MiB、50,000 行和 256 KiB 单行上限,扩大容量前需要对象存储 Adapter。
|
|
89
|
+
- 审计日志配置 `DATABASE_URL` 后读取 PostgreSQL `audit_logs`。可靠写入器提供有界重试、降级状态、关键事件本地恢复队列和健康信息;页面仍只读,且不会展示恢复队列中的事件正文。
|
|
90
|
+
- 运维页的定时任务来自真实代码注册和 PostgreSQL 状态,不允许在线编辑任务代码。当前基线的 `stale` 只做观察告警和人工处置提示,不会自动终止或重试。
|
|
91
|
+
|
|
92
|
+
## 后续工作与验证边界
|
|
93
|
+
|
|
94
|
+
- 按实际资源处理器逐一扩展后台批量任务;当前只支持字典,不能把字典接口伪装为其它实体能力。
|
|
95
|
+
- 当前自动化测试覆盖 Vue 组件、Router、同源 HTTP 客户端和 Server API,但未使用真实浏览器验证 Cookie、反向代理 TLS、跨 Origin 或多实例负载均衡。跨 Origin 部署前必须先设计 Origin 白名单、CSRF Token 和 Cookie Domain。
|
|
96
|
+
- 客户 License 文件安装串行化和时间回拨高水位当前是单进程状态;多副本 Web/Server 部署不能在未增加单写者或跨进程协调前共享写入同一路径。
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 平台内置角色基线
|
|
2
|
+
|
|
3
|
+
## 首次安装
|
|
4
|
+
|
|
5
|
+
Starter 首次安装提供四个稳定角色。角色 ID 和 code 是升级契约,不随显示名称改变:
|
|
6
|
+
|
|
7
|
+
| ID | code | 名称 | 默认数据范围 | 默认定位 |
|
|
8
|
+
| ------------------------- | -------------------- | ---------- | ------------ | ----------------------------------- |
|
|
9
|
+
| `role_super_admin` | `super-admin` | 超级管理员 | 全部 | 平台全部能力与导航 |
|
|
10
|
+
| `role_department_manager` | `department-manager` | 部门负责人 | 部门及下级 | 用户、部门只读和个人常用能力 |
|
|
11
|
+
| `role_user` | `user` | 普通用户 | 仅本人 | 个人设置、通知、搜索和 License 状态 |
|
|
12
|
+
| `role_developer` | `developer` | 开发运维 | 全部 | 开发、运维与升级恢复控制面 |
|
|
13
|
+
|
|
14
|
+
初始 `admin` 用户归属 `role_super_admin` 和 `dept_platform`。从旧版本升级时会补入超级管理员角色和缺失部门,但保留已有角色归属。
|
|
15
|
+
|
|
16
|
+
## 升级同步
|
|
17
|
+
|
|
18
|
+
运行时以 Manifest 当前权限和导航注册补充内置角色缺失项,不删除客户已经追加的自定义权限或菜单。`super-admin` 补齐全部注册能力;`developer` 补齐标准能力,但不会因为自动同步获得标记为 `sensitive-disclosure` 的明文查看权限或 `governed-export` 的治理导出权限。这两类高风险能力必须显式授权,已经由客户显式授予的权限在重复同步时保留。部门负责人和普通用户只补齐各自的最小基线。角色名称、数据范围和已有自定义授权不会在每次启动时被覆盖。
|
|
19
|
+
|
|
20
|
+
数据库 migration `0016_seed_platform_roles.sql` 幂等登记稳定角色,并升级已存在的 `user_dev_admin`。实际 Manifest 权限集合由启动同步写入,避免在 SQL migration 中复制一份会随模块演进而漂移的 Key 列表。
|
|
21
|
+
|
|
22
|
+
## 安全边界
|
|
23
|
+
|
|
24
|
+
当前 `dataScope` 和 `departmentIds` 已持久化,但 Repository 查询级的数据范围 Guard 仍是产品缺口。为避免默认角色越权写入,部门负责人基线暂不授予 `system.user.manage` 或 `system.department.manage`。在部门及下级查询约束和越权测试完成前,不应通过 seed 扩大该角色的写权限;管理员仍可按部署需求显式配置自定义角色。
|
|
25
|
+
|
|
26
|
+
用户敏感字段策略将 `system.user.read`、`system.user.reveal` 和 `system.user.export` 分为三类能力。普通读取只能取得服务端脱敏结果;明文查看与治理导出即使由超级管理员执行,也必须重新授权并写入关键审计。客户端提交的角色 code、权限数组或展示模式不是授权来源。
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from "drizzle-kit";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
dialect: "postgresql",
|
|
5
|
+
schema: "./packages/database/src/schema/index.ts",
|
|
6
|
+
out: "./packages/database/drizzle",
|
|
7
|
+
casing: "snake_case",
|
|
8
|
+
migrations: {
|
|
9
|
+
table: "__drizzle_migrations",
|
|
10
|
+
schema: "drizzle",
|
|
11
|
+
},
|
|
12
|
+
dbCredentials: {
|
|
13
|
+
url:
|
|
14
|
+
process.env.DATABASE_URL || "postgresql://localhost:5432/windy",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"module": {
|
|
4
|
+
"name": "inventory",
|
|
5
|
+
"label": "库存管理",
|
|
6
|
+
"description": "库存物料独立业务模块。",
|
|
7
|
+
"version": "0.1.0"
|
|
8
|
+
},
|
|
9
|
+
"entity": {
|
|
10
|
+
"name": "InventoryItem",
|
|
11
|
+
"pluralName": "InventoryItems",
|
|
12
|
+
"label": "库存物料",
|
|
13
|
+
"table": "inventory_items",
|
|
14
|
+
"resource": "item",
|
|
15
|
+
"route": "/api/inventory/items",
|
|
16
|
+
"featureKey": "inventory.item",
|
|
17
|
+
"featureLabel": "库存物料管理",
|
|
18
|
+
"allowedLicenseVersions": ["standard", "advanced"],
|
|
19
|
+
"fields": [
|
|
20
|
+
{
|
|
21
|
+
"name": "code",
|
|
22
|
+
"column": "code",
|
|
23
|
+
"label": "物料编码",
|
|
24
|
+
"type": "string",
|
|
25
|
+
"maxLength": 80,
|
|
26
|
+
"required": true,
|
|
27
|
+
"unique": true,
|
|
28
|
+
"searchable": true
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "name",
|
|
32
|
+
"column": "name",
|
|
33
|
+
"label": "物料名称",
|
|
34
|
+
"type": "string",
|
|
35
|
+
"maxLength": 120,
|
|
36
|
+
"required": true,
|
|
37
|
+
"searchable": true
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "quantity",
|
|
41
|
+
"column": "quantity",
|
|
42
|
+
"label": "库存数量",
|
|
43
|
+
"type": "integer",
|
|
44
|
+
"required": true
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "available",
|
|
48
|
+
"column": "available",
|
|
49
|
+
"label": "是否可用",
|
|
50
|
+
"type": "boolean",
|
|
51
|
+
"required": true
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "windy-platform-template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"workspaces": [
|
|
8
|
+
"apps/*",
|
|
9
|
+
"packages/*"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"prepare": "husky",
|
|
13
|
+
"dev": "bun run --cwd apps/web dev",
|
|
14
|
+
"dev:web": "bun run --cwd apps/web dev",
|
|
15
|
+
"dev:server": "bun run --cwd apps/server dev",
|
|
16
|
+
"dev:license": "bun run --cwd apps/license dev",
|
|
17
|
+
"dev:signing": "bun run --cwd apps/signing-service dev",
|
|
18
|
+
"generate:crud": "bun run packages/crud-generator/src/cli.ts",
|
|
19
|
+
"create:windy": "bun run packages/create-windy/src/cli.ts",
|
|
20
|
+
"test:create-windy": "bun run packages/create-windy/src/regression.ts",
|
|
21
|
+
"build": "bun run --cwd apps/web build",
|
|
22
|
+
"build:license": "bun run --cwd apps/license build:web",
|
|
23
|
+
"db:generate": "drizzle-kit generate --config drizzle.config.ts",
|
|
24
|
+
"db:migrate": "drizzle-kit migrate --config drizzle.config.ts",
|
|
25
|
+
"test:db:auth": "bun run scripts/auth-postgres-regression.ts",
|
|
26
|
+
"test:db:data-scope": "bun run scripts/data-scope-postgres-regression.ts",
|
|
27
|
+
"test:db:governance": "bun run scripts/governance-postgres-regression.ts",
|
|
28
|
+
"test:db:legacy-license": "bun run scripts/legacy-license-migration-regression.ts",
|
|
29
|
+
"test:db:license-bootstrap": "bun run scripts/license-bootstrap-postgres-regression.ts",
|
|
30
|
+
"test:db:migrations": "bun run scripts/database-migration-regression.ts",
|
|
31
|
+
"test:db:config": "bun run scripts/module-configuration-postgres-regression.ts",
|
|
32
|
+
"test:redis:health": "bun run scripts/redis-health-regression.ts",
|
|
33
|
+
"test:vault:signing": "bun run scripts/vault-signing-regression.ts",
|
|
34
|
+
"test:docker:license-signing": "bun run scripts/license-signing-compose-regression.ts",
|
|
35
|
+
"test:ops:recovery": "bun run scripts/production-recovery-regression.ts",
|
|
36
|
+
"test:ops:amd64": "bun run scripts/linux-amd64-container-regression.ts",
|
|
37
|
+
"ops:db": "bun run scripts/production-database.ts",
|
|
38
|
+
"ops:release": "bun run scripts/production-release.ts",
|
|
39
|
+
"test:release:evidence": "bun run scripts/release-evidence.ts",
|
|
40
|
+
"typecheck": "bun run --cwd apps/web typecheck && bun run --cwd apps/server typecheck && bun run --cwd apps/license typecheck && bun run --cwd apps/signing-service typecheck && bun run --cwd packages/license-sdk typecheck && bun run --cwd packages/storage typecheck && bun run --cwd packages/database typecheck && bun run --cwd packages/crud-generator typecheck && bun run --cwd packages/create-windy typecheck",
|
|
41
|
+
"lint": "oxlint .",
|
|
42
|
+
"format": "oxfmt",
|
|
43
|
+
"test": "bun test --path-ignore-patterns='packages/create-windy/template/**' && bun run --cwd apps/web test"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/bun": "^1.3.14",
|
|
47
|
+
"@types/pg": "^8.20.0",
|
|
48
|
+
"drizzle-kit": "^0.31.10",
|
|
49
|
+
"husky": "^9.1.7",
|
|
50
|
+
"oxfmt": "^0.59.0",
|
|
51
|
+
"oxlint": "^1.74.0",
|
|
52
|
+
"typescript": "5.9.3"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {}
|
|
55
|
+
}
|