@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
|
@@ -104,7 +104,7 @@ export function createFeatureTogglesFeature(
|
|
|
104
104
|
r.translations({ keys: FEATURE_TOGGLES_I18N });
|
|
105
105
|
|
|
106
106
|
// toggle-cache-sync — multi-instance snapshot propagation. One shared
|
|
107
|
-
// cursor reads every toggle-set event once
|
|
107
|
+
// cursor reads every toggle-set event once; the winning
|
|
108
108
|
// process's handler calls runtime.broadcastToggle, which publishes on
|
|
109
109
|
// GlobalFeatureToggleRuntime's syncSignal so every process (including
|
|
110
110
|
// the one that won the cursor) applies the flip to its own snapshot —
|
|
@@ -38,7 +38,7 @@ export const globalFeatureStateTable: WritableSchemaTable & TenancyBrand<"global
|
|
|
38
38
|
// sees the table, so `kumiko schema generate` reports no changes and no
|
|
39
39
|
// app ever gets a migration for it (framework gap, not app-local). Derived
|
|
40
40
|
// from the pgTable above instead of hand-written a second time — the two
|
|
41
|
-
// used to drift independently
|
|
41
|
+
// used to drift independently: a column added only to
|
|
42
42
|
// the pgTable made queries type-check while the migration generator stayed
|
|
43
43
|
// blind to it, failing in prod with "column ... does not exist" while every
|
|
44
44
|
// mocked-stack test stayed green.
|
|
@@ -38,11 +38,11 @@ export const registeredQuery = defineQueryHandler({
|
|
|
38
38
|
const overrideRows = await db.global(globalFeatureStateTable).selectMany<OverrideRow>();
|
|
39
39
|
const overrides = new Map(overrideRows.map((r) => [r.featureName, r.enabled]));
|
|
40
40
|
|
|
41
|
-
// SystemAdmin operator
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
41
|
+
// SystemAdmin operator tooling: the listing must show platform truth
|
|
42
|
+
// (all features in the registry), not its own tier cut.
|
|
43
|
+
// The per-tenant signature requires SYSTEM_TENANT_ID; the app resolver
|
|
44
|
+
// returns the union of all tier features. The sentinel convention is
|
|
45
|
+
// documented in DispatcherOptions.effectiveFeatures.
|
|
46
46
|
const effective = ctx.effectiveFeatures?.(SYSTEM_TENANT_ID);
|
|
47
47
|
|
|
48
48
|
const rows: Array<{
|
|
@@ -16,7 +16,7 @@ import { createCacheSyncToggleSignal } from "./toggle-sync-signal.ts";
|
|
|
16
16
|
|
|
17
17
|
const log = createFallbackLogger("kumiko:feature-toggles");
|
|
18
18
|
|
|
19
|
-
// Cross-replica transport for a toggle flip
|
|
19
|
+
// Cross-replica transport for a toggle flip. Deliberately narrow
|
|
20
20
|
// (featureName + enabled, not a generic channel/payload pair) so a caller
|
|
21
21
|
// can't wire the wrong signal instance in by accident — see
|
|
22
22
|
// createRedisToggleSyncSignal (toggle-sync-signal.ts) for the Redis-backed
|
|
@@ -27,7 +27,7 @@ function isTogglePayload(value: unknown): value is { featureName: string; enable
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//
|
|
30
|
+
// Gives toggle-cache-sync the cross-replica transport its shared
|
|
31
31
|
// dispatcher cursor needs — without this, only the one process that won
|
|
32
32
|
// the shared cursor's toggle-set event would ever learn about a flip.
|
|
33
33
|
// Standalone Redis transport for callers that want their own connections;
|
|
@@ -11,7 +11,7 @@ export const FEATURE_TOGGLE_AGGREGATE_TYPE = "feature-toggles";
|
|
|
11
11
|
|
|
12
12
|
// Shared acknowledgeCrossTenant() reason across all three handlers that read
|
|
13
13
|
// or write globalFeatureStateTable — one string so the three call sites
|
|
14
|
-
// can't drift
|
|
14
|
+
// can't drift.
|
|
15
15
|
export const FEATURE_TOGGLE_CROSS_TENANT_REASON =
|
|
16
16
|
"global feature-toggle state, no tenant scope by design";
|
|
17
17
|
|
|
@@ -35,13 +35,13 @@ const FEATURE_NAME = "file-derivatives";
|
|
|
35
35
|
// charset constraint (`Readonly<Record<string, VariantSpec>>`), so this
|
|
36
36
|
// stays permissive rather than guessing a convention — narrower than this
|
|
37
37
|
// would silently 404 a legitimately declared name again. Do not reintroduce
|
|
38
|
-
// a name list here "for safety"
|
|
38
|
+
// a name list here "for safety".
|
|
39
39
|
const VARIANT_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
40
40
|
|
|
41
41
|
/** Host → tenantId for the anonymous media route.
|
|
42
42
|
* MUST be cheap/synchronous (in-memory map or cached lookup): it runs
|
|
43
43
|
* *before* the query-handler rate limit, so a DB round-trip here is an
|
|
44
|
-
* unthrottled DoS surface for anonymous callers rotating Host headers
|
|
44
|
+
* unthrottled DoS surface for anonymous callers rotating Host headers. */
|
|
45
45
|
export type PublicVariantResolveApexTenant = (
|
|
46
46
|
host: string,
|
|
47
47
|
) => Promise<TenantId | null> | TenantId | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Public-Read of a derived FileRef variant — the anonymous counterpart to
|
|
2
|
-
// GET /files/:id/variant/:name (
|
|
2
|
+
// GET /files/:id/variant/:name (auth-gated). Both routes resolve the
|
|
3
3
|
// same way: the variant spec comes from the FileRef's field declaration
|
|
4
4
|
// (`createImageField({ variants: {...} })`), not a fixed list — an app that
|
|
5
5
|
// declares its own variant name gets it served here too. This route never
|
|
@@ -3,7 +3,7 @@ import type { VariantSpec } from "@cosmicdrift/kumiko-types/derivatives-types";
|
|
|
3
3
|
// Ready-made specs to spread into a field's own `variants` declaration
|
|
4
4
|
// (`createImageField({ variants: { thumb, full: { ...full, maxEdge: 4096 } } })`)
|
|
5
5
|
// — not an allow-list. Which names a route serves is decided entirely by
|
|
6
|
-
// what a field declares
|
|
6
|
+
// what a field declares; these are just common defaults.
|
|
7
7
|
export const thumb = { maxEdge: 160, fit: "cover", format: "webp" } as const satisfies VariantSpec;
|
|
8
8
|
export const card = { maxEdge: 640, fit: "inside", format: "webp" } as const satisfies VariantSpec;
|
|
9
9
|
export const hero = { maxEdge: 1600, fit: "inside", format: "webp" } as const satisfies VariantSpec;
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
// erasure hit the same store by construction. This feature re-exports the moved
|
|
9
9
|
// symbols unchanged so existing imports keep working.
|
|
10
10
|
//
|
|
11
|
-
// **Pattern
|
|
12
|
-
//
|
|
13
|
-
// -s3-env,
|
|
14
|
-
//
|
|
11
|
+
// **Pattern reference:** identical to `mail-foundation`. The foundation declares
|
|
12
|
+
// the `fileProvider` extension point; provider features (file-provider-s3,
|
|
13
|
+
// -inmemory, -s3-env, later -gcs/-azure-blob) register themselves by name. The
|
|
14
|
+
// tenant selects one at runtime via the `provider` config key.
|
|
15
15
|
//
|
|
16
|
-
// **Boot
|
|
17
|
-
//
|
|
16
|
+
// **Boot dependencies:** config (for the provider selector). No secrets, because
|
|
17
|
+
// the foundation itself does not hold any secrets.
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
20
|
access,
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
// kumiko-feature-version: 1
|
|
2
2
|
//
|
|
3
|
-
// file-provider-inmemory — In-
|
|
4
|
-
// foundation
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// file-provider-inmemory — In-memory file provider for the file-
|
|
4
|
+
// foundation plugin API. Stores files in a per-tenant Map instead
|
|
5
|
+
// of S3/Hetzner object storage. Intended for demos, sample apps,
|
|
6
|
+
// and tests without a MinIO container.
|
|
7
7
|
//
|
|
8
|
-
// **
|
|
9
|
-
// 1. Plugin
|
|
8
|
+
// **What this feature provides:**
|
|
9
|
+
// 1. Plugin registration via `r.useExtension("fileProvider",
|
|
10
10
|
// "inmemory", { build })`.
|
|
11
|
-
// 2. **
|
|
12
|
-
// InMemoryFileProvider
|
|
13
|
-
//
|
|
11
|
+
// 2. **Per-tenant storage.** Each tenant gets its own
|
|
12
|
+
// InMemoryFileProvider, providing tenant isolation by design
|
|
13
|
+
// without requiring a path convention.
|
|
14
14
|
//
|
|
15
|
-
// **Pattern
|
|
15
|
+
// **Pattern reference:** mirrors file-provider-s3.
|
|
16
16
|
//
|
|
17
|
-
// **
|
|
18
|
-
//
|
|
17
|
+
// **NOT for production.** The buffer is process memory, is lost on
|
|
18
|
+
// restart, and grows monotonically with every write.
|
|
19
19
|
|
|
20
20
|
import type {
|
|
21
21
|
FileProviderContext,
|
|
@@ -50,7 +50,7 @@ export function listKeys(tenantId: string): readonly string[] {
|
|
|
50
50
|
return providersByTenant.get(tenantId)?.keys() ?? [];
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
/** Demo/
|
|
53
|
+
/** Demo/test helper: clears a tenant's storage. */
|
|
54
54
|
export function clearStorage(tenantId: string): void {
|
|
55
55
|
providersByTenant.get(tenantId)?.clear();
|
|
56
56
|
}
|
|
@@ -70,9 +70,9 @@ export function createFileProviderInMemoryFeature() {
|
|
|
70
70
|
category: "storage",
|
|
71
71
|
recommended: false,
|
|
72
72
|
});
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
// file-foundation
|
|
73
|
+
// No requirement for "config" or "secrets": the
|
|
74
|
+
// in-memory provider has neither configuration nor secrets. Only
|
|
75
|
+
// file-foundation must be present as the plugin extension point.
|
|
76
76
|
r.requires({ features: ["file-foundation"] });
|
|
77
77
|
|
|
78
78
|
const plugin: FileProviderPlugin = {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// kumiko-feature-version: 1
|
|
2
2
|
//
|
|
3
|
-
// file-provider-s3 — concrete S3
|
|
4
|
-
// file-foundation plugin
|
|
3
|
+
// file-provider-s3 — concrete S3 implementation for the
|
|
4
|
+
// file-foundation plugin API.
|
|
5
5
|
//
|
|
6
|
-
// **
|
|
7
|
-
// 1. Provider-
|
|
8
|
-
// forcePathStyle/accessKeyId)
|
|
9
|
-
// Self-contained — file-foundation
|
|
10
|
-
// 2. Plugin
|
|
11
|
-
// { build })`. file-foundation's
|
|
12
|
-
// registry.
|
|
13
|
-
// 3. build(ctx, tenantId)
|
|
14
|
-
//
|
|
15
|
-
//
|
|
6
|
+
// **What this feature provides:**
|
|
7
|
+
// 1. Provider-specific tenant config (bucket/region/endpoint/
|
|
8
|
+
// forcePathStyle/accessKeyId) and secret (s3.secretAccessKey).
|
|
9
|
+
// Self-contained — file-foundation does not know about these.
|
|
10
|
+
// 2. Plugin registration via `r.useExtension("fileProvider", "s3",
|
|
11
|
+
// { build })`. file-foundation's factory finds the plugin through
|
|
12
|
+
// the registry.
|
|
13
|
+
// 3. build(ctx, tenantId) reads the config and secret, then calls
|
|
14
|
+
// `createS3Provider` from ./lib. This is the plugin's only
|
|
15
|
+
// cross-feature import, intentionally kept local.
|
|
16
16
|
//
|
|
17
|
-
// **Pattern
|
|
17
|
+
// **Pattern reference:** mirrors mail-transport-smtp.
|
|
18
18
|
//
|
|
19
|
-
// **Boot
|
|
19
|
+
// **Boot dependencies:** config + secrets + file-foundation.
|
|
20
20
|
|
|
21
21
|
import type {
|
|
22
22
|
FileProviderContext,
|
|
@@ -101,8 +101,8 @@ function createTenantConfigFileProviderS3Feature() {
|
|
|
101
101
|
},
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
-
// Plugin
|
|
105
|
-
// file-foundation's `provider` config
|
|
104
|
+
// Plugin registration. The entityName "s3" is what tenants set in
|
|
105
|
+
// file-foundation's `provider` config key.
|
|
106
106
|
const plugin: FileProviderPlugin = {
|
|
107
107
|
build: async (ctx: FileProviderContext, tenantId: string) => buildS3Provider(ctx, tenantId), // @wrapper-known semantic-alias
|
|
108
108
|
};
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@cosmicdrift/kumiko-framework/files";
|
|
6
6
|
|
|
7
7
|
// =============================================================================
|
|
8
|
-
//
|
|
8
|
+
// Required operator setup (multipart-upload cleanup)
|
|
9
9
|
// =============================================================================
|
|
10
10
|
//
|
|
11
11
|
// `writeStream` uses Bun's S3 writer for real multipart streaming. S3
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
// OPEN in S3 and bills storage for the parts already uploaded — until a
|
|
16
16
|
// lifecycle rule aborts it.
|
|
17
17
|
//
|
|
18
|
-
// **
|
|
18
|
+
// **Required operator setup on every bucket:**
|
|
19
19
|
//
|
|
20
20
|
// {
|
|
21
21
|
// "Rules": [{
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
// R2 and Minio support the same syntax.
|
|
32
32
|
//
|
|
33
33
|
// =============================================================================
|
|
34
|
-
//
|
|
34
|
+
// Required operator setup (IAM: list permission)
|
|
35
35
|
// =============================================================================
|
|
36
36
|
//
|
|
37
37
|
// GDPR-forget/tenant-destroy erasure (user-data-rights-defaults) calls
|
|
@@ -181,9 +181,9 @@ export function createS3Provider(config: S3ProviderConfig): FileStorageProvider
|
|
|
181
181
|
options?: SignedUrlOptions,
|
|
182
182
|
): Promise<string> {
|
|
183
183
|
assertSafeStorageKey(key);
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
184
|
+
// Bun signs contentDisposition as the response-content-disposition
|
|
185
|
+
// query parameter (a response override for the GET download) —
|
|
186
|
+
// the browser sees the original filename instead of the UUID key.
|
|
187
187
|
return client.presign(key, {
|
|
188
188
|
expiresIn: expiresInSeconds,
|
|
189
189
|
method: "GET",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// files —
|
|
2
|
-
// files:event:*-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// `@cosmicdrift/kumiko-bundled-features/files`
|
|
1
|
+
// files — complete event sourcing for file metadata. The implementation (entity,
|
|
2
|
+
// files:event:*-events, inline projection) lives in the framework alongside
|
|
3
|
+
// file-routes and fileRefsTable because file-routes depends on registered events
|
|
4
|
+
// and a projection, as required by appendDomainEventCore.
|
|
5
|
+
// This module only re-exports the feature to keep the app import path
|
|
6
|
+
// `@cosmicdrift/kumiko-bundled-features/files` stable.
|
|
7
7
|
export { createFilesFeature, fileRefEntity } from "@cosmicdrift/kumiko-framework/files";
|
package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Backfill/GC job for derivatives orphaned by a forget/tenant-destroy that ran
|
|
2
|
-
// before
|
|
2
|
+
// before binary cleanup was wired into those flows. Those older runs
|
|
3
3
|
// left the FileRef row gone with no audit trail of what was ever forgotten —
|
|
4
4
|
// so this sweep works forward from the deterministic derivative-key grammar
|
|
5
5
|
// alone: for every key under a tenant's storage prefix that parses as a
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// a soft-deleted one sitting in trash — means the derivative is still
|
|
9
9
|
// legitimate; only genuinely unreferenced derivatives are swept.
|
|
10
10
|
//
|
|
11
|
-
// Manual trigger only (no cron) — an operator runs this once after upgrading
|
|
12
|
-
//
|
|
11
|
+
// Manual trigger only (no cron) — an operator runs this once after upgrading,
|
|
12
|
+
// or on demand for spot-checks.
|
|
13
13
|
//
|
|
14
14
|
// Row unit for runChunkedMigration is a discovered derivative CANDIDATE KEY,
|
|
15
15
|
// not a tenant: one tenant's storage listing produces a variable number of
|
|
@@ -91,7 +91,7 @@ export async function sweepOrphanedDerivativesJob(
|
|
|
91
91
|
}
|
|
92
92
|
tenantCursor = tenants.at(-1)?.id;
|
|
93
93
|
for (const tenant of tenants) {
|
|
94
|
-
const tenantId = tenant.id
|
|
94
|
+
const tenantId = tenant.id;
|
|
95
95
|
let provider: FileStorageProvider;
|
|
96
96
|
try {
|
|
97
97
|
provider = await resolver(tenantId);
|
|
@@ -131,7 +131,7 @@ export async function sweepOrphanedDerivativesJob(
|
|
|
131
131
|
): Promise<"migrated" | "skipped" | "failed"> {
|
|
132
132
|
// No isDeleted filter: a soft-deleted (trashed, not yet forgotten) fileRef
|
|
133
133
|
// still legitimately backs its derivatives — only an ABSENT row (forgotten,
|
|
134
|
-
// or a tenant destroyed
|
|
134
|
+
// or a tenant destroyed with no row left at all) makes a
|
|
135
135
|
// derivative orphaned.
|
|
136
136
|
const owners = await selectMany(
|
|
137
137
|
db,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// EXT_TENANT_DATA + EXT_STORAGE_PROVIDER destroy hooks for the `fileRef`
|
|
2
|
-
// entity
|
|
2
|
+
// entity. Kept apart from the `files` feature (like folders-user-data
|
|
3
3
|
// does for EXT_USER_DATA) so file consumers without the tenant-lifecycle
|
|
4
4
|
// pipeline don't pull a hard dependency — `files` stays usable standalone.
|
|
5
5
|
//
|
|
@@ -10,18 +10,17 @@
|
|
|
10
10
|
// isDeleted filter: tenant-destroy purges trashed rows too, a destroyed
|
|
11
11
|
// tenant has no "restore from trash" future. ALSO sweeps, per row, any
|
|
12
12
|
// storageKey that does NOT sit under one of this tenant's own
|
|
13
|
-
// tenantStoragePrefixes() — the shape a tenant-handover
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// derivatives together.
|
|
13
|
+
// tenantStoragePrefixes() — the shape a tenant-handover leaves behind:
|
|
14
|
+
// the fileRef row's tenantId moved to this tenant, but the bytes stayed
|
|
15
|
+
// under the SOURCE tenant's prefix (moving them would mean copying bytes,
|
|
16
|
+
// which the handover design explicitly rejects). Must run here, not in
|
|
17
|
+
// the "files" stage below — that stage's own prefix sweep only reaches
|
|
18
|
+
// keys under ITS tenant's prefixes by construction, and by the time it
|
|
19
|
+
// runs this hook has already forgotten (hard-deleted) the rows it would
|
|
20
|
+
// need to read the storageKey off. Deleted by STEM prefix
|
|
21
|
+
// (storageKeyStemPrefix), not the exact key: a derived variant
|
|
22
|
+
// (thumbnail, resized render) has no `file_refs` row of its own, so only
|
|
23
|
+
// the stem reaches original + derivatives together.
|
|
25
24
|
// - fileRefStorageDestroyHook ("files" stage, EXT_STORAGE_PROVIDER): wipes
|
|
26
25
|
// every BINARY (original + derivatives + anything else) under the
|
|
27
26
|
// tenant's storage prefixes. A full prefix sweep per tenantStoragePrefixes()
|
|
@@ -32,19 +31,18 @@
|
|
|
32
31
|
// (the provider's own list() prefix already scopes it). Still catches a
|
|
33
32
|
// blob with no fileRef row at all (the orphan case the row-driven sweep
|
|
34
33
|
// above cannot see) — REFINED, not replaced, to skip a key a FOREIGN
|
|
35
|
-
// tenant's fileRef row still references (a tenant-handover
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// not one query per key.
|
|
34
|
+
// tenant's fileRef row still references (a tenant-handover leaves the
|
|
35
|
+
// row's tenantId moved but the storageKey under THIS tenant's prefix
|
|
36
|
+
// unchanged). By the time this stage runs, the "app-data" stage
|
|
37
|
+
// (stages.ts DESTRUCTION_STAGES: "app-data" before "files") has already
|
|
38
|
+
// hard-deleted every row THIS tenant owned, so any surviving row a listed
|
|
39
|
+
// key still matches is, by construction, a foreign tenant's — no tenant
|
|
40
|
+
// comparison needed, existence is enough. The exception is computed from
|
|
41
|
+
// the SURVIVING row's storageKeyStemPrefix (mirroring the deletion side
|
|
42
|
+
// above), not the listed key's exact match: a derivative has no fileRef row
|
|
43
|
+
// of its own, so excluding only exact matches would still delete it out
|
|
44
|
+
// from under the tenant that claimed its original. Batched: one existence
|
|
45
|
+
// query per chunk of listed keys, not one query per key.
|
|
48
46
|
|
|
49
47
|
import { createEventStoreExecutor, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
50
48
|
import {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// GDPR tenant-destroy + orphaned-derivative backfill coverage for the `files`
|
|
2
|
-
// feature's `fileRef` entity
|
|
2
|
+
// feature's `fileRef` entity. Kept apart from `files` — like
|
|
3
3
|
// folders-user-data does for EXT_USER_DATA — so file consumers without the
|
|
4
4
|
// tenant-lifecycle pipeline don't pull a hard dependency; `files` stays usable
|
|
5
5
|
// standalone (e.g. user-data-rights-demo mounts `files` + user-data-rights
|
|
@@ -127,7 +127,7 @@ export type FoldersFeatureOptions = {
|
|
|
127
127
|
/** Row-level ownership on the folder-assignment rows themselves — orthogonal
|
|
128
128
|
* to `access`, which only gates whether a caller may dispatch set/clear/list
|
|
129
129
|
* at all. Not needed to keep a caller from reading assignments on host
|
|
130
|
-
* entities they can't see: that gate is default-on
|
|
130
|
+
* entities they can't see: that gate is default-on and derives
|
|
131
131
|
* from the entity's `parentRef`. Use `ownership.read` for an ADDITIONAL row
|
|
132
132
|
* rule on the assignment row itself; it is AND-ed with the host-visibility
|
|
133
133
|
* gate. Applies only to `folder-assignment`; the `folder` catalog stays
|
|
@@ -521,8 +521,8 @@ export function FolderManager({
|
|
|
521
521
|
|
|
522
522
|
// The bucket itself must stay in the tree even when nothing is currently
|
|
523
523
|
// unfiled — it's the only drop target to un-file a leaf back out of a
|
|
524
|
-
// folder.
|
|
525
|
-
//
|
|
524
|
+
// folder. An empty `unfiled` array made the bucket vanish entirely, silently
|
|
525
|
+
// removing that escape hatch.
|
|
526
526
|
const hasUnfiled = filing !== undefined;
|
|
527
527
|
if (hasUnfiled) {
|
|
528
528
|
out.push(bucketRow(stripeNext()));
|
|
@@ -47,11 +47,11 @@ export function buildFolderTree(rows: readonly FolderRow[]): readonly FolderNode
|
|
|
47
47
|
return build(null, 0);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
// not
|
|
54
|
-
// cap, not run one iteration past it.
|
|
50
|
+
// Returns a path such as "Properties / Berlin" for a folder id by walking
|
|
51
|
+
// parentId upward, or an empty string if the id is unknown. The row-count cap
|
|
52
|
+
// stops a parent cycle (currently impossible, since there is no reparent yet)
|
|
53
|
+
// from spinning forever. Use `<`, not `<=`: a cycle of exactly rows.length
|
|
54
|
+
// nodes must stop at the cap, not run one iteration past it.
|
|
55
55
|
export function folderPath(rows: readonly FolderRow[], id: string, separator = " / "): string {
|
|
56
56
|
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
57
57
|
const names: string[] = [];
|
|
@@ -22,7 +22,7 @@ export type StaleDraftRow = {
|
|
|
22
22
|
// once; a draft saved exactly once (create, never updated) has no
|
|
23
23
|
// modified_at yet, so falls back to inserted_at.
|
|
24
24
|
//
|
|
25
|
-
// Reads the blob + tenantId BEFORE anything is deleted
|
|
25
|
+
// Reads the blob + tenantId BEFORE anything is deleted — the
|
|
26
26
|
// caller (cleanup.job.ts) walks each row's blob for FileRefs and releases
|
|
27
27
|
// them per-tenant via ctx._fileProviderResolver, then deletes the batch
|
|
28
28
|
// per-row via formDraftExecutor.delete (event-sourced, not raw SQL — a
|
|
@@ -8,7 +8,7 @@ import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
8
8
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
9
9
|
|
|
10
10
|
// Narrows a draft blob's raw FileRef-shaped storageKeys (collectDraftFileRefKeys
|
|
11
|
-
// output — extracted from free-form, client-supplied JSON
|
|
11
|
+
// output — extracted from free-form, client-supplied JSON) down to
|
|
12
12
|
// the ones with a real, non-deleted file_refs row owned by this exact
|
|
13
13
|
// (tenantId, ownerId). Without this, a crafted draft value like
|
|
14
14
|
// { storageKey: "<someone-else's-real-key>" } would reach the storage
|
|
@@ -11,8 +11,8 @@ import { FORM_DRAFT_KEY_MAX_LENGTH, FORM_DRAFT_UNIQUE_KEY_CONSTRAINT } from "./w
|
|
|
11
11
|
// (tenant, ownerId): the same key from two different users, or the same
|
|
12
12
|
// user in two different tenants, is a different draft.
|
|
13
13
|
//
|
|
14
|
-
// Boundary
|
|
15
|
-
// lives in a domain stream — it's
|
|
14
|
+
// Boundary: form-draft never holds anything that already
|
|
15
|
+
// lives in a domain stream — it's an intermediate state BEFORE the domain entity
|
|
16
16
|
// is created. Consumers delete the draft (discard handler) once the real
|
|
17
17
|
// submit succeeds; partially-created domain data past that point is the
|
|
18
18
|
// consuming app's concern, not this feature's.
|
|
@@ -34,7 +34,7 @@ export const formDraftEntity = createEntity({
|
|
|
34
34
|
personal: false,
|
|
35
35
|
reason: "technical_reference",
|
|
36
36
|
}),
|
|
37
|
-
// The blob shape is fixed
|
|
37
|
+
// The blob shape is fixed, not left to the caller:
|
|
38
38
|
// { values: Record<string, unknown>, stepIndex: number, savedAt: string }.
|
|
39
39
|
// Free-form because `values` mirrors whatever fields the in-progress
|
|
40
40
|
// form has, so it can carry arbitrary user-entered PII. Encrypted under
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// form-draft — a per-user, per-tenant working copy of an in-progress form,
|
|
2
|
-
// saved BEFORE the real domain entity exists. Backing for wizard-mode resume
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// uniqueness model.
|
|
2
|
+
// saved BEFORE the real domain entity exists. Backing for wizard-mode resume.
|
|
3
|
+
// A caller-assigned draftKey (typically screenId + optional hostEntityId)
|
|
4
|
+
// round-trips { values, stepIndex, savedAt } through save/discard/get. See
|
|
5
|
+
// entity.ts for the ownership + uniqueness model.
|
|
7
6
|
|
|
8
7
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
9
8
|
import { defineFeature, type FeatureRegistrar } from "@cosmicdrift/kumiko-framework/engine";
|
|
@@ -79,7 +79,7 @@ export const discardDraftWrite = defineWriteHandler({
|
|
|
79
79
|
// Fail-closed erase of file_refs rows FIRST (outside the best-effort
|
|
80
80
|
// storage-hygiene loop). releaseDraftFileRefs swallows per-key errors
|
|
81
81
|
// by design — routing forget through it would report discarded:true
|
|
82
|
-
// while leaving the row behind
|
|
82
|
+
// while leaving the row behind.
|
|
83
83
|
for (const ref of ownedRefs) {
|
|
84
84
|
const forgetResult = await fileRefExecutor.forget({ id: ref.id }, event.user, ctx.db);
|
|
85
85
|
if (!forgetResult.isSuccess) return forgetResult;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
2
|
import type { FormDraftBlob } from "./schemas.ts";
|
|
3
3
|
|
|
4
|
-
// The draft blob's `values` is free-form by design
|
|
4
|
+
// The draft blob's `values` is free-form by design: form-draft
|
|
5
5
|
// never knows the consuming form's field schema, only { values, stepIndex,
|
|
6
6
|
// savedAt }). A FileRef pointer is therefore recognised purely by shape —
|
|
7
7
|
// any object anywhere in `values` carrying a non-empty string `storageKey`
|
|
@@ -48,11 +48,11 @@ export function collectDraftFileRefKeys(
|
|
|
48
48
|
//
|
|
49
49
|
// Takes an already-decided key list, not the draft blob — callers must run
|
|
50
50
|
// collectDraftFileRefKeys() output through db/queries' owned-storage-key
|
|
51
|
-
// filter first. `values` is free-form, client-supplied JSON
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
51
|
+
// filter first. `values` is free-form, client-supplied JSON; releasing a key
|
|
52
|
+
// straight out of it without verifying a real, owned file_refs row exists
|
|
53
|
+
// would let a crafted `{ storageKey: "<victim's key>" }` delete someone
|
|
54
|
+
// else's file — the same ownership check file-routes.ts runs before every
|
|
55
|
+
// read/delete (loadFileForTenant + FileAccessGuard).
|
|
56
56
|
export async function releaseDraftFileRefs(
|
|
57
57
|
keys: readonly string[],
|
|
58
58
|
deleteBinary: (storageKey: string) => Promise<void>,
|
|
@@ -17,9 +17,9 @@ const draftValuesSchema = z
|
|
|
17
17
|
`values exceeds the ${FORM_DRAFT_VALUES_MAX_BYTES}-byte limit`,
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
// The draft blob shape — fixed
|
|
20
|
+
// The draft blob shape — fixed here, not left for consumers
|
|
21
21
|
// to invent per-app. `stepIndex` is in from the start so wizard-mode resume
|
|
22
|
-
//
|
|
22
|
+
// doesn't need a later migration.
|
|
23
23
|
export const formDraftBlobSchema = z.object({
|
|
24
24
|
values: z.record(z.string(), z.unknown()),
|
|
25
25
|
stepIndex: z.number().int().min(0),
|
|
@@ -41,7 +41,7 @@ export type SaveDraftPayload = z.infer<typeof saveDraftPayloadSchema>;
|
|
|
41
41
|
// row right after the domain entity write already carries the same
|
|
42
42
|
// storageKeys forward — releasing them here would destroy files the entity
|
|
43
43
|
// now depends on. Only an actual abandon/abort flow should pass
|
|
44
|
-
// releaseFiles: true (
|
|
44
|
+
// releaseFiles: true (the "explicit abort" case).
|
|
45
45
|
export const discardDraftPayloadSchema = z.object({
|
|
46
46
|
draftKey: draftKeySchema,
|
|
47
47
|
releaseFiles: z.boolean().optional(),
|