@cosmicdrift/kumiko-samples 0.385.0 → 0.387.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/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +2 -2
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
- package/packages/bundled-features/src/audit/screens.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
- package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
- package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
- package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
- package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
- package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
- package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
- package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
- package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
- package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
- package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
- package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
- package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
- package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
- package/packages/bundled-features/src/custom-fields/events.ts +7 -8
- package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
- package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
- package/packages/bundled-features/src/data-retention/feature.ts +11 -18
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
- package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
- package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
- package/packages/bundled-features/src/data-retention/presets.ts +18 -23
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
- package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
- package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
- package/packages/bundled-features/src/delivery/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
- package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
- package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
- package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
- package/packages/bundled-features/src/files/feature.ts +6 -6
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
- package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/tree.ts +5 -5
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/entity.ts +3 -3
- package/packages/bundled-features/src/form-draft/feature.ts +4 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
- package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
- package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
- package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
- package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
- package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/feature.ts +6 -7
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
- package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
- package/packages/bundled-features/src/jobs/screens.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/entity.ts +5 -5
- package/packages/bundled-features/src/ledger/feature.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
- package/packages/bundled-features/src/ledger/recurring.ts +12 -12
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
- package/packages/bundled-features/src/ledger/web/index.ts +7 -7
- package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
- package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
- package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
- package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
- package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
- package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
- package/packages/bundled-features/src/managed-pages/table.ts +16 -15
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/notes-history/entity.ts +4 -4
- package/packages/bundled-features/src/notes-history/feature.ts +2 -2
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/page-render/layout.ts +9 -9
- package/packages/bundled-features/src/page-render/markdown.ts +11 -11
- package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
- package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
- package/packages/bundled-features/src/seo/feature.ts +3 -3
- package/packages/bundled-features/src/sessions/constants.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +9 -9
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
- package/packages/bundled-features/src/sessions/screens.ts +2 -2
- package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
- package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
- package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
- package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
- package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
- package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
- package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
- package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
- package/packages/bundled-features/src/tags/feature.ts +3 -3
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +10 -10
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
- package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
- package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
- package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
- package/packages/bundled-features/src/tenant/screens.ts +1 -1
- package/packages/bundled-features/src/tenant/seeding.ts +19 -18
- package/packages/bundled-features/src/tenant/testing.ts +5 -6
- package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
- package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
- package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
- package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
- package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
- package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
- package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
- package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
- package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
- package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
- package/packages/bundled-features/src/user/schema/user.ts +45 -44
- package/packages/bundled-features/src/user/seeding.ts +40 -40
- package/packages/bundled-features/src/user/testing.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
- package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
- package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
- package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
- package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
- package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
- package/packages/bundled-features/src/user-profile/index.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
- package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
// verifyAndParseStripeWebhook — Stripe-
|
|
2
|
-
// event
|
|
3
|
-
// `verifyAndParseWebhook
|
|
1
|
+
// verifyAndParseStripeWebhook — Stripe-specific signature verification +
|
|
2
|
+
// event mapping. Registered by the plugin build (feature.ts) as
|
|
3
|
+
// `verifyAndParseWebhook`.
|
|
4
4
|
//
|
|
5
5
|
// **Steps:**
|
|
6
|
-
// 1.
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// 1. Verify the signature via stripe.webhooks.constructEvent (HMAC-SHA-256
|
|
7
|
+
// against rawBody + Stripe-Signature header). Throws on mismatch or
|
|
8
|
+
// timestamps older than 5 minutes (replay protection).
|
|
9
9
|
// 1b. checkout.session.completed / .async_payment_succeeded branch off
|
|
10
10
|
// here into a PaymentEvent (one-off-payment, own aggregate) — see
|
|
11
|
-
// "One-off-payment" section below. Everything else falls through.
|
|
12
|
-
// 2. Event-type
|
|
13
|
-
// SubscriptionEventTypes
|
|
14
|
-
//
|
|
15
|
-
// 3. Stripe
|
|
16
|
-
// (status
|
|
11
|
+
// the "One-off-payment" section below. Everything else falls through.
|
|
12
|
+
// 2. Event-type filter: only the 5 event types mapped to
|
|
13
|
+
// SubscriptionEventTypes continue; everything else returns null
|
|
14
|
+
// (the foundation responds with 200 ignored).
|
|
15
|
+
// 3. Normalize the Stripe payload into a SubscriptionEvent
|
|
16
|
+
// (status mapping, tenant ID from metadata, price-to-tier lookup).
|
|
17
17
|
//
|
|
18
|
-
// **Runtime
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// sig-verify, kein split-brain.
|
|
18
|
+
// **Runtime keys (pre-tenant):** the API key and webhook secret no longer
|
|
19
|
+
// come from a mount-time closure; they are resolved from `StripeWebhookRuntime`
|
|
20
|
+
// at webhook time. The foundation webhook handler passes a system-scoped
|
|
21
|
+
// SecretsContext as the third argument; the runtime reads both keys from it
|
|
22
|
+
// (unaudited, system-internal), falling back to the factory options. This
|
|
23
|
+
// allows key rotation without a redeploy, and the invoice lazy-fetch below
|
|
24
|
+
// uses the same rotated client as signature verification, avoiding split-brain.
|
|
26
25
|
//
|
|
27
26
|
// **Invoice-event lazy-fetch:**
|
|
28
|
-
// Invoice payloads carry only the subscription
|
|
29
|
-
//
|
|
27
|
+
// Invoice payloads carry only the subscription ID (Stripe does not expand
|
|
28
|
+
// subscriptions in webhooks), so the plugin lazy-fetches via
|
|
30
29
|
// `stripe.subscriptions.retrieve(subId)` to get the full subscription for
|
|
31
30
|
// status/tier/period-end mapping. resource_missing (deleted between webhook
|
|
32
|
-
// and
|
|
31
|
+
// and retrieval) returns null; any other Stripe error becomes 503 so Stripe
|
|
33
32
|
// redelivers.
|
|
34
33
|
|
|
35
34
|
import type {
|
|
@@ -77,18 +76,18 @@ function transientProviderRejection(error: unknown): ExtraRouteRejection {
|
|
|
77
76
|
// =============================================================================
|
|
78
77
|
|
|
79
78
|
export type StripeWebhookOptions = {
|
|
80
|
-
/** Price-to-tier
|
|
81
|
-
*
|
|
82
|
-
*
|
|
79
|
+
/** Price-to-tier map. The plugin reads the price ID from the event and
|
|
80
|
+
* maps it to a tier name. Returns null when the price ID is not mapped.
|
|
81
|
+
* App-specific and remains a factory option, not a secret. */
|
|
83
82
|
readonly priceToTier: Readonly<Record<string, string>>;
|
|
84
83
|
};
|
|
85
84
|
|
|
86
85
|
/**
|
|
87
|
-
* Stripe
|
|
88
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
89
|
-
* HandlerContext;
|
|
90
|
-
* Stripe
|
|
91
|
-
* system
|
|
86
|
+
* Stripe webhook handler implementing the plugin contract
|
|
87
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
88
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
89
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
90
|
+
* system SecretsContext (third argument).
|
|
92
91
|
*/
|
|
93
92
|
export function verifyAndParseStripeWebhook(
|
|
94
93
|
runtime: StripeWebhookRuntime,
|
|
@@ -104,16 +103,16 @@ export function verifyAndParseStripeWebhook(
|
|
|
104
103
|
throw new Error("subscription-stripe: stripe-signature header missing");
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
// 0.
|
|
108
|
-
// secret (
|
|
109
|
-
// options.
|
|
106
|
+
// 0. Resolve at runtime: obtain the API key (for the client and lazy fetch)
|
|
107
|
+
// and webhook secret (for signature verification) from system secrets,
|
|
108
|
+
// falling back to the factory options. Throws if neither is configured.
|
|
110
109
|
const { stripe, webhookSecret } = await runtime.resolve(systemSecrets);
|
|
111
110
|
|
|
112
|
-
// 1.
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
// payment
|
|
116
|
-
// path
|
|
111
|
+
// 1. Verify the signature. constructEvent throws on a mismatch (invalid
|
|
112
|
+
// signature) or timestamp-tolerance violation (default: 5 minutes).
|
|
113
|
+
// The foundation maps the thrown error to HTTP 401. This applies to
|
|
114
|
+
// BOTH branches below: the payment branch is selected only AFTER this
|
|
115
|
+
// check, so no path bypasses signature verification.
|
|
117
116
|
let event: Stripe.Event;
|
|
118
117
|
try {
|
|
119
118
|
event = await stripe.webhooks.constructEventAsync(rawBody, sigHeader, webhookSecret);
|
|
@@ -131,30 +130,29 @@ export function verifyAndParseStripeWebhook(
|
|
|
131
130
|
return await parsePaymentEvent(event, stripe);
|
|
132
131
|
}
|
|
133
132
|
|
|
134
|
-
// 2. Event-type
|
|
133
|
+
// 2. Event-type filter — only 5 event types are supported.
|
|
135
134
|
const normalizedType = mapStripeEventType(event.type);
|
|
136
135
|
if (!normalizedType) {
|
|
137
136
|
return null; // foundation returnt 200 ignored
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
// 3.
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
// oder via lazy-fetch (invoice-events).
|
|
139
|
+
// 3. Extract the payload. Stripe uses different data.object shapes
|
|
140
|
+
// depending on event.type. Extract subscription data either directly
|
|
141
|
+
// (subscription events) or through a lazy fetch (invoice events).
|
|
144
142
|
const sub = await extractSubscriptionFromEvent(event, stripe);
|
|
145
143
|
if (!sub) {
|
|
146
|
-
// event
|
|
147
|
-
//
|
|
144
|
+
// The event type passed the 5-item filter, but its payload shape did not
|
|
145
|
+
// match — treat this as Stripe SDK schema drift and return null defensively.
|
|
148
146
|
return null;
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
// 4.
|
|
152
|
-
// `metadata.tenantId`
|
|
149
|
+
// 4. Resolve the tenant from metadata. The app builder sets
|
|
150
|
+
// `metadata.tenantId` when calling createCheckoutSession.
|
|
153
151
|
const tenantId = sub.metadata?.["tenantId"];
|
|
154
152
|
if (!tenantId || tenantId.length === 0) {
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
153
|
+
// A subscription without tenant metadata cannot be created without tenant
|
|
154
|
+
// resolution. Drop the event silently (the foundation responds with 200
|
|
155
|
+
// ignored). This is an app-owner error, not a foundation error.
|
|
158
156
|
return null;
|
|
159
157
|
}
|
|
160
158
|
|
|
@@ -218,7 +216,7 @@ export function mapStripeSubscriptionState(
|
|
|
218
216
|
const periodEndUnixSec = sub.items.data[0]?.current_period_end ?? 0;
|
|
219
217
|
// Stripe returns Unix-seconds; Temporal.Instant.fromEpochMilliseconds
|
|
220
218
|
// expects ms. Multiply, then ISO. (No-Date-API-Guard forbids
|
|
221
|
-
// `new Date()` — static import above, not the ambient global
|
|
219
|
+
// `new Date()` — static import above, not the ambient global.)
|
|
222
220
|
const currentPeriodEnd = Temporal.Instant.fromEpochMilliseconds(
|
|
223
221
|
periodEndUnixSec * 1000,
|
|
224
222
|
).toString();
|
|
@@ -264,9 +262,9 @@ export function mapStripeEventType(stripeType: string): SubscriptionEventType |
|
|
|
264
262
|
}
|
|
265
263
|
}
|
|
266
264
|
|
|
267
|
-
/** Stripe
|
|
268
|
-
* incomplete
|
|
269
|
-
*
|
|
265
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
266
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
267
|
+
* an invalid status string must not be stored in the database. */
|
|
270
268
|
export function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): SubscriptionStatus {
|
|
271
269
|
switch (stripeStatus) {
|
|
272
270
|
case "active":
|
|
@@ -293,9 +291,9 @@ export function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): Subsc
|
|
|
293
291
|
}
|
|
294
292
|
}
|
|
295
293
|
|
|
296
|
-
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
294
|
+
/** Gets the subscription from the event. Subscription events include it
|
|
295
|
+
* directly in data.object; invoice events include only the subscription ID
|
|
296
|
+
* and require a lazy fetch via stripe.subscriptions.retrieve. */
|
|
299
297
|
// @wrapper-known semantic-alias
|
|
300
298
|
async function extractSubscriptionFromEvent(
|
|
301
299
|
event: Stripe.Event,
|
|
@@ -308,16 +306,16 @@ async function extractSubscriptionFromEvent(
|
|
|
308
306
|
return event.data.object as Stripe.Subscription; // @cast-boundary engine-bridge
|
|
309
307
|
case StripeEventTypes.invoicePaid:
|
|
310
308
|
case StripeEventTypes.invoicePaymentFailed: {
|
|
311
|
-
// Lazy-fetch
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
309
|
+
// Lazy-fetch the subscription. invoice.subscription is a string ID because
|
|
310
|
+
// Stripe webhooks do not expand it automatically. Fetch the full
|
|
311
|
+
// subscription so downstream status, tier via priceId, and period-end
|
|
312
|
+
// mapping remain consistent.
|
|
315
313
|
const invoice = event.data.object as Stripe.Invoice; // @cast-boundary engine-bridge
|
|
316
314
|
const subRef = (invoice as { subscription?: string | Stripe.Subscription | null }) // @cast-boundary engine-payload
|
|
317
315
|
.subscription;
|
|
318
316
|
if (!subRef) {
|
|
319
|
-
//
|
|
320
|
-
// recurring
|
|
317
|
+
// An invoice without a subscription reference is a one-shot invoice, not a
|
|
318
|
+
// recurring invoice. It is outside this domain and should be ignored.
|
|
321
319
|
return null;
|
|
322
320
|
}
|
|
323
321
|
const subId = typeof subRef === "string" ? subRef : subRef.id;
|
|
@@ -150,9 +150,9 @@ export type TagsFeatureOptions = {
|
|
|
150
150
|
/** Row-level ownership on the tag-assignment rows themselves — orthogonal to
|
|
151
151
|
* `access`, which only gates whether a caller may dispatch assign/remove/list
|
|
152
152
|
* at all. `ownership.read` is no longer what keeps a caller from reading
|
|
153
|
-
* assignments on host entities they can't see: that gate is default-on
|
|
154
|
-
*
|
|
155
|
-
*
|
|
153
|
+
* assignments on host entities they can't see: that gate is default-on and
|
|
154
|
+
* derives from the entity's `parentRef`. Use `ownership.read` for an
|
|
155
|
+
* ADDITIONAL row rule on the assignment row itself; it is AND-ed with the
|
|
156
156
|
* host-visibility gate, never a replacement for it. Applies only to
|
|
157
157
|
* `tag-assignment`; the `tag` catalog stays tenant-wide by design.
|
|
158
158
|
*
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import { DEFAULT_TAG_ACCESS, TAGS_EDIT_SCREEN_ID, TAGS_SCREEN_ID } from "./web/constants.ts";
|
|
8
8
|
|
|
9
|
-
// Declarative catalog screens
|
|
9
|
+
// Declarative catalog screens. Access matches create/update/
|
|
10
10
|
// delete so createTagsFeature({ access|roles }) stays consistent. TagManager
|
|
11
11
|
// remains for TagPicker/TagSection — only the standalone admin screen moved.
|
|
12
12
|
|
|
@@ -232,20 +232,20 @@ async function fetchTemplate(
|
|
|
232
232
|
{ limit: 1 },
|
|
233
233
|
);
|
|
234
234
|
// @cast-boundary db-row — db.select returnt unbenanntes unknown[],
|
|
235
|
-
//
|
|
235
|
+
// The row shape is guaranteed by templateResourcesTable + buildBaseColumns.
|
|
236
236
|
return (rows[0] as TemplateResourceRow | undefined) ?? null;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
function toPublic(row: TemplateResourceRow): TemplateResource {
|
|
240
240
|
// @cast-boundary db-row — Drizzle-Schema typisiert kind/contentFormat/
|
|
241
|
-
// scope/status
|
|
242
|
-
//
|
|
241
|
+
// scope/status as generic text. Database CHECK constraints restrict
|
|
242
|
+
// them to the union types; the cast asserts that schema knowledge.
|
|
243
243
|
const kind = row.kind as TemplateKind;
|
|
244
|
-
// @cast-boundary db-row —
|
|
244
|
+
// @cast-boundary db-row — see kind.
|
|
245
245
|
const contentFormat = row.contentFormat as ContentFormat;
|
|
246
|
-
// @cast-boundary db-row —
|
|
246
|
+
// @cast-boundary db-row — see kind.
|
|
247
247
|
const scope = row.scope as "system" | "tenant";
|
|
248
|
-
// @cast-boundary db-row —
|
|
248
|
+
// @cast-boundary db-row — see kind.
|
|
249
249
|
const status = row.status as "draft" | "active" | "archived";
|
|
250
250
|
const linkedEntries = parseLinkedResourceEntries(row.linkedResources);
|
|
251
251
|
return {
|
|
@@ -286,7 +286,7 @@ function parseJson(raw: string | null): Record<string, unknown> {
|
|
|
286
286
|
try {
|
|
287
287
|
const parsed = JSON.parse(raw);
|
|
288
288
|
// @cast-boundary engine-payload — JSON.parse returnt unknown, typeof-Guard
|
|
289
|
-
//
|
|
289
|
+
// narrows it to object; Record<string, unknown> is the minimal common shape.
|
|
290
290
|
return typeof parsed === "object" && parsed !== null ? (parsed as Record<string, unknown>) : {};
|
|
291
291
|
} catch {
|
|
292
292
|
return {};
|
|
@@ -302,14 +302,14 @@ export class TemplateNotFoundError extends Error {
|
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
-
// Single
|
|
306
|
-
// Pattern
|
|
305
|
+
// Single source of truth for "this handler requires template-resolver".
|
|
306
|
+
// Pattern symmetric with requireTextContent.
|
|
307
307
|
export function requireTemplateResolver(
|
|
308
308
|
ctx: { readonly templateResolver?: TemplateResolverApi } | object,
|
|
309
309
|
callerName: string,
|
|
310
310
|
): TemplateResolverApi {
|
|
311
311
|
// @cast-boundary engine-bridge — templateResolver kommt per extraContext
|
|
312
|
-
//
|
|
312
|
+
// from App-Bootstrap; the framework container does not know this field on its own.
|
|
313
313
|
const api = (ctx as { templateResolver?: TemplateResolverApi }).templateResolver;
|
|
314
314
|
if (!api) {
|
|
315
315
|
throw new InternalError({
|
|
@@ -6,11 +6,11 @@ import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.ts"
|
|
|
6
6
|
import { draftViewerTenantId, isHiddenSystemDraft, toWorkingRow } from "../template-draft.ts";
|
|
7
7
|
import { isSystemOnlyTemplateHiddenFrom } from "../template-system-only.ts";
|
|
8
8
|
|
|
9
|
-
// Admin
|
|
10
|
-
// archived
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
9
|
+
// Admin lookup for the UI editing flow. Returns the raw template, including draft/
|
|
10
|
+
// archived status. Tenant isolation: users see only templates belonging to their own
|
|
11
|
+
// tenant or SYSTEM_TENANT (system defaults are publicly readable); ctx.db is tenant-
|
|
12
|
+
// scoped for every role, so the check below is defense in depth. Anonymous access is
|
|
13
|
+
// excluded—public reads go through resolveTemplate in the API, not here.
|
|
14
14
|
export const findByIdQuery = defineQueryHandler({
|
|
15
15
|
name: "find-by-id",
|
|
16
16
|
schema: z.object({ id: z.string().min(1) }),
|
|
@@ -40,7 +40,7 @@ export const listQuery = defineQueryHandler({
|
|
|
40
40
|
where["status"] = query.payload.status;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// @cast-boundary db-row — selectMany
|
|
43
|
+
// @cast-boundary db-row — selectMany returns unknown[]; Row shape is
|
|
44
44
|
// durch templateResourcesTable + buildBaseColumns garantiert.
|
|
45
45
|
const rows = (await selectMany(ctx.db, templateResourcesTable, where, {
|
|
46
46
|
limit: 500,
|
|
@@ -38,8 +38,8 @@ export const titleSchema = z.string().min(1).max(200);
|
|
|
38
38
|
export const contentFormatSchema = z.enum(CONTENT_FORMATS);
|
|
39
39
|
export const statusSchema = z.enum(TEMPLATE_STATUSES);
|
|
40
40
|
|
|
41
|
-
// Common
|
|
42
|
-
//
|
|
41
|
+
// Common upsert payload shared by upsertSystem and upsertTenant.
|
|
42
|
+
// Only ACL and tenantId determination differ.
|
|
43
43
|
export const upsertPayloadSchema = z.object({
|
|
44
44
|
slug: templateSlugSchema,
|
|
45
45
|
kind: kindSchema,
|
|
@@ -258,9 +258,9 @@ export async function writeTemplateRow(
|
|
|
258
258
|
{ streamTenantId },
|
|
259
259
|
);
|
|
260
260
|
if (!result.isSuccess) return result;
|
|
261
|
-
// @cast-boundary db-row — executor.create
|
|
262
|
-
// INSERT RETURNING;
|
|
263
|
-
//
|
|
261
|
+
// @cast-boundary db-row — executor.create returns a row from
|
|
262
|
+
// INSERT RETURNING; the { id } shape is guaranteed because the primary key is in the
|
|
263
|
+
// RETURNING clause.
|
|
264
264
|
const createdRow = result.data as { id: string | number };
|
|
265
265
|
return {
|
|
266
266
|
isSuccess: true,
|
|
@@ -3,10 +3,9 @@ import { resolveTemplateVariables } from "../template-validation.ts";
|
|
|
3
3
|
import { upsertPayloadSchema } from "./shared.ts";
|
|
4
4
|
import { writeTemplateRow } from "./template-write.ts";
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
// scope='system'.
|
|
8
|
-
//
|
|
9
|
-
// Overrides.
|
|
6
|
+
// Creates or updates a system template under SYSTEM_TENANT_ID with
|
|
7
|
+
// scope='system'. Only SystemAdmin can change these global defaults;
|
|
8
|
+
// TenantAdmin uses upsertTenant for overrides instead.
|
|
10
9
|
export const upsertSystemWrite = defineWriteHandler({
|
|
11
10
|
name: "upsert-system",
|
|
12
11
|
schema: upsertPayloadSchema,
|
|
@@ -9,11 +9,10 @@ import { resolveTemplateVariables } from "../template-validation.ts";
|
|
|
9
9
|
import { upsertPayloadSchema } from "./shared.ts";
|
|
10
10
|
import { writeTemplateRow } from "./template-write.ts";
|
|
11
11
|
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// Tenant-Templates kuratiert).
|
|
12
|
+
// Creates or updates a tenant override under event.user.tenantId with scope='tenant'.
|
|
13
|
+
// The default status is 'draft'; users must publish explicitly via the publish handler.
|
|
14
|
+
// SystemAdmin can write for another tenant through tenantIdOverride, typically to
|
|
15
|
+
// curate tenant templates from a platform admin UI.
|
|
17
16
|
export function makeUpsertTenantWrite(policy: TemplateEditPolicy) {
|
|
18
17
|
return defineWriteHandler({
|
|
19
18
|
name: "upsert-tenant",
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
} from "@cosmicdrift/kumiko-framework/event-store";
|
|
30
30
|
import type { Dispatcher } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
31
31
|
import { runEventStoreSeed, type SeedIfExists } from "@cosmicdrift/kumiko-framework/seeding";
|
|
32
|
-
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
32
|
+
import { isPlainObject, propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
33
33
|
import { executor } from "./handlers/shared.ts";
|
|
34
34
|
import { evaluateTemplateWrite } from "./handlers/template-gates.ts";
|
|
35
35
|
import { type TemplateResourceRow, templateResourcesTable } from "./table.ts";
|
|
@@ -232,11 +232,11 @@ export async function seedSystemTemplate(
|
|
|
232
232
|
}
|
|
233
233
|
throw new Error(`seedSystemTemplate create failed: ${JSON.stringify(result)}`);
|
|
234
234
|
}
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
235
|
+
const createdId = propertyOf(result.data, "id");
|
|
236
|
+
if (createdId === undefined) {
|
|
237
237
|
throw new Error("seedSystemTemplate: executor.create did not return an id");
|
|
238
238
|
}
|
|
239
|
-
return { id: String(
|
|
239
|
+
return { id: String(createdId) };
|
|
240
240
|
},
|
|
241
241
|
update: (row) => applyUpdate(row, existingRow),
|
|
242
242
|
});
|
|
@@ -23,16 +23,15 @@ const renameMailHtmlKind: EntityEventMigration = {
|
|
|
23
23
|
transform: (fields) => (fields["kind"] === "mail-html" ? { ...fields, kind: "mail" } : fields),
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
// TemplateResource —
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// Fassung.
|
|
26
|
+
// TemplateResource — structured template definition with tenant override
|
|
27
|
+
// hierarchy, locale fallback, and resource linking via file-foundation. Exactly
|
|
28
|
+
// one row per (tenantId, slug, kind, locale); scope/status/version distinguish
|
|
29
|
+
// lifecycle states. The draft alongside an active revision is stored in `draft`;
|
|
30
|
+
// the main fields remain the served revision.
|
|
32
31
|
//
|
|
33
|
-
// `variableSchema` + `linkedResources`
|
|
34
|
-
// (
|
|
35
|
-
//
|
|
32
|
+
// `variableSchema` + `linkedResources` are JSON strings in longText
|
|
33
|
+
// (following compliance-profiles because the createEntity DSL has no dedicated
|
|
34
|
+
// jsonbField). The application layer parses the JSON and persists it as a string.
|
|
36
35
|
export const templateResourceEntity = createEntity({
|
|
37
36
|
table: "read_template_resources",
|
|
38
37
|
fields: {
|
|
@@ -47,8 +46,8 @@ export const templateResourceEntity = createEntity({
|
|
|
47
46
|
// Folder path for the content tree, `/`-separated ("page/marketing").
|
|
48
47
|
// null = root node.
|
|
49
48
|
folder: createTextField({ personal: false, reason: "technical_reference" }),
|
|
50
|
-
// Template
|
|
51
|
-
// business data
|
|
49
|
+
// Template body is authored by TenantAdmin/Operator (email-templates, etc.),
|
|
50
|
+
// and is business data—not end-user UGC.
|
|
52
51
|
content: createLongTextField({
|
|
53
52
|
personal: false,
|
|
54
53
|
reason: "is_business_data",
|
|
@@ -90,9 +89,9 @@ export type EntityAuditColumns = {
|
|
|
90
89
|
readonly modifiedById: string | null;
|
|
91
90
|
};
|
|
92
91
|
|
|
93
|
-
// Concrete
|
|
94
|
-
// Drizzle
|
|
95
|
-
//
|
|
92
|
+
// Concrete row type—the single source of truth for naming the unknown values
|
|
93
|
+
// returned by Drizzle from `Record<string, unknown>` (instead of 12×
|
|
94
|
+
// `row["x"] as Y` casts in handlers and resolvers).
|
|
96
95
|
export type TemplateResourceRow = {
|
|
97
96
|
readonly id: string | number;
|
|
98
97
|
readonly version: number;
|
|
@@ -173,7 +173,7 @@ function makeTreeProvider(tenantIdOverride?: string, collectionId?: string): Tre
|
|
|
173
173
|
const headers: Record<string, string> = { "content-type": "application/json" };
|
|
174
174
|
const csrf = readCsrfToken();
|
|
175
175
|
if (csrf !== undefined) headers[CSRF_HEADER_NAME] = csrf;
|
|
176
|
-
// kumiko-lint-ignore no-raw-hooks
|
|
176
|
+
// kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
|
|
177
177
|
fetch("/api/query", {
|
|
178
178
|
method: "POST",
|
|
179
179
|
headers,
|
|
@@ -344,7 +344,7 @@ function TextBlockEditor({
|
|
|
344
344
|
|
|
345
345
|
// Sync loaded data into the form state. loaded === null means the block does
|
|
346
346
|
// not exist yet — empty form for the create flow.
|
|
347
|
-
// kumiko-lint-ignore no-raw-hooks
|
|
347
|
+
// kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
|
|
348
348
|
useEffect(() => {
|
|
349
349
|
if (loading) return;
|
|
350
350
|
setTitle(loaded?.title ?? "");
|
|
@@ -98,10 +98,10 @@ export function createTenantFeature(options?: TenantFeatureOptions): FeatureDefi
|
|
|
98
98
|
|
|
99
99
|
r.config({
|
|
100
100
|
keys: {
|
|
101
|
-
//
|
|
101
|
+
// Core tenant settings — tenant admins can change them; all users can read them.
|
|
102
102
|
companyName: createTenantConfig("text", { default: "" }),
|
|
103
|
-
//
|
|
104
|
-
//
|
|
103
|
+
// Curated subset of IANA time zones covering the most relevant practical cases.
|
|
104
|
+
// Extend it when a real need arises.
|
|
105
105
|
timezone: createTenantConfig("select", {
|
|
106
106
|
default: "Europe/Berlin",
|
|
107
107
|
options: [
|
|
@@ -124,8 +124,8 @@ export function createTenantFeature(options?: TenantFeatureOptions): FeatureDefi
|
|
|
124
124
|
options: ["de", "en", "fr", "es"],
|
|
125
125
|
}),
|
|
126
126
|
|
|
127
|
-
// SMTP —
|
|
128
|
-
//
|
|
127
|
+
// SMTP settings — only SystemAdmin (platform operator) can change them; smtpPass is
|
|
128
|
+
// encrypted and readable only by SystemAdmin.
|
|
129
129
|
smtpHost: createTenantConfig("text", { write: access.systemAdmin, read: access.admin }),
|
|
130
130
|
smtpPass: createTenantConfig("text", {
|
|
131
131
|
write: access.systemAdmin,
|
|
@@ -133,8 +133,8 @@ export function createTenantFeature(options?: TenantFeatureOptions): FeatureDefi
|
|
|
133
133
|
encrypted: true,
|
|
134
134
|
}),
|
|
135
135
|
|
|
136
|
-
// System
|
|
137
|
-
//
|
|
136
|
+
// System settings — changeable only programmatically by SYSTEM_USER;
|
|
137
|
+
// tenant admins see them as read-only.
|
|
138
138
|
priceModel: createSystemConfig("select", {
|
|
139
139
|
default: "basic",
|
|
140
140
|
options: ["basic", "pro", "enterprise"],
|
|
@@ -32,7 +32,7 @@ async function loadMemberUserIds(db: TenantDb, tenantId: string): Promise<readon
|
|
|
32
32
|
return [...new Set(memberships.map((row) => String(row["userId"])))].sort(compareIds);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
// Label source behind every `user:user` reference column
|
|
35
|
+
// Label source behind every `user:user` reference column. The
|
|
36
36
|
// entity-convention lookup, user:query:user:list, is a SystemAdmin
|
|
37
37
|
// cross-tenant roster, so a TenantAdmin got a 403 and every actor cell fell
|
|
38
38
|
// back to the raw UUID. Deliberately narrower than tenant:query:members:
|
|
@@ -20,7 +20,7 @@ export const membersQuery = defineQueryHandler({
|
|
|
20
20
|
name: "members",
|
|
21
21
|
schema: z.object({
|
|
22
22
|
// Optional single-user filter — audit detail (and similar) only need one
|
|
23
|
-
// member's display name, not the full decrypted roster
|
|
23
|
+
// member's display name, not the full decrypted roster.
|
|
24
24
|
userId: z.string().min(1).optional(),
|
|
25
25
|
}),
|
|
26
26
|
access: { roles: access.admin },
|
|
@@ -31,7 +31,7 @@ export const membershipsQuery = defineQueryHandler({
|
|
|
31
31
|
// tenantName/tenantKey make memberships distinguishable in the UI
|
|
32
32
|
// (otherwise just the UUID prefix — seed tenants with a 00000000-…
|
|
33
33
|
// prefix would be indistinguishable). A single IN-batch over all
|
|
34
|
-
// tenantIds instead of fetchOne per membership
|
|
34
|
+
// tenantIds instead of fetchOne per membership.
|
|
35
35
|
type TenantRow = { id: unknown; name?: unknown; key?: unknown; isEnabled?: unknown };
|
|
36
36
|
const tenants = await decryptTenantNames(
|
|
37
37
|
await selectMany<TenantRow>(db, tenantTable, {
|
|
@@ -58,7 +58,7 @@ function compareTeamRows(a: TeamRow, b: TeamRow, field: SortField, dir: "asc" |
|
|
|
58
58
|
return av.localeCompare(bv) * sign;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
// User-selected facet filters (payload.filters
|
|
61
|
+
// User-selected facet filters (payload.filters) — `status` is the
|
|
62
62
|
// only filterable field here: it's synthesized from which table a row came
|
|
63
63
|
// from, not a stored column, so there is nothing else meaningful to filter
|
|
64
64
|
// on server-side yet. `filter` (singular, screen-level static filter) is
|
|
@@ -10,7 +10,7 @@ import { decryptTenantNames, takeTenantsMatchingDecryptedName } from "../decrypt
|
|
|
10
10
|
import { tenantTable } from "../schema/tenant.ts";
|
|
11
11
|
import { isSystemAdmin } from "./is-system-admin.ts";
|
|
12
12
|
|
|
13
|
-
// Label source
|
|
13
|
+
// Label source for every `tenant:tenant` reference column. The
|
|
14
14
|
// entity-convention lookup, tenant:query:tenant:list, is a SystemAdmin-only
|
|
15
15
|
// entity-list handler, so a TenantAdmin got a 403 and every tenant cell fell
|
|
16
16
|
// back to the raw UUID. A SystemAdmin keeps the global reach tenant:list gave
|