@cosmicdrift/kumiko-framework 0.386.0 → 0.388.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/AGENTS.md +6 -1
- package/LICENSE +21 -57
- package/README.md +2 -2
- package/agents/examples/anonymous-access.md +1 -1
- package/agents/examples/apex-landing.md +204 -0
- package/agents/examples/api-worker-split.md +64 -0
- package/agents/examples/app-config.md +14 -0
- package/agents/examples/auth-mfa.md +115 -0
- package/agents/examples/env-composition.md +28 -1
- package/agents/examples/legal-pages.md +1 -1
- package/agents/examples/prod-boot-options.md +16 -0
- package/agents/examples/rate-limiting.md +48 -0
- package/agents/examples/record-detail-layout.md +692 -0
- package/agents/examples/seed-migration.md +212 -0
- package/agents/examples/wizard-form.md +941 -0
- package/agents/examples/writeform-section.md +548 -0
- package/agents/features.md +19 -2
- package/agents/widgets.md +40 -39
- package/dist/api/api-constants.js +2 -2
- package/dist/api/auth-middleware.js +7 -7
- package/dist/api/auth-rate-limiters.js +7 -3
- package/dist/api/auth-routes-mfa.js +1 -1
- package/dist/api/auth-routes-session.js +1 -1
- package/dist/api/auth-routes-shared.js +7 -3
- package/dist/api/auth-routes-signup.js +1 -1
- package/dist/api/client-error-route.js +8 -2
- package/dist/api/client-ip.js +3 -1
- package/dist/api/extra-route.js +1 -1
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +3 -1
- package/dist/api/pii-leak-guard.js +4 -2
- package/dist/api/readiness.js +5 -5
- package/dist/api/redis-sse-broker.js +8 -6
- package/dist/api/request-context.d.ts +1 -1
- package/dist/api/request-context.js +1 -1
- package/dist/api/routes.js +2 -2
- package/dist/api/server-boot-checks.d.ts +10 -0
- package/dist/api/server-boot-checks.js +157 -0
- package/dist/api/server-event-dispatcher.d.ts +26 -0
- package/dist/api/server-event-dispatcher.js +208 -0
- package/dist/api/server-extra-routes.d.ts +11 -0
- package/dist/api/server-extra-routes.js +203 -0
- package/dist/api/server-middleware.d.ts +20 -0
- package/dist/api/server-middleware.js +211 -0
- package/dist/api/server-routes.d.ts +19 -0
- package/dist/api/server-routes.js +293 -0
- package/dist/api/server-websocket-routes.d.ts +4 -0
- package/dist/api/server-websocket-routes.js +108 -0
- package/dist/api/server-wiring.d.ts +32 -0
- package/dist/api/server-wiring.js +236 -0
- package/dist/api/server.d.ts +10 -15
- package/dist/api/server.js +48 -1250
- package/dist/api/session-cookies.js +4 -4
- package/dist/api/sse-broker.js +1 -1
- package/dist/api/sse-route.d.ts +13 -13
- package/dist/api/sse-route.js +31 -27
- package/dist/auth/index.js +4 -4
- package/dist/auth/roles.d.ts +4 -4
- package/dist/auth/roles.js +24 -24
- package/dist/compliance/duration-spec.js +18 -20
- package/dist/compliance/index.js +2 -3
- package/dist/compliance/override-schema.d.ts +4 -4
- package/dist/compliance/override-schema.js +19 -22
- package/dist/compliance/profiles.d.ts +26 -29
- package/dist/compliance/profiles.js +62 -69
- package/dist/compliance/sub-processors.d.ts +28 -30
- package/dist/compliance/sub-processors.js +17 -21
- package/dist/consumer-cli.js +4 -4
- package/dist/crypto/blind-index.js +18 -17
- package/dist/crypto/ciphertext-pattern.js +1 -1
- package/dist/crypto/event-pii.js +3 -3
- package/dist/crypto/kek-source.d.ts +1 -1
- package/dist/crypto/kek-source.js +3 -2
- package/dist/crypto/kms-adapter.d.ts +1 -1
- package/dist/crypto/kms-adapter.js +4 -6
- package/dist/crypto/kms-wiring.d.ts +1 -2
- package/dist/crypto/kms-wiring.js +2 -2
- package/dist/crypto/owner-transition-rekey.d.ts +5 -1
- package/dist/crypto/owner-transition-rekey.js +1 -1
- package/dist/crypto/pg-kms-adapter.js +2 -6
- package/dist/crypto/pii-field-encryption.d.ts +5 -1
- package/dist/crypto/pii-field-encryption.js +7 -5
- package/dist/crypto/subject-resolver.d.ts +1 -1
- package/dist/crypto/subject-resolver.js +2 -2
- package/dist/db/aggregate-sql.d.ts +21 -0
- package/dist/db/aggregate-sql.js +155 -0
- package/dist/db/apply-entity-event.d.ts +6 -6
- package/dist/db/apply-entity-event.js +55 -55
- package/dist/db/blind-index-cleanup.js +7 -7
- package/dist/db/closed-connection.d.ts +9 -0
- package/dist/db/closed-connection.js +95 -0
- package/dist/db/collect-table-metas.js +10 -11
- package/dist/db/compound-types.d.ts +1 -1
- package/dist/db/compound-types.js +12 -12
- package/dist/db/cursor.js +3 -4
- package/dist/db/dialect.d.ts +2 -2
- package/dist/db/dialect.js +3 -3
- package/dist/db/distinct-on.d.ts +1 -1
- package/dist/db/driver-row-coercion.d.ts +2 -0
- package/dist/db/driver-row-coercion.js +186 -0
- package/dist/db/driver-value-preparation.d.ts +16 -0
- package/dist/db/driver-value-preparation.js +99 -0
- package/dist/db/eagerload.d.ts +3 -3
- package/dist/db/eagerload.js +21 -12
- package/dist/db/entity-field-encryption.d.ts +1 -0
- package/dist/db/entity-field-encryption.js +1 -1
- package/dist/db/entity-table-meta.d.ts +2 -2
- package/dist/db/entity-table-meta.js +105 -112
- package/dist/db/event-store-executor-context.d.ts +3 -2
- package/dist/db/event-store-executor-context.js +13 -13
- package/dist/db/event-store-executor-read-aggregate.d.ts +8 -0
- package/dist/db/event-store-executor-read-aggregate.js +112 -0
- package/dist/db/event-store-executor-read-filter.d.ts +31 -0
- package/dist/db/event-store-executor-read-filter.js +203 -0
- package/dist/db/event-store-executor-read-paging.d.ts +14 -0
- package/dist/db/event-store-executor-read-paging.js +99 -0
- package/dist/db/event-store-executor-read-rows.d.ts +6 -0
- package/dist/db/event-store-executor-read-rows.js +32 -0
- package/dist/db/event-store-executor-read-search.d.ts +28 -0
- package/dist/db/event-store-executor-read-search.js +221 -0
- package/dist/db/event-store-executor-read-sort.d.ts +41 -0
- package/dist/db/event-store-executor-read-sort.js +130 -0
- package/dist/db/event-store-executor-read-where.d.ts +24 -0
- package/dist/db/event-store-executor-read-where.js +81 -0
- package/dist/db/event-store-executor-read.d.ts +2 -9
- package/dist/db/event-store-executor-read.js +50 -704
- package/dist/db/event-store-executor-write-steps.d.ts +20 -0
- package/dist/db/event-store-executor-write-steps.js +100 -0
- package/dist/db/event-store-executor-write.js +401 -510
- package/dist/db/index.d.ts +6 -2
- package/dist/db/index.js +5 -1
- package/dist/db/list-aggregate-labels.d.ts +14 -0
- package/dist/db/list-aggregate-labels.js +26 -0
- package/dist/db/located-timestamp.d.ts +11 -11
- package/dist/db/located-timestamp.js +29 -30
- package/dist/db/migrate-generator.d.ts +1 -1
- package/dist/db/migrate-generator.js +97 -105
- package/dist/db/migrate-runner.js +29 -26
- package/dist/db/money.d.ts +6 -6
- package/dist/db/money.js +29 -27
- package/dist/db/queries/backfill-pii.js +5 -5
- package/dist/db/queries/ddl.js +1 -1
- package/dist/db/queries/es-ops.d.ts +1 -1
- package/dist/db/queries/es-ops.js +1 -1
- package/dist/db/queries/event-consumer.js +3 -3
- package/dist/db/queries/event-store.js +4 -2
- package/dist/db/queries/projection-rebuild.js +3 -3
- package/dist/db/queries/raw-sql.d.ts +2 -2
- package/dist/db/queries/raw-sql.js +2 -2
- package/dist/db/queries/shadow-swap.js +19 -19
- package/dist/db/query.d.ts +3 -16
- package/dist/db/query.js +8 -761
- package/dist/db/rebuild-marker.js +20 -21
- package/dist/db/reference-data.js +6 -1
- package/dist/db/replay-migration-sql.js +2 -2
- package/dist/db/schema-inspection.js +4 -5
- package/dist/db/table-builder.d.ts +1 -2
- package/dist/db/table-builder.js +137 -190
- package/dist/db/table-info.d.ts +10 -0
- package/dist/db/table-info.js +45 -0
- package/dist/db/temporal-value-guards.d.ts +6 -0
- package/dist/db/temporal-value-guards.js +15 -0
- package/dist/db/tenant-db-runner.d.ts +1 -0
- package/dist/db/tenant-db-runner.js +3 -0
- package/dist/db/tenant-db.d.ts +2 -2
- package/dist/db/tenant-db.js +48 -11
- package/dist/db/where-clause.d.ts +6 -0
- package/dist/db/where-clause.js +236 -0
- package/dist/derivatives/delete-stored-file.js +6 -2
- package/dist/derivatives/derivatives-context.js +1 -1
- package/dist/engine/boot-validator/access-roles.js +4 -3
- package/dist/engine/boot-validator/api-ext.js +14 -14
- package/dist/engine/boot-validator/boot-check.js +1 -1
- package/dist/engine/boot-validator/config-deps.js +7 -6
- package/dist/engine/boot-validator/detail-screens.js +4 -4
- package/dist/engine/boot-validator/entity-handler.d.ts +1 -0
- package/dist/engine/boot-validator/entity-handler.js +77 -61
- package/dist/engine/boot-validator/form-derivations.js +35 -1
- package/dist/engine/boot-validator/gdpr-storage.js +4 -4
- package/dist/engine/boot-validator/i18n-keys.js +6 -4
- package/dist/engine/boot-validator/index.d.ts +2 -2
- package/dist/engine/boot-validator/index.js +22 -20
- package/dist/engine/boot-validator/nav.js +5 -5
- package/dist/engine/boot-validator/ownership.js +12 -9
- package/dist/engine/boot-validator/parent-ref.js +1 -1
- package/dist/engine/boot-validator/pii-retention.js +258 -187
- package/dist/engine/boot-validator/projection-list-screens.js +7 -7
- package/dist/engine/boot-validator/query-refs.js +1 -1
- package/dist/engine/boot-validator/screens-actions.d.ts +1 -0
- package/dist/engine/boot-validator/screens-actions.js +23 -17
- package/dist/engine/boot-validator/screens-dashboard.js +2 -5
- package/dist/engine/boot-validator/screens-forms.js +12 -17
- package/dist/engine/boot-validator/screens-kind-config-edit.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-config-edit.js +88 -0
- package/dist/engine/boot-validator/screens-kind-entity-edit.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-entity-edit.js +55 -0
- package/dist/engine/boot-validator/screens-kind-entity-list.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-entity-list.js +228 -0
- package/dist/engine/boot-validator/screens-kind-projection-detail.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-projection-detail.js +235 -0
- package/dist/engine/boot-validator/screens-kind-projection-list.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-projection-list.js +52 -0
- package/dist/engine/boot-validator/screens-kind-secret-mint.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-secret-mint.js +28 -0
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +37 -0
- package/dist/engine/boot-validator/screens-kind-shared.js +142 -0
- package/dist/engine/boot-validator/screens-lists.d.ts +2 -1
- package/dist/engine/boot-validator/screens-lists.js +26 -24
- package/dist/engine/boot-validator/screens.d.ts +0 -2
- package/dist/engine/boot-validator/screens.js +102 -869
- package/dist/engine/boot-validator/security-baseline.js +3 -2
- package/dist/engine/boot-validator/transfer-graph.js +2 -2
- package/dist/engine/boot-validator/workspaces.js +3 -3
- package/dist/engine/bridge-stub.js +3 -4
- package/dist/engine/build-app-schema.js +130 -170
- package/dist/engine/build-config-feature-schema.js +50 -50
- package/dist/engine/build-target.js +20 -23
- package/dist/engine/codemod/pipeline-codemod.js +20 -13
- package/dist/engine/config-helpers.js +4 -4
- package/dist/engine/constants.js +2 -2
- package/dist/engine/create-app.js +2 -2
- package/dist/engine/define-feature.js +21 -13
- package/dist/engine/define-handler.js +13 -11
- package/dist/engine/define-step.js +1 -1
- package/dist/engine/define-workflow.d.ts +5 -5
- package/dist/engine/define-workflow.js +6 -6
- package/dist/engine/entity-handlers.d.ts +13 -0
- package/dist/engine/entity-handlers.js +22 -34
- package/dist/engine/entity-list-runtime-options.d.ts +8 -0
- package/dist/engine/entity-list-runtime-options.js +18 -0
- package/dist/engine/event-def.js +2 -2
- package/dist/engine/extension-names.d.ts +16 -17
- package/dist/engine/extension-names.js +37 -38
- package/dist/engine/extensions/escape-hatch-usage.js +1 -1
- package/dist/engine/extensions/tenant-data.js +2 -2
- package/dist/engine/extensions/user-data.d.ts +23 -24
- package/dist/engine/factories.d.ts +14 -13
- package/dist/engine/factories.js +38 -37
- package/dist/engine/feature-ast/entity-field-types.js +1 -1
- package/dist/engine/feature-ast/extractors/handlers.js +2 -1
- package/dist/engine/feature-ast/extractors/hooks.js +1 -1
- package/dist/engine/feature-ast/extractors/round2.js +25 -6
- package/dist/engine/feature-ast/extractors/shared.d.ts +2 -3
- package/dist/engine/feature-ast/extractors/shared.js +2 -3
- package/dist/engine/feature-ast/parse.js +13 -13
- package/dist/engine/feature-ast/patch.js +4 -182
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +3 -0
- package/dist/engine/feature-ast/pattern-change-schema.js +2 -1
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +7 -0
- package/dist/engine/feature-ast/pattern-id-matchers.js +210 -0
- package/dist/engine/feature-ast/patterns.d.ts +11 -2
- package/dist/engine/feature-ast/patterns.js +43 -51
- package/dist/engine/feature-ast/render.js +50 -89
- package/dist/engine/feature-config-events-jobs.js +15 -12
- package/dist/engine/feature-entity-handlers.js +12 -5
- package/dist/engine/feature-manifest.d.ts +9 -9
- package/dist/engine/feature-manifest.js +6 -7
- package/dist/engine/feature-ui-extensions.d.ts +3 -3
- package/dist/engine/feature-ui-extensions.js +30 -22
- package/dist/engine/field-access.js +5 -6
- package/dist/engine/form-derivations.js +18 -7
- package/dist/engine/handler-field-references.js +1 -1
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.js +4 -4
- package/dist/engine/object-form.d.ts +1 -0
- package/dist/engine/object-form.js +14 -4
- package/dist/engine/ownership.js +3 -3
- package/dist/engine/parse-ref-target.js +5 -7
- package/dist/engine/pattern-library/index.js +2 -2
- package/dist/engine/pattern-library/library.js +2 -2
- package/dist/engine/pattern-library/types.js +3 -3
- package/dist/engine/pipeline.js +2 -2
- package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
- package/dist/engine/project-app-schema-for-roles.js +7 -5
- package/dist/engine/projection-helpers.js +9 -9
- package/dist/engine/qualified-name.js +2 -2
- package/dist/engine/registry-facade.js +1 -1
- package/dist/engine/registry-ingest.js +13 -13
- package/dist/engine/registry-state.js +17 -19
- package/dist/engine/registry-validate.js +12 -12
- package/dist/engine/run-in.js +2 -2
- package/dist/engine/run-pipeline.js +7 -0
- package/dist/engine/schema-builder.js +251 -233
- package/dist/engine/screen-filter-ops.js +17 -20
- package/dist/engine/screen-helpers.js +4 -3
- package/dist/engine/screen-kind.d.ts +7 -0
- package/dist/engine/screen-kind.js +1 -0
- package/dist/engine/state-machine.d.ts +12 -12
- package/dist/engine/state-machine.js +7 -7
- package/dist/engine/steps/_resolver-utils.js +4 -3
- package/dist/engine/steps/for-each.js +4 -4
- package/dist/engine/steps/unsafe-projection-delete.js +1 -1
- package/dist/engine/steps/unsafe-projection-upsert.js +4 -4
- package/dist/engine/steps/wait-for-event.js +4 -4
- package/dist/engine/steps/workflow-system-events.js +3 -3
- package/dist/engine/strip-disabled-features-from-app-schema.js +51 -14
- package/dist/engine/tier-resolver-extension.d.ts +29 -27
- package/dist/engine/tier-resolver-extension.js +26 -26
- package/dist/engine/transfer-adjacency.js +2 -2
- package/dist/engine/validate-projection-allowlist.js +9 -28
- package/dist/engine/walk-step-instances.d.ts +2 -0
- package/dist/engine/walk-step-instances.js +38 -0
- package/dist/engine/where-rule-lint.js +1 -1
- package/dist/engine/write-handler-qn-extract.js +1 -1
- package/dist/entrypoint/index.d.ts +4 -1
- package/dist/entrypoint/index.js +10 -4
- package/dist/env/index.d.ts +7 -6
- package/dist/env/index.js +10 -9
- package/dist/errors/docs-url.d.ts +1 -1
- package/dist/errors/docs-url.js +22 -2
- package/dist/errors/transition-details.js +7 -7
- package/dist/errors/write-error-info.d.ts +6 -6
- package/dist/errors/write-error-info.js +6 -6
- package/dist/es-ops/context.d.ts +9 -9
- package/dist/es-ops/context.js +29 -29
- package/dist/es-ops/index.js +7 -9
- package/dist/es-ops/operations-schema.js +4 -10
- package/dist/es-ops/runner.d.ts +11 -11
- package/dist/es-ops/runner.js +49 -53
- package/dist/es-ops/types.d.ts +55 -55
- package/dist/es-ops/types.js +11 -11
- package/dist/event-store/admin-api.js +7 -8
- package/dist/event-store/errors.js +1 -1
- package/dist/event-store/event-store.js +12 -6
- package/dist/event-store/rebuild-dead-letter.js +1 -1
- package/dist/files/bind-pending-file-refs.js +3 -3
- package/dist/files/create-file-ref-from-bytes.js +4 -1
- package/dist/files/feature.js +9 -10
- package/dist/files/file-handle.js +7 -9
- package/dist/files/file-ref-entity.js +15 -15
- package/dist/files/file-ref-table.js +7 -8
- package/dist/files/file-routes.d.ts +7 -0
- package/dist/files/file-routes.js +22 -13
- package/dist/files/in-memory-provider.js +8 -9
- package/dist/files/local-provider.js +18 -25
- package/dist/files/provider-resolver.d.ts +7 -7
- package/dist/files/resolve-content-type.js +43 -0
- package/dist/files/storage-tracking.js +2 -2
- package/dist/files/upload-ledger.js +7 -0
- package/dist/files/zip-stream.d.ts +12 -19
- package/dist/files/zip-stream.js +44 -63
- package/dist/i18n/required-surface-keys.d.ts +1 -1
- package/dist/i18n/required-surface-keys.js +188 -212
- package/dist/internal/stack-support.d.ts +2 -1
- package/dist/internal/stack-support.js +1 -1
- package/dist/jobs/job-runner-context.d.ts +32 -0
- package/dist/jobs/job-runner-context.js +305 -0
- package/dist/jobs/job-runner-execution.d.ts +7 -0
- package/dist/jobs/job-runner-execution.js +160 -0
- package/dist/jobs/job-runner-gates.d.ts +19 -0
- package/dist/jobs/job-runner-gates.js +198 -0
- package/dist/jobs/job-runner-helpers.d.ts +17 -3
- package/dist/jobs/job-runner-helpers.js +69 -4
- package/dist/jobs/job-runner-schedulers.d.ts +1 -1
- package/dist/jobs/job-runner-schedulers.js +3 -4
- package/dist/jobs/job-runner-scope.d.ts +44 -0
- package/dist/jobs/job-runner-scope.js +102 -0
- package/dist/jobs/job-runner-types.d.ts +12 -0
- package/dist/jobs/job-runner.d.ts +0 -1
- package/dist/jobs/job-runner.js +57 -669
- package/dist/lifecycle/lifecycle.js +3 -5
- package/dist/lifecycle/signal-handlers.js +5 -4
- package/dist/logging/utils.d.ts +2 -1
- package/dist/logging/utils.js +38 -10
- package/dist/migrations/index.js +1 -1
- package/dist/migrations/kumiko-drift.js +14 -13
- package/dist/migrations/pending-rebuilds.d.ts +21 -20
- package/dist/migrations/pending-rebuilds.js +27 -27
- package/dist/migrations/projection-table-index.d.ts +3 -3
- package/dist/migrations/projection-table-index.js +8 -8
- package/dist/observability/escape-hatch-report.d.ts +3 -0
- package/dist/observability/escape-hatch-report.js +12 -1
- package/dist/observability/metric-validator.js +1 -1
- package/dist/observability/metrics-handle.js +3 -3
- package/dist/pipeline/append-event-core.js +11 -2
- package/dist/pipeline/cascade-handler.d.ts +1 -1
- package/dist/pipeline/cascade-handler.js +165 -138
- package/dist/pipeline/dispatch-batch.js +2 -2
- package/dist/pipeline/dispatch-query.js +20 -13
- package/dist/pipeline/dispatch-shared.d.ts +14 -3
- package/dist/pipeline/dispatch-shared.js +67 -721
- package/dist/pipeline/dispatch-stream.js +1 -1
- package/dist/pipeline/dispatch-write.js +297 -190
- package/dist/pipeline/dispatcher-utils.d.ts +1 -1
- package/dist/pipeline/dispatcher-utils.js +1 -1
- package/dist/pipeline/event-consumer-state.js +2 -2
- package/dist/pipeline/event-dispatcher-admin.js +2 -1
- package/dist/pipeline/event-dispatcher-delivery.js +4 -6
- package/dist/pipeline/event-dispatcher.js +17 -28
- package/dist/pipeline/handler-context-auth.d.ts +9 -0
- package/dist/pipeline/handler-context-auth.js +54 -0
- package/dist/pipeline/handler-context-config.d.ts +14 -0
- package/dist/pipeline/handler-context-config.js +113 -0
- package/dist/pipeline/handler-context-db.d.ts +24 -0
- package/dist/pipeline/handler-context-db.js +149 -0
- package/dist/pipeline/handler-context-dispatch.d.ts +21 -0
- package/dist/pipeline/handler-context-dispatch.js +89 -0
- package/dist/pipeline/handler-context-events.d.ts +43 -0
- package/dist/pipeline/handler-context-events.js +237 -0
- package/dist/pipeline/handler-context-notify.d.ts +12 -0
- package/dist/pipeline/handler-context-notify.js +55 -0
- package/dist/pipeline/handler-context-observability.d.ts +7 -0
- package/dist/pipeline/handler-context-observability.js +21 -0
- package/dist/pipeline/handler-context-scope.d.ts +48 -0
- package/dist/pipeline/handler-context-scope.js +88 -0
- package/dist/pipeline/irreversible-operation-gate.js +1 -1
- package/dist/pipeline/lifecycle-pipeline.js +9 -9
- package/dist/pipeline/member-read-only-transaction.js +1 -3
- package/dist/pipeline/msp-rebuild.js +1 -1
- package/dist/pipeline/notify-scope.js +12 -1
- package/dist/pipeline/pre-handler-gates.js +20 -4
- package/dist/pipeline/pre-transaction-reservations.d.ts +1 -0
- package/dist/pipeline/pre-transaction-reservations.js +9 -3
- package/dist/pipeline/projection-rebuild.js +15 -13
- package/dist/pipeline/system-hooks.js +39 -41
- package/dist/pipeline/system-identity-switch.js +1 -3
- package/dist/pipeline/tenant-timezone-cache.js +1 -1
- package/dist/random/generate.d.ts +29 -29
- package/dist/random/generate.js +30 -30
- package/dist/random/words.js +20 -20
- package/dist/rate-limit/middleware.js +9 -5
- package/dist/redis/client.js +2 -2
- package/dist/redis/pubsub-signal.js +14 -17
- package/dist/schema-cli/apply-command.d.ts +2 -0
- package/dist/schema-cli/apply-command.js +97 -0
- package/dist/schema-cli/baseline-command.d.ts +2 -0
- package/dist/schema-cli/baseline-command.js +33 -0
- package/dist/schema-cli/generate-command.d.ts +2 -0
- package/dist/schema-cli/generate-command.js +90 -0
- package/dist/schema-cli/shared.d.ts +39 -0
- package/dist/schema-cli/shared.js +95 -0
- package/dist/schema-cli/status-command.d.ts +2 -0
- package/dist/schema-cli/status-command.js +73 -0
- package/dist/schema-cli/validate-boot-input.d.ts +5 -0
- package/dist/schema-cli/validate-boot-input.js +130 -0
- package/dist/schema-cli/validate-command.d.ts +2 -0
- package/dist/schema-cli/validate-command.js +130 -0
- package/dist/schema-cli.d.ts +2 -18
- package/dist/schema-cli.js +47 -510
- package/dist/search/index.js +4 -4
- package/dist/search/meilisearch-adapter.js +2 -1
- package/dist/search/purge-subject.js +4 -5
- package/dist/search/reindex-entity.js +6 -9
- package/dist/time/boot-tz-warning.d.ts +2 -2
- package/dist/time/boot-tz-warning.js +8 -8
- package/dist/time/iana.js +10 -10
- package/dist/time/index.js +9 -9
- package/dist/time/legacy-date.d.ts +2 -2
- package/dist/time/legacy-date.js +6 -8
- package/dist/time/polyfill.js +1 -1
- package/dist/time/tz-context.d.ts +1 -1
- package/dist/time/tz-context.js +1 -1
- package/dist/ui-types/app-schema.js +7 -7
- package/dist/ui-types/list-row-meta.js +4 -4
- package/dist/upgrade-cli.js +159 -130
- package/dist/utils/compare.js +1 -1
- package/package.json +5 -5
- package/src/changes.json +358 -0
- package/src/scripts/codemod/crypto-shredding-testing-move.ts +2 -2
- package/src/scripts/codemod/feature-layout.ts +10 -2
- package/src/scripts/codemod/migrate-cross-tenant.ts +1 -1
- package/src/scripts/codemod/migrate-open-to-all.ts +1 -1
- package/src/scripts/codemod/object-form.ts +41 -4
- package/src/scripts/codemod/package-merge.ts +58 -8
- package/src/scripts/codemod/pii-personal-migration.ts +192 -153
- package/src/scripts/codemod/testing-injection.ts +122 -42
- package/src/scripts/codemod/testing-move.ts +29 -7
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +2 -2
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { ENTITY_CONVENTION_QUERY_BRAND } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import { listAggregatePayloadSchema, } from "@cosmicdrift/kumiko-types/list-aggregate-types";
|
|
2
3
|
import * as z from "zod";
|
|
3
4
|
import { collectReferenceFields, enrichRowWithReferences, enrichWithReferences, } from "../db/eagerload.js";
|
|
4
5
|
import { createEventStoreExecutor } from "../db/event-store-executor.js";
|
|
6
|
+
import { answerListAggregate } from "../db/list-aggregate-labels.js";
|
|
5
7
|
import { buildEntityTable } from "../db/table-builder.js";
|
|
6
8
|
import { acknowledgeConventionCrossTenant, reportConventionCrossTenantUse, } from "../db/tenant-db.js";
|
|
7
9
|
import { InternalError } from "../errors/index.js";
|
|
8
10
|
import { isSystemIdentity } from "../pipeline/system-identity-switch.js";
|
|
9
11
|
import { assertUnreachable } from "../utils/index.js";
|
|
10
12
|
import { PAGED_QUERY_HANDLER_BRAND } from "./define-handler.js";
|
|
13
|
+
import { entityListRuntime } from "./entity-list-runtime-options.js";
|
|
11
14
|
import { assertReason } from "./escape-hatch-reason.js";
|
|
12
15
|
import { dropEmptyWriteOnlyValues } from "./field-access.js";
|
|
13
16
|
import { instructionFieldNames } from "./instruction-fields.js";
|
|
@@ -90,14 +93,14 @@ export const entityListSchema = z.object({
|
|
|
90
93
|
.object({
|
|
91
94
|
field: z.string(),
|
|
92
95
|
op: z.enum(["eq", "ne", "lt", "gt", "lte", "gte", "in"]),
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
+
// `unknown` at compile time; the server checks while building the WHERE
|
|
97
|
+
// clause that the value's type matches the field. z.unknown() accepts
|
|
98
|
+
// everything, so the type check occurs in executor.list.
|
|
96
99
|
value: z.unknown(),
|
|
97
100
|
})
|
|
98
101
|
.optional(),
|
|
99
|
-
// User-
|
|
100
|
-
// `filter
|
|
102
|
+
// User-selected faceted filters are dynamic and additive to the static
|
|
103
|
+
// `filter`; executor.list combines all of them with AND.
|
|
101
104
|
filters: z
|
|
102
105
|
.array(z.object({
|
|
103
106
|
field: z.string(),
|
|
@@ -105,6 +108,7 @@ export const entityListSchema = z.object({
|
|
|
105
108
|
value: z.unknown(),
|
|
106
109
|
}))
|
|
107
110
|
.optional(),
|
|
111
|
+
aggregate: listAggregatePayloadSchema.optional(),
|
|
108
112
|
});
|
|
109
113
|
function parseHandlerName(name, validVerbs) {
|
|
110
114
|
const colonIdx = name.indexOf(":");
|
|
@@ -277,10 +281,10 @@ export function defineEntityWriteHandler(name, entity, options) {
|
|
|
277
281
|
changes: dropEmptyWriteOnlyValues(entity, submitted.changes),
|
|
278
282
|
};
|
|
279
283
|
const streamTenantId = await foreignRowTenantFor(event.user, payload.id, db, ctx);
|
|
280
|
-
// skipUnchanged
|
|
284
|
+
// skipUnchanged: API-driven updates diff against the stored
|
|
281
285
|
// row so a resubmitted-but-identical field doesn't force a fresh
|
|
282
286
|
// pii/encrypted ciphertext. Direct executor.update() callers (e.g.
|
|
283
|
-
// KEK-rotation, the user-data-rights
|
|
287
|
+
// KEK-rotation, the user-data-rights backfill) don't go through
|
|
284
288
|
// this handler and keep today's always-re-encrypt behavior, which
|
|
285
289
|
// they rely on to intentionally force a fresh event/ciphertext.
|
|
286
290
|
return executor.update(payload, event.user, db, {
|
|
@@ -350,7 +354,7 @@ export function defineEntityQueryHandler(name, entity, options) {
|
|
|
350
354
|
const executor = createEventStoreExecutor(table, entity, { entityName });
|
|
351
355
|
let schema;
|
|
352
356
|
let handler;
|
|
353
|
-
//
|
|
357
|
+
// Server-side eager loading: when the entity has reference fields, the
|
|
354
358
|
// handler resolves the UUIDs against the referenced entities after the
|
|
355
359
|
// main query. The `_refs` property lands on every row; the renderer-side
|
|
356
360
|
// useReferenceLookup stays as a fallback (for apps that write custom
|
|
@@ -384,35 +388,19 @@ export function defineEntityQueryHandler(name, entity, options) {
|
|
|
384
388
|
case "list":
|
|
385
389
|
schema = entityListSchema;
|
|
386
390
|
handler = async (query, ctx) => {
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
// Runtime-Override holt das.
|
|
391
|
+
// Pass the SearchAdapter from ctx through so payload.search is executed
|
|
392
|
+
// against Meilisearch/InMem at runtime (remote combobox search). The
|
|
393
|
+
// executor is built at definition time and cannot know the adapter, so the
|
|
394
|
+
// runtime override supplies it.
|
|
392
395
|
const listPayload = query.payload; // @cast-boundary engine-payload
|
|
393
396
|
const db = dbFor(ctx);
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
...
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
// same runtime-override extension point as searchAdapter above.
|
|
400
|
-
referenceSearch: {
|
|
401
|
-
fields: ctx.registry.getSearchableReferences(entityName),
|
|
402
|
-
resolveEntity: (name) => ctx.registry.getEntity(name),
|
|
403
|
-
},
|
|
404
|
-
referenceSort: {
|
|
405
|
-
fields: ctx.registry.getSortableReferences(entityName),
|
|
406
|
-
resolveEntity: (name) => ctx.registry.getEntity(name),
|
|
407
|
-
},
|
|
408
|
-
parentVisibility: { entities: ctx.registry.getAllEntities() },
|
|
409
|
-
});
|
|
410
|
-
const eagerLoadViewer = {
|
|
411
|
-
user: query.user,
|
|
412
|
-
parentVisibility: { entities: ctx.registry.getAllEntities() },
|
|
413
|
-
};
|
|
397
|
+
const { runtimeOptions, eagerLoadViewer, resolveEntity } = entityListRuntime(ctx, entityName, query.user);
|
|
398
|
+
if (listPayload.aggregate !== undefined) {
|
|
399
|
+
return answerListAggregate(executor, { ...listPayload, aggregate: listPayload.aggregate }, query.user, db, runtimeOptions, { entity, resolveEntity, viewer: eagerLoadViewer });
|
|
400
|
+
}
|
|
401
|
+
const result = await executor.list(listPayload, query.user, db, runtimeOptions);
|
|
414
402
|
const enrichedRows = hasRefFields
|
|
415
|
-
? await enrichWithReferences(result.rows, entity,
|
|
403
|
+
? await enrichWithReferences(result.rows, entity, resolveEntity, db, eagerLoadViewer)
|
|
416
404
|
: result.rows;
|
|
417
405
|
return { ...result, rows: augmentDerivedFields(enrichedRows, entity) };
|
|
418
406
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ListRuntimeOptions } from "@cosmicdrift/kumiko-types/event-store-executor-types";
|
|
2
|
+
import type { EagerLoadEntityResolver, EagerLoadViewer } from "../db/eagerload.ts";
|
|
3
|
+
import type { HandlerContext, SessionUser } from "./types/index.ts";
|
|
4
|
+
export declare function entityListRuntime(ctx: HandlerContext, entityName: string, user: SessionUser): {
|
|
5
|
+
readonly runtimeOptions: ListRuntimeOptions;
|
|
6
|
+
readonly eagerLoadViewer: EagerLoadViewer;
|
|
7
|
+
readonly resolveEntity: EagerLoadEntityResolver;
|
|
8
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Registry access only exists at request time, so the searchable/sortable-reference
|
|
2
|
+
// caches, the entity resolver and the join-row read gate travel through the
|
|
3
|
+
// runtime-override extension point of the executor verbs.
|
|
4
|
+
export function entityListRuntime(ctx, entityName, user) {
|
|
5
|
+
const parentVisibility = { entities: ctx.registry.getAllEntities() };
|
|
6
|
+
const resolveEntity = (name) => ctx.registry.getEntity(name);
|
|
7
|
+
return {
|
|
8
|
+
runtimeOptions: {
|
|
9
|
+
...(ctx.searchAdapter !== undefined && { searchAdapter: ctx.searchAdapter }),
|
|
10
|
+
...(ctx.includeDeleted === true && { includeDeleted: true }),
|
|
11
|
+
referenceSearch: { fields: ctx.registry.getSearchableReferences(entityName), resolveEntity },
|
|
12
|
+
referenceSort: { fields: ctx.registry.getSortableReferences(entityName), resolveEntity },
|
|
13
|
+
parentVisibility,
|
|
14
|
+
},
|
|
15
|
+
eagerLoadViewer: { user, parentVisibility },
|
|
16
|
+
resolveEntity,
|
|
17
|
+
};
|
|
18
|
+
}
|
package/dist/engine/event-def.js
CHANGED
|
@@ -2,7 +2,7 @@ import { normalizeEventPiiSubject } from "@cosmicdrift/kumiko-types/handlers";
|
|
|
2
2
|
import { ZodObject } from "zod";
|
|
3
3
|
import { qn, toKebab } from "./qualified-name.js";
|
|
4
4
|
// A payload field that still holds null/undefined after parsing — the case
|
|
5
|
-
// where an event-PII owner field yields no subject at append time
|
|
5
|
+
// where an event-PII owner field yields no subject at append time.
|
|
6
6
|
// A `.default(...)` accepts undefined but parses to a value, so it is not
|
|
7
7
|
// absentable.
|
|
8
8
|
function isAbsentable(field) {
|
|
@@ -90,7 +90,7 @@ function validateEventPiiFields(featureName, eventName, schema, piiFields) {
|
|
|
90
90
|
*/
|
|
91
91
|
export function createEventDef(options) {
|
|
92
92
|
const { feature, name: eventName, schema } = options;
|
|
93
|
-
// Fail-closed PII stance gate
|
|
93
|
+
// Fail-closed PII stance gate — runs before anything else so
|
|
94
94
|
// an untyped JS consumer (no compiler to stop it) still can't register
|
|
95
95
|
// an event without declaring whether its payload carries personal data.
|
|
96
96
|
const missingStanceError = () => new Error(`[Feature ${feature}] defineEvent("${eventName}") must declare an explicit PII stance. Pass { piiFields: { <payloadField>: { personal: { of: "<userIdField>" } } } } for payload fields owned by a user (or { personal: "tenant" } / { personal: "self" } for tenant- or record-scoped subjects), or { piiFields: "none" } when the payload holds none.`);
|
|
@@ -8,14 +8,14 @@ import type { UserDataExtensionOptions } from "./extensions/user-data.ts";
|
|
|
8
8
|
import type { AssignableFromRole } from "./role-assignment.ts";
|
|
9
9
|
import { TENANT_TIER_RESOLVER_EXT, type TierResolverPlugin } from "./tier-resolver-extension.ts";
|
|
10
10
|
/**
|
|
11
|
-
* `userData` —
|
|
11
|
+
* `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Expected hook methods:
|
|
14
14
|
* - `export(userId, ctx) => Promise<UserDataExport>`
|
|
15
15
|
* - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Registered by: `user-data-rights`.
|
|
18
|
+
* Used by: every feature with user references (tasks, comments, files, ...).
|
|
19
19
|
*/
|
|
20
20
|
export declare const EXT_USER_DATA: "userData";
|
|
21
21
|
export declare const EXT_USER_DATA_ORDER: {
|
|
@@ -41,17 +41,16 @@ export declare const EXT_TENANT_DATA: "tenantData";
|
|
|
41
41
|
*/
|
|
42
42
|
export declare const EXT_STORAGE_PROVIDER: "storageProvider";
|
|
43
43
|
/**
|
|
44
|
-
* `fileProvider` —
|
|
44
|
+
* `fileProvider` — file-storage provider plugin selection (file-foundation).
|
|
45
45
|
*
|
|
46
|
-
* Provider
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
46
|
+
* Provider features (file-provider-s3, -inmemory, -s3-env) register an
|
|
47
|
+
* implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
|
|
48
|
+
* the per-tenant config key `provider` selects one at runtime. The framework
|
|
49
|
+
* resolver (`createFileProviderForTenant`) reads it so upload routes,
|
|
50
|
+
* `ctx.files`, and GDPR jobs all use the same store.
|
|
51
51
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* registrieren.
|
|
52
|
+
* The framework owns this contract to prevent string drift — file-foundation
|
|
53
|
+
* MUST register the extension point and config key under exactly these names.
|
|
55
54
|
*/
|
|
56
55
|
export declare const EXT_FILE_PROVIDER: "fileProvider";
|
|
57
56
|
export declare const FILE_PROVIDER_CONFIG_KEY: "file-foundation:config:provider";
|
|
@@ -85,7 +84,7 @@ export declare const EXT_DERIVATIVE_RENDERER: "derivativeRenderer";
|
|
|
85
84
|
* serves nothing for that entityType, not even a 403 (404, so existence isn't
|
|
86
85
|
* confirmed to an unauthorised caller).
|
|
87
86
|
*
|
|
88
|
-
* Registered/consumed by: `file-derivatives`' public variant route
|
|
87
|
+
* Registered/consumed by: `file-derivatives`' public variant route.
|
|
89
88
|
*/
|
|
90
89
|
export declare const EXT_DERIVATIVE_PUBLIC_PREDICATE: "derivativePublicPredicate";
|
|
91
90
|
/**
|
|
@@ -150,9 +149,9 @@ export declare const EXT_TENANT_LIFECYCLE_STATUS: "tenantLifecycleStatus";
|
|
|
150
149
|
export declare const EXT_ASSIGNABLE_ROLE: "assignableRole";
|
|
151
150
|
export declare const TENANT_MEMBERSHIPS_QUERY: "tenant:query:memberships";
|
|
152
151
|
/**
|
|
153
|
-
* Union
|
|
154
|
-
*
|
|
155
|
-
*
|
|
152
|
+
* Union of standardized extension names for the privacy surface.
|
|
153
|
+
* Not every extension in the system is included — other features can still
|
|
154
|
+
* register their own extension names.
|
|
156
155
|
*/
|
|
157
156
|
export type KumikoExtensionName = typeof EXT_USER_DATA | typeof EXT_TENANT_DATA | typeof EXT_STORAGE_PROVIDER | typeof EXT_SEARCH_ADAPTER | typeof EXT_EXTERNAL_RESOURCE | typeof EXT_INFRA_RESOURCE | typeof EXT_FILE_PROVIDER | typeof EXT_DERIVATIVE_RENDERER | typeof EXT_DERIVATIVE_PUBLIC_PREDICATE | typeof EXT_DERIVATIVE_OVERLAY_RESOLVER | typeof EXT_PRINCIPAL_STATUS | typeof EXT_TENANT_LIFECYCLE_STATUS | typeof EXT_ASSIGNABLE_ROLE;
|
|
158
157
|
/** The four `destroyTenant(tenantId, ctx)`-only resource-cleanup extension points. */
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
import { TENANT_TIER_RESOLVER_EXT } from "./tier-resolver-extension.js";
|
|
2
|
-
//
|
|
2
|
+
// Standardized extension names for privacy-hook axes.
|
|
3
3
|
//
|
|
4
|
-
// Features
|
|
4
|
+
// Features register extensions via:
|
|
5
5
|
// r.extendsRegistrar(EXT_USER_DATA, { hooks: { ... } });
|
|
6
6
|
//
|
|
7
|
-
//
|
|
7
|
+
// Other features attach to them via:
|
|
8
8
|
// r.useExtension(EXT_USER_DATA, "myEntity", { ...hookImpls });
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
// text-content
|
|
12
|
-
// Constants
|
|
13
|
-
//
|
|
14
|
-
// (validateExtensionUsages)
|
|
15
|
-
//
|
|
16
|
-
//
|
|
10
|
+
// Background: magic strings drift between bundled features (for example,
|
|
11
|
+
// text-content uses "Admin" as a role, while tenant-handler uses
|
|
12
|
+
// "TenantAdmin"). Constants are the single source of truth; string literals
|
|
13
|
+
// are gradually replaced at the relevant integration points. The boot
|
|
14
|
+
// validator (validateExtensionUsages) checks that every useExtension has a
|
|
15
|
+
// matching extendsRegistrar, so typos in constants cause a compile-time
|
|
16
|
+
// failure.
|
|
17
17
|
//
|
|
18
|
-
// Hook
|
|
19
|
-
//
|
|
20
|
-
// userData / tenantData →
|
|
21
|
-
// storageProvider →
|
|
22
|
-
// searchAdapter / external / →
|
|
18
|
+
// Hook signatures and boot validation for each extension axis are added by
|
|
19
|
+
// the feature that registers that axis:
|
|
20
|
+
// userData / tenantData → (user-data-rights, retention)
|
|
21
|
+
// storageProvider → (storage-encryption)
|
|
22
|
+
// searchAdapter / external / → (tenant-lifecycle)
|
|
23
23
|
// infraResource
|
|
24
24
|
/**
|
|
25
|
-
* `userData` —
|
|
25
|
+
* `userData` — user-data rights hooks (GDPR Articles 15, 17, and 20).
|
|
26
26
|
*
|
|
27
|
-
*
|
|
27
|
+
* Expected hook methods:
|
|
28
28
|
* - `export(userId, ctx) => Promise<UserDataExport>`
|
|
29
29
|
* - `delete(userId, strategy: "delete" | "anonymize", ctx) => Promise<void>`
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* Registered by: `user-data-rights`.
|
|
32
|
+
* Used by: every feature with user references (tasks, comments, files, ...).
|
|
33
33
|
*/
|
|
34
34
|
export const EXT_USER_DATA = "userData";
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// user-data-rights)
|
|
38
|
-
//
|
|
39
|
-
// (
|
|
35
|
+
// Ordering bands for EXT_USER_DATA hooks (forget pipeline). The contract was
|
|
36
|
+
// implicit across two packages (-100 in custom-fields, 0 in
|
|
37
|
+
// user-data-rights), so a host hook with order < REDACT_BEFORE_OWNER would run
|
|
38
|
+
// BEFORE the redactors and reintroduce the strip-after-owner-null bug
|
|
39
|
+
// (GDPR Article 17 regression). Rule: redactors < 0 <= owner-mutating hooks.
|
|
40
40
|
export const EXT_USER_DATA_ORDER = {
|
|
41
41
|
REDACT_BEFORE_OWNER: -100,
|
|
42
42
|
DEFAULT: 0,
|
|
@@ -60,23 +60,22 @@ export const EXT_TENANT_DATA = "tenantData";
|
|
|
60
60
|
*/
|
|
61
61
|
export const EXT_STORAGE_PROVIDER = "storageProvider";
|
|
62
62
|
/**
|
|
63
|
-
* `fileProvider` —
|
|
63
|
+
* `fileProvider` — file-storage provider plugin selection (file-foundation).
|
|
64
64
|
*
|
|
65
|
-
* Provider
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
65
|
+
* Provider features (file-provider-s3, -inmemory, -s3-env) register an
|
|
66
|
+
* implementation via `r.useExtension(EXT_FILE_PROVIDER, "<name>", { build })`;
|
|
67
|
+
* the per-tenant config key `provider` selects one at runtime. The framework
|
|
68
|
+
* resolver (`createFileProviderForTenant`) reads it so upload routes,
|
|
69
|
+
* `ctx.files`, and GDPR jobs all use the same store.
|
|
70
70
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* registrieren.
|
|
71
|
+
* The framework owns this contract to prevent string drift — file-foundation
|
|
72
|
+
* MUST register the extension point and config key under exactly these names.
|
|
74
73
|
*/
|
|
75
74
|
export const EXT_FILE_PROVIDER = "fileProvider";
|
|
76
|
-
//
|
|
77
|
-
// (
|
|
78
|
-
//
|
|
79
|
-
//
|
|
75
|
+
// Qualified config key registered by the file-foundation feature
|
|
76
|
+
// (format `<feature>:config:<key>`). This coupling is intentional: the
|
|
77
|
+
// framework resolver is below the feature and reads the key by string. Renaming
|
|
78
|
+
// the file-foundation feature MUST be accompanied by changing this constant.
|
|
80
79
|
export const FILE_PROVIDER_CONFIG_KEY = "file-foundation:config:provider";
|
|
81
80
|
// Two roles: boot gate (validateBoot requires its presence once file/image
|
|
82
81
|
// fields are in use) AND the ENV source of the config key above, bridged via
|
|
@@ -114,7 +113,7 @@ export const EXT_DERIVATIVE_RENDERER = "derivativeRenderer";
|
|
|
114
113
|
* serves nothing for that entityType, not even a 403 (404, so existence isn't
|
|
115
114
|
* confirmed to an unauthorised caller).
|
|
116
115
|
*
|
|
117
|
-
* Registered/consumed by: `file-derivatives`' public variant route
|
|
116
|
+
* Registered/consumed by: `file-derivatives`' public variant route.
|
|
118
117
|
*/
|
|
119
118
|
export const EXT_DERIVATIVE_PUBLIC_PREDICATE = "derivativePublicPredicate";
|
|
120
119
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// reads the { escapeHatch: { reason } } convention off a
|
|
2
2
|
// `r.useExtension(...)` registration's untyped options bag. Registration-time
|
|
3
3
|
// validation (feature-ui-extensions.ts's useExtension) already rejects an
|
|
4
4
|
// empty reason, but options stays `Record<string, unknown>`, so orchestrators
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// Hook
|
|
1
|
+
// Hook signature types for EXT_TENANT_DATA (GDPR tenant-scoped destruction).
|
|
2
2
|
//
|
|
3
3
|
// Mirror of engine/extensions/user-data.ts at tenant granularity.
|
|
4
|
-
// tenant-lifecycle orchestrates
|
|
4
|
+
// tenant-lifecycle orchestrates destruction via registry.getExtensionUsages(EXT_TENANT_DATA).
|
|
5
5
|
export function isTenantDataExtensionHooks(o) {
|
|
6
6
|
return typeof o === "object" && o !== null && "destroy" in o && typeof o.destroy === "function";
|
|
7
7
|
}
|
|
@@ -2,15 +2,15 @@ import type { TenantDb } from "../../db/tenant-db.ts";
|
|
|
2
2
|
import type { Registry, TenantId } from "../types/index.ts";
|
|
3
3
|
type UserId = string;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* - "delete":
|
|
7
|
-
* - "anonymize":
|
|
8
|
-
* "[Geloescht]" —
|
|
9
|
-
*
|
|
5
|
+
* Strategy for the forget path per entity:
|
|
6
|
+
* - "delete": Physically remove the row (profile, personal notes, sessions).
|
|
7
|
+
* - "anonymize": Set the user reference to null and display fields to
|
|
8
|
+
* "[Geloescht]" — typical for shared data (tasks,
|
|
9
|
+
* comments) so other users do not lose the history.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* The cleanup job applies the retention policy per entity to select the
|
|
12
|
+
* strategy. blockDelete entries ALWAYS use `anonymize` to respect retention
|
|
13
|
+
* obligations.
|
|
14
14
|
*/
|
|
15
15
|
export type UserDataDeleteStrategy = "delete" | "anonymize";
|
|
16
16
|
/**
|
|
@@ -27,7 +27,7 @@ export type UserDataDeleteStrategy = "delete" | "anonymize";
|
|
|
27
27
|
*/
|
|
28
28
|
export type TenantUserModel = "single-user" | "multi-user";
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* `db` is a tenant-filtered `TenantDb`, bound to `tenantId`
|
|
31
31
|
* (or the per-user sub-tx in the forget path). Unfiltered access needs
|
|
32
32
|
* `escapeHatch: { reason }` on the `r.useExtension(...)` registration,
|
|
33
33
|
* then `ctx.db.unsafeRaw()`.
|
|
@@ -82,15 +82,15 @@ export interface UserDataHookCtx {
|
|
|
82
82
|
readonly userEmailBeforeDelete?: string | null;
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Feature/entity snippet included in the export bundle. The export job
|
|
86
|
+
* orchestrates JSON serialization; hooks return plain records.
|
|
87
87
|
*/
|
|
88
88
|
export interface UserDataExportSnippet {
|
|
89
89
|
readonly entity: string;
|
|
90
90
|
readonly rows: ReadonlyArray<Record<string, unknown>>;
|
|
91
91
|
/**
|
|
92
|
-
* Optional
|
|
93
|
-
*
|
|
92
|
+
* Optional signed URLs for file references. user-data-rights puts them
|
|
93
|
+
* separately in the ZIP under `files/`. Other hooks leave this empty.
|
|
94
94
|
*/
|
|
95
95
|
readonly fileRefs?: ReadonlyArray<{
|
|
96
96
|
readonly fileRefId: string;
|
|
@@ -99,22 +99,21 @@ export interface UserDataExportSnippet {
|
|
|
99
99
|
}>;
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
-
* Export
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* Side-Effects.
|
|
102
|
+
* Export hook: collects all data belonging to a user for an entity. It is
|
|
103
|
+
* called once per registered entity by the data export job. Idempotent — it
|
|
104
|
+
* can be called multiple times without side effects.
|
|
106
105
|
*
|
|
107
|
-
*
|
|
108
|
-
* `r.useExtension(EXT_USER_DATA, ...)
|
|
106
|
+
* The data-rights runner invokes this by iterating over all
|
|
107
|
+
* `r.useExtension(EXT_USER_DATA, ...)` registrations.
|
|
109
108
|
*/
|
|
110
109
|
export type UserDataExportHook = (ctx: UserDataHookCtx) => Promise<UserDataExportSnippet | null>;
|
|
111
110
|
/**
|
|
112
|
-
* Forget
|
|
113
|
-
*
|
|
114
|
-
*
|
|
111
|
+
* Forget hook: deletes or anonymizes entity rows belonging to a user. The
|
|
112
|
+
* cleanup job supplies the strategy, which may differ by entity because of
|
|
113
|
+
* the retention policy.
|
|
115
114
|
*
|
|
116
|
-
* Idempotent —
|
|
117
|
-
*
|
|
115
|
+
* Idempotent — if the job runs twice during crash recovery, the hook must not
|
|
116
|
+
* crash.
|
|
118
117
|
*
|
|
119
118
|
* Return additive to `void`: a hook can return `{status:"ok"}` or
|
|
120
119
|
* `{status:"incomplete", reason}` to signal a partial success to the
|
|
@@ -7,13 +7,13 @@ export declare function createTextField<R extends true | false = false>(override
|
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Long-form text field for source-code, markdown, blog-posts, email-
|
|
10
|
-
* templates — anything that can be megabytes large.
|
|
11
|
-
* from `text`:
|
|
12
|
-
* DB
|
|
10
|
+
* templates — anything that can be megabytes large. Its type-level API
|
|
11
|
+
* differs from `text`: it has no sortable/searchable/filterable/format options.
|
|
12
|
+
* The DB mapping is identical to text (`PG text` is unbounded).
|
|
13
13
|
*
|
|
14
|
-
* Soft-cap default:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Soft-cap default: no maxLength (`PG text` has a 1 GB hard limit).
|
|
15
|
+
* Set an explicit `maxLength` to reject an accidental browser paste early
|
|
16
|
+
* (for example, `1_000_000 = 1 MB`).
|
|
17
17
|
*/
|
|
18
18
|
/**
|
|
19
19
|
* Read-time computed field for `EntityDefinition.derivedFields` (NOT `fields`).
|
|
@@ -112,12 +112,12 @@ export declare function createDateField<R extends true | false = false>(override
|
|
|
112
112
|
required: R;
|
|
113
113
|
};
|
|
114
114
|
/**
|
|
115
|
-
* UTC
|
|
116
|
-
* (createdAt, loginAt, actualPickupAt). Temporal.Instant
|
|
115
|
+
* UTC instant for events occurring at a specific point in time
|
|
116
|
+
* (createdAt, loginAt, actualPickupAt). Uses Temporal.Instant internally.
|
|
117
117
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
118
|
+
* With `locatedBy: "<name>Tz"`, the field becomes a wall-clock pair for an
|
|
119
|
+
* appointment at a location — prefer `createLocatedTimestampField()` instead,
|
|
120
|
+
* which creates one atomic field rather than a loosely connected pair.
|
|
121
121
|
*/
|
|
122
122
|
export declare function createTimestampField<R extends true | false = false>(overrides?: Partial<Omit<TimestampFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
|
|
123
123
|
required?: R;
|
|
@@ -125,8 +125,9 @@ export declare function createTimestampField<R extends true | false = false>(ove
|
|
|
125
125
|
required: R;
|
|
126
126
|
};
|
|
127
127
|
/**
|
|
128
|
-
* IANA-
|
|
129
|
-
*
|
|
128
|
+
* IANA time-zone name (for example, "Europe/Berlin"). The boot/schema
|
|
129
|
+
* validator checks it using `Intl.supportedValuesOf("timeZone")` during the
|
|
130
|
+
* Zod step.
|
|
130
131
|
*/
|
|
131
132
|
export declare function createTzField<R extends true | false = false>(overrides?: Partial<Omit<TzFieldDef, "type" | "required" | keyof ResolvedPiiFlags>> & PersonalAnnotationsNoFind & {
|
|
132
133
|
required?: R;
|