@cosmicdrift/kumiko-samples 0.385.0 → 0.387.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +2 -2
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
- package/packages/bundled-features/src/audit/screens.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
- package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
- package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
- package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +6 -6
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -17
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +20 -20
- package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
- package/packages/bundled-features/src/billing-foundation/types.ts +64 -65
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
- package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
- package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
- package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
- package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
- package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
- package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
- package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
- package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
- package/packages/bundled-features/src/custom-fields/events.ts +7 -8
- package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
- package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
- package/packages/bundled-features/src/data-retention/feature.ts +11 -18
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
- package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
- package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
- package/packages/bundled-features/src/data-retention/presets.ts +18 -23
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
- package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
- package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
- package/packages/bundled-features/src/delivery/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
- package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
- package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
- package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
- package/packages/bundled-features/src/files/feature.ts +6 -6
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
- package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/tree.ts +5 -5
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/entity.ts +3 -3
- package/packages/bundled-features/src/form-draft/feature.ts +4 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
- package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
- package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
- package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
- package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +11 -11
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
- package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/feature.ts +6 -7
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
- package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
- package/packages/bundled-features/src/jobs/screens.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/entity.ts +5 -5
- package/packages/bundled-features/src/ledger/feature.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
- package/packages/bundled-features/src/ledger/recurring.ts +12 -12
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
- package/packages/bundled-features/src/ledger/web/index.ts +7 -7
- package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
- package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
- package/packages/bundled-features/src/mail-foundation/feature.ts +26 -27
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
- package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
- package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
- package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
- package/packages/bundled-features/src/managed-pages/table.ts +16 -15
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/notes-history/entity.ts +4 -4
- package/packages/bundled-features/src/notes-history/feature.ts +2 -2
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/page-render/layout.ts +9 -9
- package/packages/bundled-features/src/page-render/markdown.ts +11 -11
- package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
- package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
- package/packages/bundled-features/src/seo/feature.ts +3 -3
- package/packages/bundled-features/src/sessions/constants.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +9 -9
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
- package/packages/bundled-features/src/sessions/screens.ts +2 -2
- package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
- package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
- package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +1 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
- package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
- package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
- package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
- package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -43
- package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +2 -2
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
- package/packages/bundled-features/src/tags/feature.ts +3 -3
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +10 -10
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
- package/packages/bundled-features/src/template-resolver/seeding.ts +4 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +1 -1
- package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
- package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
- package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
- package/packages/bundled-features/src/tenant/screens.ts +1 -1
- package/packages/bundled-features/src/tenant/seeding.ts +19 -18
- package/packages/bundled-features/src/tenant/testing.ts +5 -6
- package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
- package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
- package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
- package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
- package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
- package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
- package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
- package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +8 -8
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
- package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
- package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
- package/packages/bundled-features/src/user/schema/user.ts +45 -44
- package/packages/bundled-features/src/user/seeding.ts +40 -40
- package/packages/bundled-features/src/user/testing.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
- package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +166 -276
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
- package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
- package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
- package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
- package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
- package/packages/bundled-features/src/user-profile/index.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
- package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { v5 as uuidv5 } from "uuid";
|
|
2
2
|
|
|
3
|
-
// Fixed UUID
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Fixed UUID namespaces for deterministic aggregate-ID derivation.
|
|
4
|
+
// Generated once (2026-07-12) and immutable: changing one would re-key
|
|
5
|
+
// every existing aggregate stream, breaking message history and idempotency.
|
|
6
|
+
// Drift is pinned in __tests__/feature.test.ts.
|
|
7
7
|
|
|
8
|
-
/** Namespace
|
|
8
|
+
/** Namespace for inbound-message streams. */
|
|
9
9
|
const INBOUND_MESSAGE_NAMESPACE = "7f2a9c41-3d6b-4e0f-9c58-2b1e7a4d8f63";
|
|
10
10
|
|
|
11
|
-
/** Namespace
|
|
11
|
+
/** Namespace for mail-thread streams. */
|
|
12
12
|
const MAIL_THREAD_NAMESPACE = "b48d1e72-5c9a-4f36-8e0d-6a3f9b2c7e15";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Deterministic aggregate
|
|
16
|
-
* (accountId, providerMessageId):
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* Deterministic aggregate ID for an inbound message. The key is
|
|
16
|
+
* (accountId, providerMessageId): if the provider delivers the same message
|
|
17
|
+
* twice (IDLE duplicate notification, cursor overlap, watch-restart replay),
|
|
18
|
+
* both deliveries use the same stream, so the idempotency check in the
|
|
19
|
+
* ingest handler sees the event that was already appended.
|
|
20
20
|
*
|
|
21
|
-
* accountId
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* accountId, rather than tenantId, is part of the key because two accounts in
|
|
22
|
+
* the same tenant can receive the same email (CC'd to both inboxes); these
|
|
23
|
+
* are two distinct inbound messages.
|
|
24
24
|
*/
|
|
25
25
|
// @wrapper-known uuid-domain
|
|
26
26
|
export function inboundMessageAggregateId(accountId: string, providerMessageId: string): string {
|
|
@@ -28,11 +28,11 @@ export function inboundMessageAggregateId(accountId: string, providerMessageId:
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* Deterministic aggregate
|
|
32
|
-
* (tenantId, threadKey)
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* Deterministic aggregate ID for a mail thread. The key is
|
|
32
|
+
* (tenantId, threadKey): threads are tenant-wide, not account-specific, so a
|
|
33
|
+
* conversation spanning two connected inboxes is one thread. threadKey is
|
|
34
|
+
* normalized by the provider (References/In-Reply-To chain or provider
|
|
35
|
+
* thread ID).
|
|
36
36
|
*/
|
|
37
37
|
// @wrapper-known uuid-domain
|
|
38
38
|
export function mailThreadAggregateId(tenantId: string, threadKey: string): string {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// createInboundMailConnectRoutes — declarative extraRoutes
|
|
2
|
-
//
|
|
1
|
+
// createInboundMailConnectRoutes — declarative extraRoutes the app owner mounts
|
|
2
|
+
// via `extraRoutes` in buildServer.
|
|
3
3
|
//
|
|
4
4
|
// GET /api/inbound-mail/connect (entry:"user" — signed-in caller)
|
|
5
5
|
// GET /inbound-mail/oauth/callback (entry:"signature" — anonymous,
|
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
UserExtraRouteDeps,
|
|
18
18
|
} from "@cosmicdrift/kumiko-framework/api";
|
|
19
19
|
import { ExtraRouteRejection, signatureRoute } from "@cosmicdrift/kumiko-framework/api";
|
|
20
|
+
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
20
21
|
import type { Context } from "hono";
|
|
21
22
|
import {
|
|
22
23
|
INBOUND_MAIL_FOUNDATION_FEATURE,
|
|
@@ -241,7 +242,7 @@ export function createInboundMailConnectRoutes(
|
|
|
241
242
|
if (!dispatched.isSuccess) {
|
|
242
243
|
return errorJson(c, 502, "account_create_failed", JSON.stringify(dispatched.error ?? {}));
|
|
243
244
|
}
|
|
244
|
-
const accountId = (dispatched.data
|
|
245
|
+
const accountId = propertyOf(dispatched.data, "accountId");
|
|
245
246
|
if (typeof accountId !== "string") {
|
|
246
247
|
return errorJson(c, 502, "account_create_failed", "connect-account returned no accountId");
|
|
247
248
|
}
|
|
@@ -1,71 +1,69 @@
|
|
|
1
1
|
// Feature name
|
|
2
2
|
export const INBOUND_MAIL_FOUNDATION_FEATURE = "inbound-mail-foundation" as const;
|
|
3
3
|
|
|
4
|
-
// Extension-point name
|
|
4
|
+
// Extension-point name for provider plugins (inbound-provider-imap,
|
|
5
5
|
// inbound-provider-m365-graph, inbound-provider-gmail-rest, ...).
|
|
6
6
|
export const INBOUND_MAIL_PROVIDER_EXTENSION = "inboundMailProvider" as const;
|
|
7
7
|
|
|
8
8
|
// Qualified write handler names (QN format: scope:type:name).
|
|
9
9
|
export const InboundMailFoundationHandlers = {
|
|
10
|
-
/** Programmatic entry
|
|
11
|
-
* fetchSince
|
|
12
|
-
* PII
|
|
10
|
+
/** Programmatic entry point for provider plugins (watch callback +
|
|
11
|
+
* fetchSince sync): accepts a normalized message and atomically performs
|
|
12
|
+
* idempotency handling, PII encryption, event append, and thread update. */
|
|
13
13
|
ingestMessage: "inbound-mail-foundation:write:ingest-message",
|
|
14
|
-
/** Tenant
|
|
15
|
-
*
|
|
16
|
-
* an. */
|
|
14
|
+
/** Tenant admin connects a mailbox (IMAP credentials via secrets or an
|
|
15
|
+
* OAuth redirect via oauth-routes). Creates the mail-account stream. */
|
|
17
16
|
connectAccount: "inbound-mail-foundation:write:connect-account",
|
|
18
|
-
/** Account
|
|
19
|
-
*
|
|
17
|
+
/** Account status transitions (watch error/backoff, OAuth refresh
|
|
18
|
+
* failure, re-enabled). */
|
|
20
19
|
updateAccount: "inbound-mail-foundation:write:update-account",
|
|
21
|
-
/** Tenant
|
|
22
|
-
*
|
|
20
|
+
/** Tenant admin disconnects a mailbox. The stream remains for auditing;
|
|
21
|
+
* the status becomes disconnected and the watch stops. */
|
|
23
22
|
disconnectAccount: "inbound-mail-foundation:write:disconnect-account",
|
|
24
23
|
} as const;
|
|
25
24
|
|
|
26
25
|
// Qualified query handler names.
|
|
27
26
|
export const InboundMailFoundationQueries = {
|
|
28
|
-
/** Tenant-scoped
|
|
27
|
+
/** Tenant-scoped list of connected mailboxes. */
|
|
29
28
|
listAccounts: "inbound-mail-foundation:query:account:list",
|
|
30
|
-
/** Tenant-scoped
|
|
31
|
-
|
|
29
|
+
/** Tenant-scoped message list (inbox cockpit). PII is decrypted on read.
|
|
30
|
+
*/
|
|
32
31
|
listMessages: "inbound-mail-foundation:query:message:list",
|
|
33
32
|
} as const;
|
|
34
33
|
|
|
35
34
|
// Normalized account status values — provider-agnostic.
|
|
36
35
|
export const InboundMailAccountStatuses = {
|
|
37
|
-
/**
|
|
36
|
+
/** Connected; watch/sync is running or ready to start. */
|
|
38
37
|
active: "active",
|
|
39
|
-
/** Credentials
|
|
38
|
+
/** Credentials or token are invalid; the tenant admin must reconnect. */
|
|
40
39
|
authError: "auth_error",
|
|
41
40
|
/** Transienter Fehler, Supervisor backoff-retried. */
|
|
42
41
|
degraded: "degraded",
|
|
43
|
-
/**
|
|
42
|
+
/** Disconnected by the tenant admin; no further syncs run. */
|
|
44
43
|
disconnected: "disconnected",
|
|
45
44
|
} as const;
|
|
46
45
|
export type InboundMailAccountStatus =
|
|
47
46
|
(typeof InboundMailAccountStatuses)[keyof typeof InboundMailAccountStatuses];
|
|
48
47
|
|
|
49
48
|
/**
|
|
50
|
-
* Tenant
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* verifiziert, kein Framework-Gap.
|
|
49
|
+
* Tenant secret slot for an account: IMAP app password OR OAuth refresh
|
|
50
|
+
* token. The provider interprets the contents according to `authMethod`.
|
|
51
|
+
* Dynamic per-account keying is supported by the secrets feature:
|
|
52
|
+
* SecretsContext.get/set accept arbitrary string keys (resolveKey in
|
|
53
|
+
* secrets-context.ts), so no framework change is required.
|
|
56
54
|
*/
|
|
57
55
|
export function inboundCredentialSecretKey(accountId: string): string {
|
|
58
56
|
return `${INBOUND_MAIL_FOUNDATION_FEATURE}:inbound.credential.${accountId}`;
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
59
|
+
// Authentication method for an account, set by the connect flow and read
|
|
60
|
+
// by providers (IMAP uses it to distinguish the password form from the
|
|
61
|
+
// XOAUTH2 fallback).
|
|
64
62
|
export const InboundMailAuthMethods = {
|
|
65
63
|
/** Formular-Connect: Config (host/port/secure) + Tenant-Secret. */
|
|
66
64
|
password: "password",
|
|
67
|
-
/** SASL XOAUTH2
|
|
68
|
-
*
|
|
65
|
+
/** SASL XOAUTH2 over IMAP — fallback for M365/Gmail accounts without a
|
|
66
|
+
* mounted enterprise provider (same secret slot). */
|
|
69
67
|
xoauth2: "xoauth2",
|
|
70
68
|
/** Nativer OAuth-Provider (m365-graph, gmail-rest). */
|
|
71
69
|
oauth: "oauth",
|
|
@@ -73,8 +71,7 @@ export const InboundMailAuthMethods = {
|
|
|
73
71
|
export type InboundMailAuthMethod =
|
|
74
72
|
(typeof InboundMailAuthMethods)[keyof typeof InboundMailAuthMethods];
|
|
75
73
|
|
|
76
|
-
// **Multi-
|
|
77
|
-
// (
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
// connect-Flow.
|
|
74
|
+
// **Multi-provider:** no global `provider` config key
|
|
75
|
+
// (unlike mail-foundation, as with billing-foundation). A tenant can connect
|
|
76
|
+
// an IMAP mailbox and an M365 mailbox in parallel; the provider is stored per
|
|
77
|
+
// MailAccount row (`provider` field) and set by the connect flow.
|
|
@@ -9,28 +9,27 @@ import {
|
|
|
9
9
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
10
10
|
|
|
11
11
|
// ============================================================================
|
|
12
|
-
// Read
|
|
12
|
+
// Read models for the three event-sourced aggregates
|
|
13
13
|
// ============================================================================
|
|
14
14
|
//
|
|
15
|
-
// Inline
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
15
|
+
// Inline projection targets. Written EXCLUSIVELY by projection applies
|
|
16
|
+
// (see feature.ts), never directly by the handler.
|
|
17
|
+
// The event-store streams `mail-account` / `inbound-message` / `mail-thread`
|
|
18
|
+
// are the source of truth, so these tables can be rebuilt.
|
|
19
19
|
//
|
|
20
20
|
// **PII convention:** `personal: "tenant"` (not `encrypted`): fields must
|
|
21
|
-
// crypto-
|
|
22
|
-
// tenant
|
|
23
|
-
// maxLength
|
|
24
|
-
// <blob>` — Plaintext×~2.3 +
|
|
21
|
+
// be crypto-shredded when eraseSubjectKeys deletes the tenant subject key on
|
|
22
|
+
// tenant destruction (pattern from billing-foundation).
|
|
23
|
+
// maxLength is budgeted for ciphertext (`kumiko-pii:v1:<subject>:
|
|
24
|
+
// <blob>` — Plaintext×~2.3 + envelope overhead).
|
|
25
25
|
//
|
|
26
|
-
// **
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// Erasure-Pfad ist tenant-destroy).
|
|
26
|
+
// **Design decision:** The PII subject of an inbound mail is currently the
|
|
27
|
+
// TENANT (mailbox owner), not the external sender. A sender-forget flow would
|
|
28
|
+
// require per-sender keys and is deliberately not included; the erasure path
|
|
29
|
+
// is tenant destruction.
|
|
31
30
|
|
|
32
|
-
/**
|
|
33
|
-
* (= accountId, random uuid
|
|
31
|
+
/** A connected mailbox. One row per account, with PK = aggregateId
|
|
32
|
+
* (= accountId, random uuid on connect). */
|
|
34
33
|
export const mailAccountEntity = createEntity({
|
|
35
34
|
table: "read_mail_accounts",
|
|
36
35
|
fields: {
|
|
@@ -46,10 +45,10 @@ export const mailAccountEntity = createEntity({
|
|
|
46
45
|
personal: false,
|
|
47
46
|
reason: "technical_reference",
|
|
48
47
|
}),
|
|
49
|
-
// null = tenant-
|
|
50
|
-
//
|
|
51
|
-
// Owner + TenantAdmin (
|
|
52
|
-
// V1 (
|
|
48
|
+
// null = tenant-shared mailbox (info@), set = this user's personal
|
|
49
|
+
// mailbox. Visibility filters in the list queries:
|
|
50
|
+
// Owner + TenantAdmin (compliance); NO crypto-subject change in
|
|
51
|
+
// V1 (subject remains Tenant, see header).
|
|
53
52
|
ownerUserId: createTextField({ maxLength: 36, personal: false, reason: "pseudonymous_fk" }),
|
|
54
53
|
// Tenant-authored mailbox label, not a person's name.
|
|
55
54
|
displayName: createTextField({
|
|
@@ -57,7 +56,7 @@ export const mailAccountEntity = createEntity({
|
|
|
57
56
|
personal: false,
|
|
58
57
|
reason: "tenant_config_not_personal",
|
|
59
58
|
}),
|
|
60
|
-
//
|
|
59
|
+
// Mailbox address — tenant PII.
|
|
61
60
|
address: createTextField({ required: true, maxLength: 1000, personal: "tenant", find: "none" }),
|
|
62
61
|
status: createTextField({
|
|
63
62
|
required: true,
|
|
@@ -70,8 +69,8 @@ export const mailAccountEntity = createEntity({
|
|
|
70
69
|
},
|
|
71
70
|
});
|
|
72
71
|
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
72
|
+
/** An incoming mail (envelope + snippet, NO body — bodyRef
|
|
73
|
+
* points to file-foundation). PK = aggregateId =
|
|
75
74
|
* inboundMessageAggregateId(accountId, providerMessageId). */
|
|
76
75
|
export const inboundMessageEntity = createEntity({
|
|
77
76
|
table: "read_inbound_messages",
|
|
@@ -82,9 +81,9 @@ export const inboundMessageEntity = createEntity({
|
|
|
82
81
|
personal: false,
|
|
83
82
|
reason: "technical_reference",
|
|
84
83
|
}),
|
|
85
|
-
// Scope
|
|
86
|
-
//
|
|
87
|
-
//
|
|
84
|
+
// Scope is inherited from the account at ingest time: messages from a
|
|
85
|
+
// personal mailbox are visible only to the owner (+ TenantAdmin),
|
|
86
|
+
// without joining read_mail_accounts.
|
|
88
87
|
ownerUserId: createTextField({ maxLength: 36, personal: false, reason: "pseudonymous_fk" }),
|
|
89
88
|
messageIdHeader: createTextField({
|
|
90
89
|
required: true,
|
|
@@ -127,29 +126,29 @@ export const mailThreadEntity = createEntity({
|
|
|
127
126
|
},
|
|
128
127
|
});
|
|
129
128
|
|
|
130
|
-
// Single source of truth
|
|
131
|
-
// connect-handler)
|
|
132
|
-
//
|
|
133
|
-
//
|
|
129
|
+
// Single source of truth for the PII field lists — encrypt (ingest/
|
|
130
|
+
// connect-handler) and decrypt (list-queries) share the same list,
|
|
131
|
+
// so a future tenantOwned field cannot be omitted in either location
|
|
132
|
+
// (pattern from billing-foundation entities.ts).
|
|
134
133
|
export const MAIL_ACCOUNT_PII_FIELDS = collectPiiSubjectFields(mailAccountEntity);
|
|
135
134
|
export const INBOUND_MESSAGE_PII_FIELDS = collectPiiSubjectFields(inboundMessageEntity);
|
|
136
135
|
export const MAIL_THREAD_PII_FIELDS = collectPiiSubjectFields(mailThreadEntity);
|
|
137
136
|
|
|
138
137
|
// ============================================================================
|
|
139
|
-
// Unmanaged
|
|
138
|
+
// Unmanaged direct-write stores — sync machinery, NOT event-sourced
|
|
140
139
|
// ============================================================================
|
|
141
140
|
//
|
|
142
|
-
// SyncCursor + SeenMessage
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
141
|
+
// SyncCursor + SeenMessage are technical tick state for the watch/sync
|
|
142
|
+
// loops: high-frequency writes without business-fact semantics. As
|
|
143
|
+
// r.entity, they would (a) flood the event log and (b) be wiped during a
|
|
144
|
+
// projection rebuild (direct write without an event means the rebuild finds
|
|
145
|
+
// nothing). Therefore r.unmanagedTable — migration DDL, but not a rebuild
|
|
146
|
+
// target (pattern from sessions/feature.ts).
|
|
148
147
|
|
|
149
|
-
/** Provider
|
|
150
|
-
* Graph deltaLink, Gmail historyId.
|
|
151
|
-
* Write-locked
|
|
152
|
-
*
|
|
148
|
+
/** Provider cursor per account ("where was I?"): IMAP UIDVALIDITY:UIDNEXT,
|
|
149
|
+
* Graph deltaLink, Gmail historyId. One row per (accountId, scope).
|
|
150
|
+
* Write-locked to privileged — only Foundation handlers/supervisors
|
|
151
|
+
* write it; tenant requests cannot. */
|
|
153
152
|
export const syncCursorEntity = createEntity({
|
|
154
153
|
table: "store_mail_sync_cursors",
|
|
155
154
|
softDelete: false,
|
|
@@ -182,10 +181,10 @@ export const syncCursorEntity = createEntity({
|
|
|
182
181
|
},
|
|
183
182
|
});
|
|
184
183
|
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
* ingest
|
|
188
|
-
*
|
|
184
|
+
/** Deduplication anchor for O(1) idempotency without scanning the stream
|
|
185
|
+
* for very long message histories: (accountId, providerMessageId) UNIQUE.
|
|
186
|
+
* The ingest handler checks here first (cheap); the stream scan remains
|
|
187
|
+
* defense-in-depth. */
|
|
189
188
|
export const seenMessageEntity = createEntity({
|
|
190
189
|
table: "store_mail_seen_messages",
|
|
191
190
|
softDelete: false,
|
|
@@ -211,9 +210,9 @@ export const seenMessageEntity = createEntity({
|
|
|
211
210
|
},
|
|
212
211
|
});
|
|
213
212
|
|
|
214
|
-
// Plain EntityTableMeta (
|
|
215
|
-
//
|
|
216
|
-
//
|
|
213
|
+
// Plain EntityTableMeta (not a branded EntityTable) — unmanaged direct-
|
|
214
|
+
// write stores; handlers write via ctx.db (see user-session.ts-
|
|
215
|
+
// rationale).
|
|
217
216
|
export const syncCursorTable = deriveEntityTableMeta("mail-sync-cursor", syncCursorEntity, {
|
|
218
217
|
source: "unmanaged",
|
|
219
218
|
});
|
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
// Domain
|
|
1
|
+
// Domain events for inbound-mail-foundation.
|
|
2
2
|
//
|
|
3
|
-
// **Pattern:** event-sourced —
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// **Pattern:** event-sourced — each incoming mail and account-lifecycle
|
|
4
|
+
// transition becomes a domain event. Read models = inline projections
|
|
5
|
+
// (read_mail_accounts / read_inbound_messages / read_mail_threads).
|
|
6
|
+
// Future consumers (business processes: ticket creation, receipt
|
|
7
|
+
// recognition, auto-replies) listen directly to `inbound-message-received`
|
|
8
|
+
// and can replay the COMPLETE history retroactively via
|
|
9
|
+
// extendEntityProjection.
|
|
10
10
|
//
|
|
11
|
-
// **Payload
|
|
12
|
-
// -
|
|
13
|
-
// provider-raw
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
11
|
+
// **Payload discipline (events are forever):**
|
|
12
|
+
// - Domain-clean and generic: no app-specific terms (no solon), and no
|
|
13
|
+
// provider-raw structures in the payload — raw data lives in
|
|
14
|
+
// metadata.headers.
|
|
15
|
+
// - NO bodies: bodyRef points to file-foundation storage. The event store
|
|
16
|
+
// is not a blob store.
|
|
17
|
+
// - PII (address/from/to/cc/subject/snippet) is stored as ciphertext in
|
|
18
|
+
// the payload (`kumiko-pii:v1:...`), encrypted BEFORE append in the
|
|
19
|
+
// write handler — the subject key is the tenant, and tenant destruction's
|
|
20
|
+
// eraseSubjectKeys makes both the event log and projection unreadable
|
|
21
|
+
// (crypto-shredding, the billing-foundation pattern).
|
|
21
22
|
|
|
22
23
|
import * as z from "zod";
|
|
23
24
|
import { INBOUND_MAIL_FOUNDATION_FEATURE, InboundMailAccountStatuses } from "./constants.ts";
|
|
24
25
|
|
|
25
|
-
// Aggregate
|
|
26
|
+
// Aggregate types for the event store.
|
|
26
27
|
export const MAIL_ACCOUNT_AGGREGATE_TYPE = "mail-account" as const;
|
|
27
28
|
export const INBOUND_MESSAGE_AGGREGATE_TYPE = "inbound-message" as const;
|
|
28
29
|
export const MAIL_THREAD_AGGREGATE_TYPE = "mail-thread" as const;
|
|
29
30
|
|
|
30
|
-
// Event-name
|
|
31
|
-
//
|
|
31
|
+
// Event-name constants — short forms (for r.defineEvent) and qualified
|
|
32
|
+
// FQNs (for ctx.unsafeAppendEvent and projection-apply keys).
|
|
32
33
|
export const MAIL_ACCOUNT_CONNECTED_EVENT_SHORT = "mail-account-connected" as const;
|
|
33
34
|
export const MAIL_ACCOUNT_UPDATED_EVENT_SHORT = "mail-account-updated" as const;
|
|
34
35
|
export const MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT = "mail-account-disconnected" as const;
|
|
@@ -54,48 +55,50 @@ const accountStatusEnum = z.enum([
|
|
|
54
55
|
]);
|
|
55
56
|
|
|
56
57
|
// ============================================================================
|
|
57
|
-
// mail-account
|
|
58
|
+
// mail-account stream — connected / updated / disconnected
|
|
58
59
|
// ============================================================================
|
|
59
60
|
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
// (
|
|
63
|
-
// billing-foundation events.ts).
|
|
61
|
+
// One stream per mailbox (aggregateId = accountId, random UUID on connect).
|
|
62
|
+
// address is PII, so maxLength is 1000 to allow for ciphertext expansion
|
|
63
|
+
// (a 200-character plaintext becomes ~460+ characters in a JSON envelope;
|
|
64
|
+
// see billing-foundation events.ts).
|
|
64
65
|
export const mailAccountEventPayloadSchema = z.object({
|
|
65
66
|
provider: z.string().min(1).max(50),
|
|
66
|
-
/** "password" | "xoauth2" | "oauth" (InboundMailAuthMethods) —
|
|
67
|
-
* string
|
|
67
|
+
/** "password" | "xoauth2" | "oauth" (InboundMailAuthMethods) — deliberately
|
|
68
|
+
* a string rather than an enum, so new auth methods require no event
|
|
69
|
+
* upcaster. */
|
|
68
70
|
authMethod: z.string().min(1).max(30),
|
|
69
|
-
/** null = tenant
|
|
71
|
+
/** null = shared by the tenant; otherwise, this user's personal mailbox. */
|
|
70
72
|
ownerUserId: z.string().max(36).nullable(),
|
|
71
73
|
displayName: z.string().max(200),
|
|
72
74
|
address: z.string().min(1).max(1000),
|
|
73
75
|
status: accountStatusEnum,
|
|
74
|
-
/** Provider-
|
|
75
|
-
*
|
|
76
|
+
/** Provider-agnostic watch state ("idle", "watching", "backoff:3", ...)
|
|
77
|
+
* — an operational signal only, not PII. */
|
|
76
78
|
watchState: z.string().max(100),
|
|
77
79
|
});
|
|
78
80
|
export type MailAccountEventPayload = z.infer<typeof mailAccountEventPayloadSchema>;
|
|
79
81
|
|
|
80
82
|
// ============================================================================
|
|
81
|
-
// inbound-message
|
|
83
|
+
// inbound-message stream — exactly ONE received event per message
|
|
82
84
|
// ============================================================================
|
|
83
85
|
//
|
|
84
86
|
// aggregateId = inboundMessageAggregateId(accountId, providerMessageId)
|
|
85
|
-
// → deterministic,
|
|
87
|
+
// → deterministic, so provider replays collide on the same stream.
|
|
86
88
|
//
|
|
87
|
-
// PII
|
|
88
|
-
// to/cc
|
|
89
|
-
//
|
|
89
|
+
// PII fields (from/to/cc/subject/snippet): ciphertext with generous
|
|
90
|
+
// maximum lengths. to/cc are JSON-stringified string[] BEFORE encryption;
|
|
91
|
+
// the payload contains the ciphertext string, not the array (primitives only,
|
|
92
|
+
// upcaster-safe).
|
|
90
93
|
export const inboundMessageEventPayloadSchema = z.object({
|
|
91
94
|
accountId: z.uuid(),
|
|
92
|
-
/** Scope
|
|
95
|
+
/** Scope inherited from the account at ingest time. */
|
|
93
96
|
ownerUserId: z.string().max(36).nullable(),
|
|
94
|
-
/** RFC-5322 Message-ID
|
|
95
|
-
*
|
|
97
|
+
/** RFC-5322 Message-ID header (normalized, without <>) — NOT PII-encrypted:
|
|
98
|
+
* idempotency/threading anchor and opaque technical ID. */
|
|
96
99
|
messageIdHeader: z.string().min(1).max(500),
|
|
97
|
-
/**
|
|
98
|
-
*
|
|
100
|
+
/** Normalized thread key (References-chain root or provider thread ID,
|
|
101
|
+
* prefixed by the provider). */
|
|
99
102
|
threadKey: z.string().min(1).max(500),
|
|
100
103
|
from: z.string().min(1).max(2000),
|
|
101
104
|
/** JSON-stringified string[], dann PII-encrypted. */
|
|
@@ -104,14 +107,14 @@ export const inboundMessageEventPayloadSchema = z.object({
|
|
|
104
107
|
cc: z.string().max(8000),
|
|
105
108
|
subject: z.string().max(4000),
|
|
106
109
|
snippet: z.string().max(4000),
|
|
107
|
-
/** ISO
|
|
108
|
-
* receivedDateTime),
|
|
110
|
+
/** ISO instant — receipt time reported by the provider (INTERNALDATE or
|
|
111
|
+
* receivedDateTime), not ingest time. */
|
|
109
112
|
receivedAtIso: z.string().min(1),
|
|
110
|
-
/** file-foundation
|
|
111
|
-
*
|
|
113
|
+
/** file-foundation reference to the raw body (MIME). Empty when the app
|
|
114
|
+
* is mounted without body persistence (snippet-only mode). */
|
|
112
115
|
bodyRef: z.string().max(500),
|
|
113
|
-
/**
|
|
114
|
-
*
|
|
116
|
+
/** Domain scope hint for downstream business processes — generic
|
|
117
|
+
* ("inbox", folder name), with NO app-specific semantics. */
|
|
115
118
|
scope: z.string().max(200),
|
|
116
119
|
});
|
|
117
120
|
export type InboundMessageEventPayload = z.infer<typeof inboundMessageEventPayloadSchema>;
|
|
@@ -134,14 +137,15 @@ export type MailThreadEventPayload = z.infer<typeof mailThreadEventPayloadSchema
|
|
|
134
137
|
export type InboundMessageEventHeaders = {
|
|
135
138
|
readonly providerMessageId: string;
|
|
136
139
|
readonly providerName: string;
|
|
137
|
-
/** Provider
|
|
138
|
-
*
|
|
140
|
+
/** Provider cursor snapshot at ingest time (UIDVALIDITY:UID, deltaLink,
|
|
141
|
+
* historyId ...) — useful for debugging and replay, not part of the
|
|
142
|
+
* payload. */
|
|
139
143
|
readonly providerCursor: string;
|
|
140
144
|
};
|
|
141
145
|
|
|
142
146
|
export type MailAccountEventHeaders = {
|
|
143
147
|
readonly providerName: string;
|
|
144
|
-
/**
|
|
148
|
+
/** What triggered the transition ("connect_flow", "watch_supervisor",
|
|
145
149
|
* "oauth_refresh", "tenant_admin"). */
|
|
146
150
|
readonly reason: string;
|
|
147
151
|
};
|