@cosmicdrift/kumiko-samples 0.367.0 → 0.369.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/package.json +1 -1
- package/packages/bundled-features/package.json +16 -2
- package/packages/bundled-features/src/audit/handlers/details.query.ts +1 -1
- package/packages/bundled-features/src/audit/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -3
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +10 -3
- 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 +6 -2
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +2 -2
- package/packages/bundled-features/src/auth-foundation/feature.ts +43 -34
- package/packages/bundled-features/src/auth-foundation/index.ts +1 -0
- package/packages/bundled-features/src/auth-mfa/db/queries.ts +5 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
- 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 +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +1 -1
- package/packages/bundled-features/src/auth-mfa-user-data/index.ts +19 -10
- package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/feature.ts +138 -135
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/projection.ts +3 -2
- package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +52 -1
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +203 -15
- package/packages/bundled-features/src/cap-counter/changes.json +13 -0
- package/packages/bundled-features/src/cap-counter/feature.ts +84 -73
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +3 -4
- package/packages/bundled-features/src/cap-counter/index.ts +9 -1
- package/packages/bundled-features/src/cap-counter/tables.ts +10 -3
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -2
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +6 -2
- package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/changes.json +7 -0
- package/packages/bundled-features/src/channel-email/email-channel.ts +39 -8
- package/packages/bundled-features/src/channel-email/feature.ts +1 -1
- package/packages/bundled-features/src/channel-email/index.ts +5 -1
- package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/tables.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +1 -2
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +8 -4
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +26 -17
- package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
- package/packages/bundled-features/src/config/resolver.ts +1 -1
- package/packages/bundled-features/src/config/web/i18n.ts +1 -2
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +9 -7
- package/packages/bundled-features/src/custom-fields/db/queries/field-access.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/projection.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/db/queries/retention.ts +6 -2
- package/packages/bundled-features/src/custom-fields/db/queries/user-data-rights.ts +1 -1
- package/packages/bundled-features/src/custom-fields/feature.ts +11 -14
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +2 -2
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +16 -10
- package/packages/bundled-features/src/delivery/address-opt-out.ts +5 -2
- package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
- package/packages/bundled-features/src/delivery/changes.json +6 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +1 -1
- package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
- package/packages/bundled-features/src/delivery/db/queries/preferences.ts +1 -1
- package/packages/bundled-features/src/delivery/delivery-service.ts +16 -6
- package/packages/bundled-features/src/delivery/feature.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +3 -2
- package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
- package/packages/bundled-features/src/delivery/index.ts +8 -1
- package/packages/bundled-features/src/delivery/unsubscribe.ts +66 -37
- package/packages/bundled-features/src/delivery/upsert-preference.ts +5 -2
- package/packages/bundled-features/src/derivatives-sharp/feature.ts +21 -12
- package/packages/bundled-features/src/derivatives-sharp/index.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +112 -103
- package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
- package/packages/bundled-features/src/document-ingest-foundation/index.ts +4 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +134 -129
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +38 -29
- package/packages/bundled-features/src/file-foundation/index.ts +1 -0
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +1 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +32 -21
- package/packages/bundled-features/src/file-provider-inmemory/index.ts +6 -1
- package/packages/bundled-features/src/file-provider-s3/changes.json +10 -1
- package/packages/bundled-features/src/file-provider-s3/env-feature.ts +62 -0
- package/packages/bundled-features/src/file-provider-s3/feature.ts +107 -73
- package/packages/bundled-features/src/file-provider-s3/index.ts +6 -1
- package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -0
- package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/s3-provider.ts +19 -19
- package/packages/bundled-features/src/file-provider-s3-env/index.ts +7 -2
- package/packages/bundled-features/src/files-provider-s3/index.ts +11 -3
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +1 -1
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -2
- package/packages/bundled-features/src/folders/feature.ts +8 -3
- package/packages/bundled-features/src/folders-user-data/index.ts +27 -18
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/draft-count.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +3 -2
- package/packages/bundled-features/src/form-draft/feature.ts +6 -1
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +2 -2
- package/packages/bundled-features/src/form-draft/index.ts +1 -1
- package/packages/bundled-features/src/form-draft/lookup.ts +1 -1
- package/packages/bundled-features/src/form-draft-user-data/index.ts +19 -10
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +165 -154
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +1 -2
- package/packages/bundled-features/src/inbound-mail-foundation/index.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +5 -2
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +3 -2
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +22 -13
- package/packages/bundled-features/src/inbound-provider-imap/index.ts +6 -1
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +20 -12
- package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -0
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +1 -1
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +7 -2
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +11 -10
- 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/feature.ts +6 -3
- package/packages/bundled-features/src/mail-foundation/feature.ts +66 -46
- package/packages/bundled-features/src/mail-foundation/i18n.ts +8 -0
- package/packages/bundled-features/src/mail-foundation/index.ts +1 -0
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +31 -17
- package/packages/bundled-features/src/mail-transport-inmemory/index.ts +6 -1
- package/packages/bundled-features/src/mail-transport-smtp/changes.json +7 -0
- package/packages/bundled-features/src/mail-transport-smtp/config-keys.ts +67 -0
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +67 -82
- package/packages/bundled-features/src/mail-transport-smtp/i18n.ts +28 -0
- package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -0
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -2
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +1 -2
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -4
- package/packages/bundled-features/src/metrics/compute.ts +1 -1
- package/packages/bundled-features/src/metrics/filters.ts +1 -1
- package/packages/bundled-features/src/metrics/validate.ts +1 -1
- package/packages/bundled-features/src/notes-history/feature.ts +6 -3
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/notes-history-user-data/index.ts +27 -18
- package/packages/bundled-features/src/personal-access-tokens/changes.json +6 -0
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +17 -2
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +8 -6
- package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -0
- package/packages/bundled-features/src/readiness/feature.ts +25 -16
- package/packages/bundled-features/src/readiness/index.ts +1 -1
- package/packages/bundled-features/src/secrets/changes.json +6 -0
- package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
- package/packages/bundled-features/src/secrets/feature.ts +26 -6
- package/packages/bundled-features/src/secrets/handlers/delete.write.ts +5 -2
- package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
- package/packages/bundled-features/src/secrets/handlers/set.write.ts +5 -2
- package/packages/bundled-features/src/secrets/secrets-context.ts +4 -3
- package/packages/bundled-features/src/sessions/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/detail.query.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/mine.query.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/session-callbacks.ts +14 -7
- package/packages/bundled-features/src/sessions/testing.ts +1 -1
- package/packages/bundled-features/src/tags/feature.ts +6 -3
- package/packages/bundled-features/src/template-resolver/api.ts +1 -1
- package/packages/bundled-features/src/template-resolver/constants.ts +0 -1
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +1 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +4 -2
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/seeding.ts +3 -3
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-preview.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-resources.ts +1 -1
- package/packages/bundled-features/src/template-resolver/testing.ts +1 -1
- package/packages/bundled-features/src/template-resolver-user-data/index.ts +23 -14
- package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -2
- package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/me.query.ts +1 -1
- 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/remove-member.write.ts +2 -1
- package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.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/handlers/update-member-roles.write.ts +1 -2
- package/packages/bundled-features/src/tenant/invited-membership.ts +2 -2
- package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -2
- package/packages/bundled-features/src/tenant/seeding.ts +12 -12
- package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +1 -2
- package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +1 -2
- package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +3 -3
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +10 -5
- package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
- package/packages/bundled-features/src/tenant-settings/feature.ts +34 -29
- package/packages/bundled-features/src/tier-engine/feature.ts +426 -428
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +2 -3
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +5 -2
- package/packages/bundled-features/src/user/changes.json +6 -0
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +1 -1
- package/packages/bundled-features/src/user/handlers/create.write.ts +1 -2
- package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -1
- package/packages/bundled-features/src/user/index.ts +5 -1
- package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
- package/packages/bundled-features/src/user/principal-status.ts +13 -3
- package/packages/bundled-features/src/user/resolve-display-names.ts +1 -1
- package/packages/bundled-features/src/user/seeding.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/changes.json +6 -0
- package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +7 -4
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -2
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +40 -3
- package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +7 -2
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +7 -3
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +11 -5
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +10 -5
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +1 -2
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/lib.ts +5 -2
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/feature.ts +58 -47
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/index.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
- package/samples/apps/admin-console/src/run-config.ts +2 -2
- package/samples/apps/cap-billing-demo/package.json +3 -0
- package/samples/apps/cap-billing-demo/src/feature.ts +2 -2
- package/samples/apps/cap-billing-demo/src/run-config.ts +8 -8
- package/samples/apps/marketing-demo/src/app/seed.ts +1 -1
- package/samples/apps/marketing-demo/src/db/queries/seed-counts.ts +1 -1
- package/samples/apps/showcase/package.json +3 -0
- package/samples/apps/showcase/src/app/seed-items.ts +1 -1
- package/samples/apps/styleguide/src/app/seed.ts +2 -2
- package/samples/apps/styleguide/src/features/ai-settings/seed.ts +2 -2
- package/samples/apps/ui-walkthrough/scripts/emit-e2e-data.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +2 -2
- package/samples/apps/ui-walkthrough/src/app/seed-vehicles.ts +1 -1
- package/samples/apps/ui-walkthrough/src/app/seed.ts +1 -1
- package/samples/apps/ui-walkthrough/src/db/queries/row-counts.ts +1 -1
- package/samples/apps/ui-walkthrough/src/db/queries/task-counts.ts +1 -1
- package/samples/apps/use-all-bundled/feature-manifest.json +16 -16
- package/samples/apps/use-all-bundled/package.json +3 -0
- package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -2
- package/samples/apps/use-all-bundled/src/app/auth-constants.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/cap-overview-caps.ts +2 -2
- package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/seed-documents.ts +1 -1
- package/samples/apps/use-all-bundled/src/app/seed.ts +11 -5
- package/samples/apps/use-all-bundled/src/run-config.ts +55 -56
- package/samples/apps/user-data-rights-demo/README.md +2 -2
- package/samples/apps/user-data-rights-demo/package.json +3 -0
- package/samples/apps/user-data-rights-demo/src/run-config.ts +7 -7
- package/samples/apps/workspaces/package.json +3 -0
- package/samples/recipes/access-control/package.json +3 -0
- package/samples/recipes/anonymous-access/package.json +3 -0
- package/samples/recipes/anonymous-access-multitenant/package.json +3 -0
- package/samples/recipes/apex-landing/package.json +1 -0
- package/samples/recipes/apex-surface-auth/package.json +3 -0
- package/samples/recipes/apex-surface-auth/src/feature.ts +2 -2
- package/samples/recipes/api-worker-split/package.json +3 -0
- package/samples/recipes/api-worker-split/src/feature.ts +1 -2
- package/samples/recipes/auth-claims/package.json +3 -0
- package/samples/recipes/auth-foundation-providers/src/feature.ts +1 -1
- package/samples/recipes/auth-mfa/package.json +3 -0
- package/samples/recipes/basic-entity/package.json +3 -0
- package/samples/recipes/chat-channels/package.json +3 -0
- package/samples/recipes/compliance-profiles-demo/package.json +3 -0
- package/samples/recipes/cross-feature-events/package.json +3 -1
- package/samples/recipes/cross-feature-events/src/feature.ts +1 -1
- package/samples/recipes/crypto-shredding-hr/package.json +3 -0
- package/samples/recipes/currencies-global/package.json +3 -0
- package/samples/recipes/currencies-per-tenant/package.json +3 -0
- package/samples/recipes/custom-fields-basic/package.json +3 -0
- package/samples/recipes/custom-handlers/package.json +3 -0
- package/samples/recipes/dashboard-stats/package.json +3 -0
- package/samples/recipes/delivery-notifications/package.json +3 -0
- package/samples/recipes/e2e-generator/package.json +3 -0
- package/samples/recipes/embedded/package.json +3 -0
- package/samples/recipes/embedded-entity-form/package.json +1 -0
- package/samples/recipes/encrypted-tenant-config/README.md +1 -1
- package/samples/recipes/encrypted-tenant-config/package.json +3 -0
- package/samples/recipes/error-contract/package.json +3 -0
- package/samples/recipes/event-sourcing/package.json +3 -1
- package/samples/recipes/event-sourcing/src/feature.ts +16 -20
- package/samples/recipes/event-sourcing/tsconfig.json +2 -6
- package/samples/recipes/feature-toggles/package.json +3 -0
- package/samples/recipes/field-access/package.json +3 -0
- package/samples/recipes/files-post-processing/package.json +1 -0
- package/samples/recipes/golden-path/README.md +30 -0
- package/samples/recipes/golden-path/package.json +11 -0
- package/samples/recipes/golden-path/src/feature.ts +70 -0
- package/samples/recipes/idempotency/package.json +3 -0
- package/samples/recipes/inbound-mail-triage/package.json +3 -0
- package/samples/recipes/lane-routing/package.json +3 -0
- package/samples/recipes/ledger-banking/package.json +3 -0
- package/samples/recipes/ledger-invoicing/package.json +3 -0
- package/samples/recipes/legal-pages/package.json +3 -0
- package/samples/recipes/lifecycle-hooks/package.json +3 -0
- package/samples/recipes/managed-config/package.json +3 -0
- package/samples/recipes/managed-pages/package.json +3 -0
- package/samples/recipes/notes-history-basic/package.json +3 -0
- package/samples/recipes/ownership/package.json +3 -0
- package/samples/recipes/pdf-audit-export/package.json +1 -0
- package/samples/recipes/pipeline-basics/package.json +3 -0
- package/samples/recipes/public-share-token/package.json +3 -0
- package/samples/recipes/public-share-token/src/feature.ts +1 -1
- package/samples/recipes/rate-limiting/package.json +3 -0
- package/samples/recipes/realtime-sse/package.json +3 -0
- package/samples/recipes/record-detail-layout/package.json +1 -0
- package/samples/recipes/reference-data/package.json +3 -0
- package/samples/recipes/relations/package.json +3 -0
- package/samples/recipes/screens-nav/package.json +3 -0
- package/samples/recipes/search/package.json +3 -0
- package/samples/recipes/secrets-demo/package.json +3 -0
- package/samples/recipes/security-baseline/src/feature.ts +2 -2
- package/samples/recipes/session-revocation/README.md +1 -1
- package/samples/recipes/session-revocation/package.json +3 -0
- package/samples/recipes/session-revocation/src/feature.ts +1 -1
- package/samples/recipes/state-machine/package.json +3 -1
- package/samples/recipes/state-machine/src/entities/invoice.ts +2 -2
- package/samples/recipes/state-machine/src/events.ts +19 -0
- package/samples/recipes/state-machine/src/feature.ts +25 -30
- package/samples/recipes/state-machine/src/handlers/_helpers.ts +13 -14
- package/samples/recipes/state-machine/src/handlers/create.ts +1 -1
- package/samples/recipes/state-machine/src/handlers/transitions.ts +129 -122
- package/samples/recipes/state-machine/src/reducer.ts +1 -1
- package/samples/recipes/state-machine/tsconfig.json +2 -6
- package/samples/recipes/tags-basic/package.json +3 -0
- package/samples/recipes/tenant-isolation/package.json +3 -0
- package/samples/recipes/tenant-settings/package.json +3 -0
- package/samples/recipes/tier-admin/package.json +3 -0
- package/samples/recipes/timezones/package.json +3 -0
- package/samples/recipes/tsconfig.base.json +1 -1
- package/samples/recipes/user-data-rights/package.json +3 -0
- package/samples/recipes/user-data-rights/src/feature.ts +6 -2
- package/samples/recipes/user-profile/package.json +3 -0
- package/samples/recipes/user-profile/src/feature.ts +2 -2
- package/samples/recipes/webhook-step/package.json +3 -0
- package/samples/recipes/wizard-form/package.json +1 -0
- package/samples/recipes/workflow-engine/package.json +3 -0
- package/samples/recipes/workflow-engine/src/db/queries/suspended-runs.ts +5 -2
- package/samples/recipes/writeform-section/package.json +1 -0
- package/packages/bundled-features/src/file-provider-s3-env/feature.ts +0 -58
- /package/packages/bundled-features/src/{files-provider-s3 → file-provider-s3/lib}/env-helper.ts +0 -0
|
@@ -107,7 +107,7 @@ function registerFolders(
|
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
const defaultFoldersFeature = defineFeature(FOLDERS_FEATURE_NAME, (r) =>
|
|
111
111
|
registerFolders(r, DEFAULT_FOLDER_ACCESS, undefined, undefined, undefined),
|
|
112
112
|
);
|
|
113
113
|
|
|
@@ -156,7 +156,9 @@ function resolveAccess(opts: FoldersFeatureOptions): AccessRule {
|
|
|
156
156
|
|
|
157
157
|
// Options wrapper. Without options returns the module-level singleton (no
|
|
158
158
|
// rebuild). access/roles/toggleable build a fresh feature-definition.
|
|
159
|
-
export function createFoldersFeature(
|
|
159
|
+
export function createFoldersFeature(
|
|
160
|
+
opts: FoldersFeatureOptions = {},
|
|
161
|
+
): typeof defaultFoldersFeature {
|
|
160
162
|
if (
|
|
161
163
|
opts.access === undefined &&
|
|
162
164
|
opts.roles === undefined &&
|
|
@@ -164,7 +166,7 @@ export function createFoldersFeature(opts: FoldersFeatureOptions = {}): typeof f
|
|
|
164
166
|
opts.ownership === undefined &&
|
|
165
167
|
opts.parents === undefined
|
|
166
168
|
) {
|
|
167
|
-
return
|
|
169
|
+
return defaultFoldersFeature;
|
|
168
170
|
}
|
|
169
171
|
assertNoWhereRuleInOwnershipWrite("createFoldersFeature", opts.ownership?.write);
|
|
170
172
|
if (opts.parents !== undefined && opts.parents.length === 0) {
|
|
@@ -180,3 +182,6 @@ export function createFoldersFeature(opts: FoldersFeatureOptions = {}): typeof f
|
|
|
180
182
|
registerFolders(r, access, opts.toggleable, opts.ownership, opts.parents),
|
|
181
183
|
);
|
|
182
184
|
}
|
|
185
|
+
|
|
186
|
+
/** @deprecated Use createFoldersFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
187
|
+
export const foldersFeature = createFoldersFeature();
|
|
@@ -12,22 +12,31 @@ import {
|
|
|
12
12
|
folderExportHook,
|
|
13
13
|
} from "./hooks.js";
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
"
|
|
15
|
+
export function createFoldersUserDataFeature() {
|
|
16
|
+
return defineFeature(
|
|
17
|
+
"folders-user-data",
|
|
18
|
+
(r) => {
|
|
19
|
+
r.describe(
|
|
20
|
+
"GDPR (Art. 20 export / Art. 17 erasure) coverage for the `folders` feature's `folder` + `folder-assignment` entities. Mounts the EXT_USER_DATA export + delete hooks so a tenant's folder tree and its entity-to-folder assignments are included in the user-data export bundle and erased on a tenant-scoped forget (single-user tenants only; multi-user + anonymize are no-ops since folder rows carry no per-user PII). Kept separate from `folders` so folder consumers without the user-data-rights pipeline don't pull a hard dependency — requires `user-data-rights`, optionalRequires `folders`.",
|
|
21
|
+
);
|
|
22
|
+
// user-data-rights is the hard dependency (EXT_USER_DATA host). `folders` is
|
|
23
|
+
// OPTIONAL: if it's mounted toggleable(default=false) (e.g. per-tenant via
|
|
24
|
+
// tier), a hard r.requires would throw an "effectively disabled" boot
|
|
25
|
+
// warning even though the folder entities exist and the hooks work fine.
|
|
26
|
+
r.requires({ features: ["user-data-rights"] });
|
|
27
|
+
r.optionalRequires("folders");
|
|
28
|
+
r.useExtension(EXT_USER_DATA, "folder", {
|
|
29
|
+
export: folderExportHook,
|
|
30
|
+
delete: folderDeleteHook,
|
|
31
|
+
});
|
|
32
|
+
r.useExtension(EXT_USER_DATA, "folder-assignment", {
|
|
33
|
+
export: folderAssignmentExportHook,
|
|
34
|
+
delete: folderAssignmentDeleteHook,
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
{ dedupeOptions: {} },
|
|
18
38
|
);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
r.requires({ features: ["user-data-rights"] });
|
|
24
|
-
r.optionalRequires("folders");
|
|
25
|
-
r.useExtension(EXT_USER_DATA, "folder", {
|
|
26
|
-
export: folderExportHook,
|
|
27
|
-
delete: folderDeleteHook,
|
|
28
|
-
});
|
|
29
|
-
r.useExtension(EXT_USER_DATA, "folder-assignment", {
|
|
30
|
-
export: folderAssignmentExportHook,
|
|
31
|
-
delete: folderAssignmentDeleteHook,
|
|
32
|
-
});
|
|
33
|
-
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @deprecated Use createFoldersUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
42
|
+
export const foldersUserDataFeature = createFoldersUserDataFeature();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import type { FormDraftBlob } from "../../schemas.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { unsafeReadRetrying } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
|
|
5
5
|
// COUNT(*), not selectMany(...).length — save.write.ts checks this on every
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type DbRunner,
|
|
2
3
|
instantToTimestamptzParam,
|
|
4
|
+
toPostgresArrayLiteral,
|
|
3
5
|
unsafeReadRetrying,
|
|
4
|
-
} from "@cosmicdrift/kumiko-framework/
|
|
5
|
-
import { type DbRunner, toPostgresArrayLiteral } from "@cosmicdrift/kumiko-framework/db";
|
|
6
|
+
} from "@cosmicdrift/kumiko-framework/db";
|
|
6
7
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
7
8
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
8
9
|
|
|
@@ -56,4 +56,9 @@ function registerFormDraft(r: FeatureRegistrar<typeof FORM_DRAFT_FEATURE_NAME>):
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export
|
|
59
|
+
export function createFormDraftFeature() {
|
|
60
|
+
return defineFeature(FORM_DRAFT_FEATURE_NAME, registerFormDraft, { dedupeOptions: {} });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @deprecated Use createFormDraftFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
64
|
+
export const formDraftFeature = createFormDraftFeature();
|
|
@@ -77,7 +77,7 @@ async function releaseRowFileRefs(
|
|
|
77
77
|
isCreateMode,
|
|
78
78
|
);
|
|
79
79
|
const systemUser = createSystemUser(row.tenantId);
|
|
80
|
-
const tenantDb = createTenantDb(db, row.tenantId, "system");
|
|
80
|
+
const tenantDb = createTenantDb({ db, tenantId: row.tenantId, mode: "system" });
|
|
81
81
|
for (const ref of ownedRefs) {
|
|
82
82
|
const forgetResult = await fileRefExecutor.forget({ id: ref.id }, systemUser, tenantDb);
|
|
83
83
|
if (!forgetResult.isSuccess) {
|
|
@@ -132,7 +132,7 @@ export async function deleteStaleDraftsBatch(
|
|
|
132
132
|
const byId = new Map(batch.map((row) => [row.id, row]));
|
|
133
133
|
for (const [tenantId, ids] of groupStaleDraftIdsByTenant(batch)) {
|
|
134
134
|
const systemUser = createSystemUser(tenantId);
|
|
135
|
-
const tenantDb = createTenantDb(db, tenantId, "system");
|
|
135
|
+
const tenantDb = createTenantDb({ db, tenantId, mode: "system" });
|
|
136
136
|
for (const id of ids) {
|
|
137
137
|
// Race: user may have saved between select and here — skip if no longer stale.
|
|
138
138
|
if (!(await isDraftStillStale(db, tenantId, id, retentionDays))) {
|
|
@@ -8,7 +8,7 @@ export {
|
|
|
8
8
|
} from "./constants.js";
|
|
9
9
|
export { formDraftEntity } from "./entity.js";
|
|
10
10
|
export { formDraftExecutor, formDraftTable } from "./executor.js";
|
|
11
|
-
export { formDraftFeature } from "./feature.js";
|
|
11
|
+
export { createFormDraftFeature, formDraftFeature } from "./feature.js";
|
|
12
12
|
export { discardDraftWrite } from "./handlers/discard.write.js";
|
|
13
13
|
export { type GetDraftResult, getDraftQuery } from "./handlers/get.query.js";
|
|
14
14
|
export { type ListDraftsResult, listDraftsQuery } from "./handlers/list.query.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
1
|
import type { TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import { formDraftTable } from "./executor.js";
|
|
@@ -8,14 +8,23 @@
|
|
|
8
8
|
import { defineFeature, EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
9
9
|
import { formDraftDeleteHook, formDraftExportHook } from "./hooks.js";
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
"
|
|
11
|
+
export function createFormDraftUserDataFeature() {
|
|
12
|
+
return defineFeature(
|
|
13
|
+
"form-draft-user-data",
|
|
14
|
+
(r) => {
|
|
15
|
+
r.describe(
|
|
16
|
+
"GDPR (Art. 20 export / Art. 17 erasure) coverage for the `form-draft` feature's `form-draft` entity. Mounts the EXT_USER_DATA export hook so a user's saved drafts are included in the user-data export bundle, and a delete hook that physically removes the user's own draft rows on forget. Kept separate from `form-draft` so form-draft consumers without the user-data-rights pipeline don't pull a hard dependency — requires `user-data-rights`, optionalRequires `form-draft`.",
|
|
17
|
+
);
|
|
18
|
+
r.requires({ features: ["user-data-rights"] });
|
|
19
|
+
r.optionalRequires("form-draft");
|
|
20
|
+
r.useExtension(EXT_USER_DATA, "form-draft", {
|
|
21
|
+
export: formDraftExportHook,
|
|
22
|
+
delete: formDraftDeleteHook,
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
{ dedupeOptions: {} },
|
|
14
26
|
);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
delete: formDraftDeleteHook,
|
|
20
|
-
});
|
|
21
|
-
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** @deprecated Use createFormDraftUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
30
|
+
export const formDraftUserDataFeature = createFormDraftUserDataFeature();
|
|
@@ -97,169 +97,180 @@ import {
|
|
|
97
97
|
mailThreadTenantDestroyHook,
|
|
98
98
|
} from "./tenant-destroy-hook.js";
|
|
99
99
|
|
|
100
|
-
export
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
export function createInboundMailFoundationFeature() {
|
|
101
|
+
return defineFeature(
|
|
102
|
+
INBOUND_MAIL_FOUNDATION_FEATURE,
|
|
103
|
+
(r) => {
|
|
104
|
+
r.describe(
|
|
105
|
+
"Plugin host for inbound e-mail (inbox federation) — provider plugins (inbound-provider-imap, later M365 Graph / Gmail REST) register at the `inboundMailProvider` extension point with verify/fetch and optional oauth/watch (live push). The foundation owns three event-sourced streams (mail-account lifecycle, inbound-message with exactly-once ingest via deterministic aggregate ids, mail-thread rollup) and their projections `read_mail_accounts`/`read_inbound_messages`/`read_mail_threads`; PII fields are envelope-encrypted per tenant subject key before every append (crypto-shredding on tenant destroy). Wire `createInboundMailConnectRoutes` (OAuth connect + anonymous callback outside /api) and `createInboundMailSupervisor` (IDLE watch with backoff + reconciliation poll) in bin/server.ts. Consume `inbound-mail-foundation:event:inbound-message-received` from app features to attach business processes.",
|
|
106
|
+
);
|
|
107
|
+
r.uiHints({
|
|
108
|
+
displayLabel: "Inbound Mail · Foundation",
|
|
109
|
+
category: "notifications",
|
|
110
|
+
recommended: false,
|
|
111
|
+
});
|
|
112
|
+
// EXT_TENANT_DATA-Hook braucht den tenant-lifecycle-Host.
|
|
113
|
+
r.requires({ features: ["tenant-lifecycle"] });
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
115
|
+
// 5 fine-grained domain-events (Payload-Schemas: events.ts).
|
|
116
|
+
// piiFields: "none" — address/subject/snippet are already ciphertext under the tenant subject key before append (see events.ts).
|
|
117
|
+
// "displayName" stays plaintext (often the mailbox owner's real name for
|
|
118
|
+
// personal accounts); encrypting it would break the entity-projection read
|
|
119
|
+
// path that carries it as `personal: false`.
|
|
120
|
+
r.defineEvent(MAIL_ACCOUNT_CONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
|
|
121
|
+
piiFields: "none",
|
|
122
|
+
});
|
|
123
|
+
r.defineEvent(MAIL_ACCOUNT_UPDATED_EVENT_SHORT, mailAccountEventPayloadSchema, {
|
|
124
|
+
piiFields: "none",
|
|
125
|
+
});
|
|
126
|
+
r.defineEvent(MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT, mailAccountEventPayloadSchema, {
|
|
127
|
+
piiFields: "none",
|
|
128
|
+
});
|
|
129
|
+
r.defineEvent(INBOUND_MESSAGE_RECEIVED_EVENT_SHORT, inboundMessageEventPayloadSchema, {
|
|
130
|
+
piiFields: "none",
|
|
131
|
+
});
|
|
132
|
+
r.defineEvent(MAIL_THREAD_UPDATED_EVENT_SHORT, mailThreadEventPayloadSchema, {
|
|
133
|
+
piiFields: "none",
|
|
134
|
+
});
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
136
|
+
// Inline projections — apply in derselben TX wie der Append.
|
|
137
|
+
r.projection({
|
|
138
|
+
name: "mail-account",
|
|
139
|
+
source: MAIL_ACCOUNT_AGGREGATE_TYPE,
|
|
140
|
+
table: mailAccountsProjectionTable,
|
|
141
|
+
entity: mailAccountEntity,
|
|
142
|
+
apply: {
|
|
143
|
+
[MAIL_ACCOUNT_CONNECTED_EVENT_QN]: applyMailAccountConnected,
|
|
144
|
+
[MAIL_ACCOUNT_UPDATED_EVENT_QN]: applyMailAccountUpdated,
|
|
145
|
+
[MAIL_ACCOUNT_DISCONNECTED_EVENT_QN]: applyMailAccountDisconnected,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
r.projection({
|
|
149
|
+
name: "inbound-message",
|
|
150
|
+
source: INBOUND_MESSAGE_AGGREGATE_TYPE,
|
|
151
|
+
table: inboundMessagesProjectionTable,
|
|
152
|
+
entity: inboundMessageEntity,
|
|
153
|
+
apply: {
|
|
154
|
+
[INBOUND_MESSAGE_RECEIVED_EVENT_QN]: applyInboundMessageReceived,
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
r.projection({
|
|
158
|
+
name: "mail-thread",
|
|
159
|
+
source: MAIL_THREAD_AGGREGATE_TYPE,
|
|
160
|
+
table: mailThreadsProjectionTable,
|
|
161
|
+
entity: mailThreadEntity,
|
|
162
|
+
apply: {
|
|
163
|
+
[MAIL_THREAD_UPDATED_EVENT_QN]: applyMailThreadUpdated,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
163
166
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
167
|
+
// Plugin extension point — providers register via
|
|
168
|
+
// r.useExtension("inboundMailProvider", "<key>", plugin).
|
|
169
|
+
r.extendsRegistrar(INBOUND_MAIL_PROVIDER_EXTENSION, {
|
|
170
|
+
onRegister: () => {
|
|
171
|
+
// No side-effects at register-time — lookup happens at runtime
|
|
172
|
+
// via resolveInboundProviderForKey/-Account.
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Sync machinery: high-frequency tick state, deliberately NOT
|
|
177
|
+
// event-sourced — r.storeTable keeps the migration DDL but excludes the
|
|
178
|
+
// tables from the projection rebuild (#494/#498 class).
|
|
179
|
+
r.storeTable(syncCursorTable, {
|
|
180
|
+
reason: "read_side.mail_sync_cursors_direct_write",
|
|
181
|
+
});
|
|
182
|
+
r.storeTable(seenMessageTable, {
|
|
183
|
+
reason: "read_side.mail_seen_messages_direct_write",
|
|
184
|
+
});
|
|
172
185
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
reason: "read_side.mail_seen_messages_direct_write",
|
|
181
|
-
});
|
|
186
|
+
// Write-Handler:
|
|
187
|
+
// - ingest-message: programmatic (Supervisor/Poll, SystemAdmin)
|
|
188
|
+
// - connect/update/disconnect-account: Lifecycle
|
|
189
|
+
r.writeHandler(ingestMessageHandler);
|
|
190
|
+
r.writeHandler(connectAccountHandler);
|
|
191
|
+
r.writeHandler(updateAccountHandler);
|
|
192
|
+
r.writeHandler(disconnectAccountHandler);
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
r.writeHandler(ingestMessageHandler);
|
|
187
|
-
r.writeHandler(connectAccountHandler);
|
|
188
|
-
r.writeHandler(updateAccountHandler);
|
|
189
|
-
r.writeHandler(disconnectAccountHandler);
|
|
194
|
+
// List-Queries (PII-decrypted, scope-gefiltert).
|
|
195
|
+
r.queryHandler(listAccountsQuery);
|
|
196
|
+
r.queryHandler(listMessagesQuery);
|
|
190
197
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
// Entity-genaue GDPR-Destroy-Hooks — der gdpr-storage-Boot-Validator
|
|
199
|
+
// prueft die EXT_TENANT_DATA-Registrierung pro tenant-subject-Entity.
|
|
200
|
+
r.useExtension(EXT_TENANT_DATA, "mail-account", {
|
|
201
|
+
destroy: mailAccountTenantDestroyHook,
|
|
202
|
+
escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
|
|
203
|
+
});
|
|
204
|
+
r.useExtension(EXT_TENANT_DATA, "inbound-message", {
|
|
205
|
+
destroy: inboundMessageTenantDestroyHook,
|
|
206
|
+
escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
|
|
207
|
+
});
|
|
208
|
+
r.useExtension(EXT_TENANT_DATA, "mail-thread", {
|
|
209
|
+
destroy: mailThreadTenantDestroyHook,
|
|
210
|
+
escapeHatch: { reason: INBOUND_MAIL_TENANT_DESTROY_ARCHIVE_REASON },
|
|
211
|
+
});
|
|
194
212
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
213
|
+
// Data-Retention (#957) — perTenant fan-out (one run per tenant, like
|
|
214
|
+
// data-retention:retention-cleanup): runInboundMailRetention's raw query
|
|
215
|
+
// helpers need the unfiltered runner, so the handler declares escapeHatch
|
|
216
|
+
// and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
|
|
217
|
+
// + the bodies grow unbounded (GDPR Art. 5).
|
|
218
|
+
const INBOUND_MAIL_RETENTION_REASON =
|
|
219
|
+
"inbound-mail retention runs raw deletes; every statement filters by this run's tenantId";
|
|
220
|
+
r.job({
|
|
221
|
+
name: "inbound-mail-retention",
|
|
222
|
+
trigger: { cron: "0 3 * * *" },
|
|
223
|
+
perTenant: true,
|
|
224
|
+
concurrency: "skip",
|
|
225
|
+
escapeHatch: { reason: INBOUND_MAIL_RETENTION_REASON },
|
|
226
|
+
handler: async (_payload, ctx) => {
|
|
227
|
+
if (!ctx.registry) {
|
|
228
|
+
throw new Error(
|
|
229
|
+
"inbound-mail-retention: ctx.registry required (JobContext incomplete)",
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
const tenantId = ctx.systemUser?.tenantId ?? ctx._tenantId;
|
|
233
|
+
if (tenantId === undefined) {
|
|
234
|
+
// skip: cron fired without a perTenant fan-out tenant — nothing scoped
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
|
|
238
|
+
const retentionDb = ctx.db.unsafeRaw() as DbConnection; // @cast-boundary db-operator — jobs never run inside a DbTx
|
|
209
239
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
throw new Error("inbound-mail-retention: ctx.registry required (JobContext incomplete)");
|
|
226
|
-
}
|
|
227
|
-
const tenantId = ctx.systemUser?.tenantId ?? ctx._tenantId;
|
|
228
|
-
if (tenantId === undefined) {
|
|
229
|
-
// skip: cron fired without a perTenant fan-out tenant — nothing scoped
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
|
|
233
|
-
const retentionDb = ctx.db.unsafeRaw() as DbConnection; // @cast-boundary db-operator — jobs never run inside a DbTx
|
|
240
|
+
// Body-Objekte liegen in file-foundation. Provider lazy + memoized —
|
|
241
|
+
// heute schreibt der Ingest kein bodyRef (storeBody-Hook ungebunden),
|
|
242
|
+
// der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
|
|
243
|
+
// die Retention die Bodies mit ab.
|
|
244
|
+
let providerPromise: Promise<FileStorageProvider> | null = null;
|
|
245
|
+
const deleteBodyObject = async (bodyRef: string): Promise<void> => {
|
|
246
|
+
if (!providerPromise) {
|
|
247
|
+
providerPromise = createFileProviderForTenant(
|
|
248
|
+
{ config: ctx.config, registry: ctx.registry },
|
|
249
|
+
tenantId,
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
const provider = await providerPromise;
|
|
253
|
+
await provider.delete(bodyRef);
|
|
254
|
+
};
|
|
234
255
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// der Provider wird also nie gebaut. Sobald storeBody wired ist, raeumt
|
|
238
|
-
// die Retention die Bodies mit ab.
|
|
239
|
-
let providerPromise: Promise<FileStorageProvider> | null = null;
|
|
240
|
-
const deleteBodyObject = async (bodyRef: string): Promise<void> => {
|
|
241
|
-
if (!providerPromise) {
|
|
242
|
-
providerPromise = createFileProviderForTenant(
|
|
243
|
-
{ config: ctx.config, registry: ctx.registry },
|
|
256
|
+
const report = await runInboundMailRetention({
|
|
257
|
+
db: retentionDb,
|
|
244
258
|
tenantId,
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
deleteBodyObject,
|
|
259
|
+
now: T.Now.instant(),
|
|
260
|
+
deleteBodyObject,
|
|
261
|
+
});
|
|
262
|
+
if (report.bodyObjectErrors > 0) {
|
|
263
|
+
// biome-ignore lint/suspicious/noConsole: operator-visibility for failed body deletes
|
|
264
|
+
console.warn(
|
|
265
|
+
`[inbound-mail-foundation:inbound-mail-retention] tenant=${tenantId} bodyObjectErrors=${report.bodyObjectErrors}`,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
},
|
|
256
269
|
});
|
|
257
|
-
if (report.bodyObjectErrors > 0) {
|
|
258
|
-
// biome-ignore lint/suspicious/noConsole: operator-visibility for failed body deletes
|
|
259
|
-
console.warn(
|
|
260
|
-
`[inbound-mail-foundation:inbound-mail-retention] tenant=${tenantId} bodyObjectErrors=${report.bodyObjectErrors}`,
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
270
|
},
|
|
264
|
-
|
|
265
|
-
|
|
271
|
+
{ dedupeOptions: {} },
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** @deprecated Use createInboundMailFoundationFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
276
|
+
export const inboundMailFoundationFeature = createInboundMailFoundationFeature();
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts
CHANGED
|
@@ -20,12 +20,11 @@
|
|
|
20
20
|
// SystemAdmin-only: Aufrufer ist der Watch/Sync-Supervisor bzw. der
|
|
21
21
|
// Poll-Cron mit programmatic SystemUser — nie ein Tenant-Request.
|
|
22
22
|
|
|
23
|
-
import { countWhere } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
24
23
|
import {
|
|
25
24
|
configuredPiiSubjectKms,
|
|
26
25
|
encryptPiiFieldValues,
|
|
27
26
|
} from "@cosmicdrift/kumiko-framework/crypto";
|
|
28
|
-
import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
|
|
27
|
+
import { acquireNamespacedAdvisoryLock, countWhere } from "@cosmicdrift/kumiko-framework/db";
|
|
29
28
|
import type { WriteHandlerDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
30
29
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
31
30
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
@@ -54,7 +54,7 @@ export {
|
|
|
54
54
|
mailAccountEventPayloadSchema,
|
|
55
55
|
mailThreadEventPayloadSchema,
|
|
56
56
|
} from "./events.js";
|
|
57
|
-
export { inboundMailFoundationFeature } from "./feature.js";
|
|
57
|
+
export { createInboundMailFoundationFeature, inboundMailFoundationFeature } from "./feature.js";
|
|
58
58
|
export {
|
|
59
59
|
createOAuthAccessTokenManager,
|
|
60
60
|
inboundRefreshTokenSecretOptions,
|
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
// audit context. SecretsContext does not cache values (only unwrapped DEKs),
|
|
17
17
|
// so the read always reflects the latest committed write.
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import {
|
|
20
|
+
acquireNamespacedAdvisoryLock,
|
|
21
|
+
type DbConnection,
|
|
22
|
+
transaction,
|
|
23
|
+
} from "@cosmicdrift/kumiko-framework/db";
|
|
21
24
|
import type { SecretsContext } from "@cosmicdrift/kumiko-framework/secrets";
|
|
22
25
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
23
26
|
import { InboundMailAuthMethods, inboundCredentialSecretKey } from "./constants.js";
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
// in den list-queries.
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
|
+
buildEntityTable,
|
|
22
|
+
type EntityTableMeta,
|
|
21
23
|
insertOnConflictDoNothing,
|
|
22
24
|
requireEntityTableMeta,
|
|
23
25
|
upsertOnConflict,
|
|
24
|
-
} from "@cosmicdrift/kumiko-framework/
|
|
25
|
-
import { buildEntityTable, type EntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
|
|
26
|
+
} from "@cosmicdrift/kumiko-framework/db";
|
|
26
27
|
import { defineApply } from "@cosmicdrift/kumiko-framework/engine";
|
|
27
28
|
import { inboundMessageEntity, mailAccountEntity, mailThreadEntity } from "./entities.js";
|
|
28
29
|
import type {
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
// only while the connection is open. Losing the claim (Redis outage, TTL
|
|
45
45
|
// exceeded) tears down the local watcher instead of racing a new holder.
|
|
46
46
|
|
|
47
|
-
import { fetchOne, insertOne, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
48
47
|
import {
|
|
49
48
|
configuredPiiSubjectKms,
|
|
50
49
|
decryptPiiFieldValues,
|
|
51
50
|
} from "@cosmicdrift/kumiko-framework/crypto";
|
|
52
51
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
52
|
+
import { fetchOne, insertOne, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/db";
|
|
53
53
|
import type { DistributedLock } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
54
54
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
55
55
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|