@cosmicdrift/kumiko-samples 0.386.0 → 0.388.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +9 -2
- package/packages/bundled-features/src/agent-tools/changes.json +6 -0
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
- package/packages/bundled-features/src/audit/changes.json +12 -0
- package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
- 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/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
- 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 +9 -4
- 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-code-or-recovery-field.tsx +68 -0
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
- package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -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/plan-switch-preview.query.ts +65 -0
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
- package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
- package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
- package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
- package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
- 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 +144 -66
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
- package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
- 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/cap-reservation.ts +5 -1
- package/packages/bundled-features/src/cap-counter/changes.json +18 -0
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
- 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 +9 -2
- 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/changes.json +6 -0
- package/packages/bundled-features/src/channel-email/feature.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/changes.json +12 -0
- package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -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/handlers/values.query.ts +4 -2
- 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 +28 -9
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
- 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/changes.json +30 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
- package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
- package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
- 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/handlers/preferences.query.ts +20 -1
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
- package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
- package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
- 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-foundation/index.ts +1 -0
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
- 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/README.md +1 -1
- 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/changes.json +6 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -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/host-routing/README.md +1 -1
- package/packages/bundled-features/src/host-routing/changes.json +6 -0
- package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
- package/packages/bundled-features/src/host-routing/options.ts +2 -1
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
- 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 +27 -15
- package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
- 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/screens.ts +0 -3
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
- 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/changes.json +13 -0
- 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 +20 -11
- 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/handlers/tenant-failures.query.ts +45 -40
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
- 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/README.md +1 -1
- 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/changes.json +6 -0
- package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
- 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 +9 -6
- 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/renderer-pdf/changes.json +6 -0
- package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
- 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 +16 -11
- 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 +11 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/index.ts +1 -1
- package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
- 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/step-dispatcher/changes.json +6 -0
- package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
- package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
- package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
- package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
- package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
- package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
- package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
- package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
- package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
- 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/changes.json +12 -0
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -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 +9 -8
- 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 +41 -14
- package/packages/bundled-features/src/template-resolver/changes.json +48 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
- package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
- 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/tenant-override-counts.query.ts +9 -5
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
- 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/handlers/usage.query.ts +37 -26
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
- package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
- package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
- package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
- package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
- package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
- package/packages/bundled-features/src/tenant/changes.json +6 -0
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
- 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 +8 -5
- 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/changes.json +6 -0
- package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
- 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/changes.json +6 -0
- 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 +12 -9
- 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/constants.ts +3 -3
- 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 +169 -280
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
- 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/waitlist/changes.json +18 -0
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
- package/packages/bundled-features/src/waitlist/import.ts +5 -0
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
- package/packages/bundled-features/src/waitlist/options.ts +3 -0
- 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
- package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
- package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
- package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
- package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
- package/samples/recipes/auth-mfa/README.md +5 -0
- package/samples/recipes/auth-mfa/package.json +5 -2
- package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
- package/samples/recipes/auth-mfa/tsconfig.json +8 -0
- package/samples/recipes/env-composition/README.md +3 -1
- package/samples/recipes/env-composition/src/env.ts +2 -0
- package/samples/recipes/legal-pages/README.md +1 -1
- package/samples/recipes/rate-limiting/README.md +18 -0
- package/samples/recipes/rate-limiting/src/feature.ts +12 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
// ingest-message — programmatic entry
|
|
2
|
-
// (watch
|
|
3
|
-
// RawInboundMessage
|
|
1
|
+
// ingest-message — programmatic entry point for provider plugins
|
|
2
|
+
// (watch callback + fetchSince sync). Accepts a normalized
|
|
3
|
+
// RawInboundMessage and performs atomically in ONE TX:
|
|
4
4
|
//
|
|
5
|
-
// 1. Idempotency
|
|
6
|
-
// depth:
|
|
7
|
-
// 2. threadKey
|
|
8
|
-
// References
|
|
9
|
-
// 3. PII
|
|
10
|
-
//
|
|
11
|
-
// 4. inbound-message-received
|
|
12
|
-
// read_inbound_messages in
|
|
5
|
+
// 1. Idempotency check (cheap: store_mail_seen_messages; defense in
|
|
6
|
+
// depth: stream existence check on the deterministic aggregateId).
|
|
7
|
+
// 2. threadKey normalization (provider thread ID preferred, otherwise
|
|
8
|
+
// References chain root, otherwise Message-ID = single-message thread).
|
|
9
|
+
// 3. PII encryption (from/to/cc/subject/snippet) BEFORE the append —
|
|
10
|
+
// both the event log AND projection contain ciphertext.
|
|
11
|
+
// 4. inbound-message-received append (inline projection writes
|
|
12
|
+
// read_inbound_messages in the same TX). Savepoint-scoped
|
|
13
13
|
// (ctx.tryAppendEvent) — a losing concurrent ingest for the same
|
|
14
14
|
// messageAggId returns { duplicate: true } instead of failing the TX.
|
|
15
|
-
// 5. Thread
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
// 6. seen-message
|
|
15
|
+
// 5. Thread rollup: mail-thread-updated append with a recalculated
|
|
16
|
+
// snapshot (count+1, max(lastMessageAt)) — the apply is a
|
|
17
|
+
// dumb UPSERT.
|
|
18
|
+
// 6. Insert the seen-message deduplication anchor.
|
|
19
19
|
//
|
|
20
|
-
// SystemAdmin-only:
|
|
21
|
-
//
|
|
20
|
+
// SystemAdmin-only: the caller is the watch/sync supervisor or
|
|
21
|
+
// the poll cron with a programmatic SystemUser — never a tenant request.
|
|
22
22
|
|
|
23
23
|
import {
|
|
24
24
|
configuredPiiSubjectKms,
|
|
@@ -49,25 +49,25 @@ import {
|
|
|
49
49
|
import { inboundMessagesProjectionTable } from "../projection.ts";
|
|
50
50
|
|
|
51
51
|
// =============================================================================
|
|
52
|
-
// Input
|
|
53
|
-
// types.ts)
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
52
|
+
// Input schema — the normalized provider output (RawInboundMessage,
|
|
53
|
+
// types.ts) plus the envelope (accountId/providerName/providerCursor). rawMime
|
|
54
|
+
// is intentionally excluded: the caller persists the body to
|
|
55
|
+
// file-foundation BEFORE the ingest call and passes only bodyRef — the
|
|
56
|
+
// handler payload remains blob-free (event-store discipline).
|
|
57
57
|
// =============================================================================
|
|
58
58
|
|
|
59
59
|
export const ingestMessageSchema = z.object({
|
|
60
60
|
accountId: z.uuid(),
|
|
61
|
-
/** Scope
|
|
62
|
-
* MailAccountRecord
|
|
61
|
+
/** Scope inherited from the account — the supervisor knows the
|
|
62
|
+
* MailAccountRecord and passes ownerUserId through. */
|
|
63
63
|
ownerUserId: z.string().max(36).nullable(),
|
|
64
64
|
providerName: z.string().min(1).max(50),
|
|
65
|
-
/** Provider-native Message-ID —
|
|
65
|
+
/** Provider-native Message-ID — idempotency anchor with accountId. */
|
|
66
66
|
providerMessageId: z.string().min(1).max(500),
|
|
67
|
-
/** RFC-5322 Message-ID
|
|
67
|
+
/** RFC-5322 Message-ID without <>; null → deterministic fallback. */
|
|
68
68
|
messageIdHeader: z.string().min(1).max(500).nullable(),
|
|
69
69
|
providerThreadId: z.string().min(1).max(500).nullable(),
|
|
70
|
-
/** References/In-Reply-To
|
|
70
|
+
/** References/In-Reply-To chain, oldest first. */
|
|
71
71
|
references: z.array(z.string().min(1).max(500)).max(200),
|
|
72
72
|
from: z.string().min(1).max(2000),
|
|
73
73
|
to: z.array(z.string().max(2000)).max(200),
|
|
@@ -78,20 +78,20 @@ export const ingestMessageSchema = z.object({
|
|
|
78
78
|
/** file-foundation-Ref; leer im snippet-only-Mode. */
|
|
79
79
|
bodyRef: z.string().max(500),
|
|
80
80
|
scope: z.string().min(1).max(200),
|
|
81
|
-
/** Cursor
|
|
82
|
-
* metadata.headers,
|
|
81
|
+
/** Cursor snapshot at ingest time — used for debugging/replay and stored in
|
|
82
|
+
* metadata.headers, never in the payload. */
|
|
83
83
|
providerCursor: z.string().max(2000),
|
|
84
84
|
});
|
|
85
85
|
type IngestMessagePayload = z.infer<typeof ingestMessageSchema>;
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* threadKey
|
|
89
|
-
* 1.
|
|
90
|
-
* IMAP
|
|
91
|
-
* 2.
|
|
92
|
-
*
|
|
93
|
-
* 3.
|
|
94
|
-
*
|
|
88
|
+
* Normalizes threadKey:
|
|
89
|
+
* 1. Use the provider thread ID when present — prefix it with the provider
|
|
90
|
+
* so IMAP References keys and Graph conversationIds never collide.
|
|
91
|
+
* 2. Otherwise use the root of the References chain (the oldest Message-ID,
|
|
92
|
+
* which is the thread anchor shared by all replies).
|
|
93
|
+
* 3. Otherwise use the own Message-ID → single-message thread; a later
|
|
94
|
+
* reply carries it as the References root and joins the same thread.
|
|
95
95
|
*/
|
|
96
96
|
function buildThreadKey(p: IngestMessagePayload, effectiveMessageIdHeader: string): string {
|
|
97
97
|
if (p.providerThreadId) return `${p.providerName}:${p.providerThreadId}`.slice(0, 500);
|
|
@@ -123,12 +123,12 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
123
123
|
const messageAggId = inboundMessageAggregateId(payload.accountId, payload.providerMessageId);
|
|
124
124
|
|
|
125
125
|
// ---------------------------------------------------------------
|
|
126
|
-
// 1. Idempotency.
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
126
|
+
// 1. Idempotency. Use the deduplication anchor row first because it is
|
|
127
|
+
// cheap. The stream check afterward provides defense in depth if
|
|
128
|
+
// an earlier ingest died AFTER the append but BEFORE the seen insert
|
|
129
|
+
// (this cannot happen within one TX, but the check is cheap and makes
|
|
130
|
+
// the handler robust to rebuilding if store_mail_seen_messages is
|
|
131
|
+
// ever truncated).
|
|
132
132
|
// ---------------------------------------------------------------
|
|
133
133
|
const seenRows = await ctx.db.selectMany(seenMessageTable, {
|
|
134
134
|
accountId: payload.accountId,
|
|
@@ -163,11 +163,10 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
163
163
|
const threadAggId = mailThreadAggregateId(tenantId, threadKey);
|
|
164
164
|
|
|
165
165
|
// ---------------------------------------------------------------
|
|
166
|
-
// 3. PII
|
|
167
|
-
//
|
|
168
|
-
// (primitives only, upcaster-safe).
|
|
169
|
-
// plaintext
|
|
170
|
-
// billing-foundation process-event #724/#800).
|
|
166
|
+
// 3. PII encryption. Serialize to/cc as JSON BEFORE encryption so the
|
|
167
|
+
// payload contains a ciphertext string rather than an array
|
|
168
|
+
// (primitives only, upcaster-safe). If no KMS is configured, pass
|
|
169
|
+
// through plaintext (engine-off behavior).
|
|
171
170
|
// ---------------------------------------------------------------
|
|
172
171
|
const piiKms = configuredPiiSubjectKms();
|
|
173
172
|
const messagePlainPii = {
|
|
@@ -243,14 +242,14 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
243
242
|
// concurrent ingests on the same thread (Watch-Push vs.
|
|
244
243
|
// Poll-Reconciliation overlap, or two different messages of the
|
|
245
244
|
// same thread arriving at once) converge on the true count.
|
|
246
|
-
// acquireNamespacedAdvisoryLock below
|
|
245
|
+
// acquireNamespacedAdvisoryLock below serializes this whole
|
|
247
246
|
// countWhere+append section per threadAggId — transaction-scoped,
|
|
248
247
|
// so it survives tryAppendEvent's inner SAVEPOINT and releases at
|
|
249
248
|
// the enclosing TX's commit/rollback. Without it, a concurrent
|
|
250
249
|
// commit landing between countWhere and tryAppendEvent's own fresh
|
|
251
250
|
// version-read makes the append succeed with a stale count instead
|
|
252
251
|
// of a VersionConflictError, so the retry loop below never sees it
|
|
253
|
-
// as a conflict to retry (
|
|
252
|
+
// as a conflict to retry (the original gap). Unlike step 4, a
|
|
254
253
|
// lost version-conflict race here must NOT be treated as a no-op
|
|
255
254
|
// duplicate — skipping would leave this message's contribution to
|
|
256
255
|
// messageCount/lastMessageAt out of the thread forever. Exhausting
|
|
@@ -315,8 +314,8 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
315
314
|
}
|
|
316
315
|
|
|
317
316
|
// ---------------------------------------------------------------
|
|
318
|
-
// 6.
|
|
319
|
-
//
|
|
317
|
+
// 6. Deduplication anchor. It runs in the same TX as the appends, so
|
|
318
|
+
// if the handler fails, everything is rolled back together.
|
|
320
319
|
// ---------------------------------------------------------------
|
|
321
320
|
await ctx.db.insertOne(seenMessageTable, {
|
|
322
321
|
tenantId,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// list-accounts — tenant-scoped
|
|
2
|
-
// Connect
|
|
3
|
-
// billing-foundation list-subscriptions
|
|
1
|
+
// list-accounts — tenant-scoped list of connected mailboxes for the
|
|
2
|
+
// Connect/Settings UI. PII (address) is decrypted on read, following the
|
|
3
|
+
// billing-foundation list-subscriptions pattern.
|
|
4
4
|
//
|
|
5
|
-
// **Scope
|
|
6
|
-
// (ownerUserId=null)
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
5
|
+
// **Scope visibility:** authorized users can see shared mailboxes
|
|
6
|
+
// (ownerUserId=null); personal mailboxes are visible only to their owner,
|
|
7
|
+
// TenantAdmin, or SystemAdmin for compliance access. Filtering runs in memory
|
|
8
|
+
// after the tenant-scoped select because a tenant has only a single- to
|
|
9
|
+
// double-digit number of connected mailboxes.
|
|
10
10
|
import {
|
|
11
11
|
configuredPiiSubjectKms,
|
|
12
12
|
decryptPiiFieldValues,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// list-messages — tenant-scoped
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// list-messages — tenant-scoped message list for the inbox cockpit.
|
|
2
|
+
// Optional filters: accountId (one mailbox), threadKey (one conversation),
|
|
3
|
+
// scope (folder hint). PII (from/to/cc/subject/snippet) is decrypted on read;
|
|
4
|
+
// to/cc remain JSON-stringified strings, which the client parses as documented
|
|
5
|
+
// in the event payload.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// Deliberately no pagination in V1: the projection is tenant-scoped and the
|
|
8
|
+
// inbox cockpit loads bounded time ranges; a `limit` field can be added
|
|
9
|
+
// compatibly without breaking the QN.
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
configuredPiiSubjectKms,
|
|
@@ -42,8 +42,8 @@ export const listMessagesQuery: QueryHandlerDef = {
|
|
|
42
42
|
if (payload.scope) filter["scope"] = payload.scope;
|
|
43
43
|
|
|
44
44
|
const allRows = await ctx.db.selectMany(inboundMessagesProjectionTable, filter);
|
|
45
|
-
// Scope
|
|
46
|
-
//
|
|
45
|
+
// Scope visibility: messages in personal mailboxes are visible only to the
|
|
46
|
+
// owner or TenantAdmin/SystemAdmin.
|
|
47
47
|
const rows = allRows.filter((row) => isVisibleToCaller(row, ctx.user));
|
|
48
48
|
const piiKms = configuredPiiSubjectKms();
|
|
49
49
|
if (!piiKms) return { rows };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// Scope
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// für read_mail_accounts und read_inbound_messages (Scope-Vererbung).
|
|
1
|
+
// Scope visibility: shared rows (`ownerUserId=null`) are visible to any authorized caller;
|
|
2
|
+
// personal rows are visible only to the owner, `TenantAdmin`, or `SystemAdmin` for compliance.
|
|
3
|
+
// The same rule applies to `read_mail_accounts` and `read_inbound_messages`.
|
|
5
4
|
|
|
6
5
|
export function isVisibleToCaller(
|
|
7
6
|
row: Readonly<Record<string, unknown>>,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
// update-account — Account
|
|
2
|
-
// error/backoff, OAuth
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// update-account — Account status transitions: the watch supervisor reports
|
|
2
|
+
// error/backoff, OAuth refresh fails (auth_error), or a tenant admin re-enables
|
|
3
|
+
// the account after fixing its credentials. Full-snapshot event: loads the
|
|
4
|
+
// latest state, merges the delta fields, and appends the new snapshot.
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
|
|
7
|
+
import {
|
|
8
|
+
type SessionUser,
|
|
9
|
+
SYSTEM_USER_ID,
|
|
10
|
+
type WriteHandlerDef,
|
|
11
|
+
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
12
|
import { failNotFound, failUnprocessable } from "@cosmicdrift/kumiko-framework/errors";
|
|
8
13
|
import * as z from "zod";
|
|
9
14
|
import { InboundMailAccountStatuses } from "../constants.ts";
|
|
@@ -27,12 +32,19 @@ export const updateAccountSchema = z.object({
|
|
|
27
32
|
/** Ops-Signal ("idle", "watching", "backoff:3", ...). */
|
|
28
33
|
watchState: z.string().max(100).optional(),
|
|
29
34
|
displayName: z.string().max(200).optional(),
|
|
30
|
-
/** Audit
|
|
31
|
-
* "
|
|
32
|
-
reason: z.string().min(1).max(100),
|
|
35
|
+
/** Audit reason for metadata.headers, honored for the system identity only
|
|
36
|
+
* ("watch_supervisor", "oauth_refresh"); user callers get a role-derived reason. */
|
|
37
|
+
reason: z.string().min(1).max(100).optional(),
|
|
33
38
|
});
|
|
34
39
|
type UpdateAccountPayload = z.infer<typeof updateAccountSchema>;
|
|
35
40
|
|
|
41
|
+
const SYSTEM_FALLBACK_REASON = "system";
|
|
42
|
+
|
|
43
|
+
function auditReasonFor(user: SessionUser, requestedReason: string | undefined): string {
|
|
44
|
+
if (user.id === SYSTEM_USER_ID) return requestedReason ?? SYSTEM_FALLBACK_REASON;
|
|
45
|
+
return user.roles.includes(ROLES.SystemAdmin) ? "system_admin" : "tenant_admin";
|
|
46
|
+
}
|
|
47
|
+
|
|
36
48
|
export const updateAccountHandler: WriteHandlerDef = {
|
|
37
49
|
name: "update-account",
|
|
38
50
|
schema: updateAccountSchema,
|
|
@@ -48,15 +60,15 @@ export const updateAccountHandler: WriteHandlerDef = {
|
|
|
48
60
|
return failNotFound("mail-account", payload.accountId);
|
|
49
61
|
}
|
|
50
62
|
if (current.status === InboundMailAccountStatuses.disconnected) {
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
63
|
+
// Disconnected accounts are final; re-enabling requires a fresh connect
|
|
64
|
+
// (new stream, new secret slot). This prevents a delayed supervisor tick
|
|
65
|
+
// from restoring a disconnected account to active (disconnect vs. poll
|
|
66
|
+
// race).
|
|
55
67
|
return failUnprocessable("account_disconnected", { accountId: payload.accountId });
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
70
|
+
// address/provider/authMethod come unchanged from the latest snapshot
|
|
71
|
+
// (address remains ciphertext—never re-encrypt it).
|
|
60
72
|
const eventPayload: MailAccountEventPayload = {
|
|
61
73
|
...current,
|
|
62
74
|
...(payload.status !== undefined ? { status: payload.status } : {}),
|
|
@@ -65,7 +77,7 @@ export const updateAccountHandler: WriteHandlerDef = {
|
|
|
65
77
|
};
|
|
66
78
|
const headers: MailAccountEventHeaders = {
|
|
67
79
|
providerName: current.provider,
|
|
68
|
-
reason: payload.reason,
|
|
80
|
+
reason: auditReasonFor(event.user, payload.reason),
|
|
69
81
|
};
|
|
70
82
|
await ctx.unsafeAppendEvent({
|
|
71
83
|
aggregateId: payload.accountId,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
// HMAC-
|
|
1
|
+
// HMAC-signed OAuth-`state` parameter for the connect flow.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
3
|
+
// Binds {tenantId, ownerUserId?, providerKey, mailbox, nonce} to the
|
|
4
|
+
// redirect: the anonymous callback (outside /api/*) trusts only the
|
|
5
|
+
// verified state, preventing CSRF and cross-tenant or cross-user claiming
|
|
6
|
+
// because an attacker cannot redirect the callback to another tenant or
|
|
7
|
+
// user without breaking the signature.
|
|
8
8
|
//
|
|
9
9
|
// Format: <payload-base64url>.<expiresAtMs>.<hmac-base64url>
|
|
10
|
-
//
|
|
11
|
-
// HMAC
|
|
10
|
+
// Patterned after auth-email-password/signed-token.ts (HMAC-SHA256, purpose
|
|
11
|
+
// in the HMAC input, timing-safe comparison, expiry in the clear-text
|
|
12
|
+
// segment).
|
|
12
13
|
|
|
13
14
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
14
15
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
@@ -18,14 +19,14 @@ const STATE_PURPOSE = "inbound-mail-oauth-connect";
|
|
|
18
19
|
|
|
19
20
|
export type OAuthStatePayload = {
|
|
20
21
|
readonly tenantId: string;
|
|
21
|
-
/** null = shared
|
|
22
|
+
/** null = shared mailbox; otherwise this user's personal mailbox. */
|
|
22
23
|
readonly ownerUserId: string | null;
|
|
23
24
|
readonly providerKey: string;
|
|
24
|
-
/**
|
|
25
|
-
*
|
|
25
|
+
/** Mailbox address from the connect request; after token exchange, it is
|
|
26
|
+
* stored in the MailAccount. */
|
|
26
27
|
readonly mailbox: string;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
28
|
+
/** One-time nonce makes each state unique, preventing replay across
|
|
29
|
+
* two parallel connect flows. */
|
|
29
30
|
readonly nonce: string;
|
|
30
31
|
};
|
|
31
32
|
|
|
@@ -72,8 +73,8 @@ export function verifyOAuthState(
|
|
|
72
73
|
const expected = sign(hmacInput(payloadB64, expiresAtMs), secret);
|
|
73
74
|
const expectedBuf = Buffer.from(expected, "base64url");
|
|
74
75
|
const providedBuf = Buffer.from(providedSig, "base64url");
|
|
75
|
-
//
|
|
76
|
-
//
|
|
76
|
+
// Check the length before timingSafeEqual: it throws on a length mismatch,
|
|
77
|
+
// and the throw itself leaks information through timing.
|
|
77
78
|
if (expectedBuf.length !== providedBuf.length) return { ok: false, reason: "bad_signature" };
|
|
78
79
|
if (!timingSafeEqual(expectedBuf, providedBuf)) return { ok: false, reason: "bad_signature" };
|
|
79
80
|
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
// Inline
|
|
1
|
+
// Inline projections for the three event-sourced streams:
|
|
2
2
|
// mail-account → read_mail_accounts (UPSERT, current state)
|
|
3
3
|
// inbound-message → read_inbound_messages (INSERT-ignore, append-only)
|
|
4
|
-
// mail-thread → read_mail_threads (UPSERT,
|
|
4
|
+
// mail-thread → read_mail_threads (UPSERT, rollup)
|
|
5
5
|
//
|
|
6
|
-
// Apply
|
|
7
|
-
// own-write
|
|
6
|
+
// Apply runs in the same transaction as ctx.unsafeAppendEvent, providing
|
|
7
|
+
// read-your-own-write without waiting for a dispatcher tick (as in
|
|
8
|
+
// billing-foundation).
|
|
8
9
|
//
|
|
9
|
-
// **Production-deployment caveat** (
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
10
|
+
// **Production-deployment caveat** (same as billing-foundation):
|
|
11
|
+
// The tables are registered as raw drizzle-pgTable instances in r.projection,
|
|
12
|
+
// NOT as r.entity. Apps must include them in their drizzle/generate.ts
|
|
13
|
+
// (via *-ProjectionTable imports). setupTestStack pushes them automatically
|
|
14
|
+
// via r.projection.table.
|
|
14
15
|
//
|
|
15
|
-
// **PII:**
|
|
16
|
-
//
|
|
17
|
-
// write
|
|
18
|
-
// in
|
|
16
|
+
// **PII:** The payload fields (address/from/to/cc/subject/snippet) already
|
|
17
|
+
// arrive as ciphertext because they are encrypted BEFORE the append in the
|
|
18
|
+
// write handler. The applies only copy them through; decryption happens only
|
|
19
|
+
// in the list queries.
|
|
19
20
|
|
|
20
21
|
import {
|
|
21
22
|
buildEntityTable,
|
|
@@ -32,8 +33,8 @@ import type {
|
|
|
32
33
|
MailThreadEventPayload,
|
|
33
34
|
} from "./events.ts";
|
|
34
35
|
|
|
35
|
-
// Drizzle
|
|
36
|
-
// projection
|
|
36
|
+
// Drizzle table instances derived from the entity shapes, shared between
|
|
37
|
+
// projection applies and list queries to provide one column namespace.
|
|
37
38
|
export const mailAccountsProjectionTable = buildEntityTable("mail-account", mailAccountEntity);
|
|
38
39
|
export const inboundMessagesProjectionTable = buildEntityTable(
|
|
39
40
|
"inbound-message",
|
|
@@ -57,9 +58,10 @@ const mailThreadsProjectionMeta: EntityTableMeta = requireEntityTableMeta(
|
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
// =============================================================================
|
|
60
|
-
// mail-account — connected/updated/disconnected
|
|
61
|
-
//
|
|
62
|
-
// defensive consistency
|
|
61
|
+
// mail-account — connected/updated/disconnected share the payload shape;
|
|
62
|
+
// the event type identifies what happened. All three perform a full UPSERT
|
|
63
|
+
// for defensive consistency during from-scratch rebuilds and out-of-order
|
|
64
|
+
// processing.
|
|
63
65
|
// =============================================================================
|
|
64
66
|
|
|
65
67
|
const applyMailAccountUpsert = defineApply<MailAccountEventPayload>(async (event, tx) => {
|
|
@@ -91,16 +93,16 @@ const applyMailAccountUpsert = defineApply<MailAccountEventPayload>(async (event
|
|
|
91
93
|
|
|
92
94
|
/** mail-account-connected → UPSERT full. */
|
|
93
95
|
export const applyMailAccountConnected = applyMailAccountUpsert;
|
|
94
|
-
/** mail-account-updated → UPSERT
|
|
96
|
+
/** mail-account-updated → full UPSERT for status/watchState transitions. */
|
|
95
97
|
export const applyMailAccountUpdated = applyMailAccountUpsert;
|
|
96
|
-
/** mail-account-disconnected → UPSERT
|
|
97
|
-
*
|
|
98
|
+
/** mail-account-disconnected → full UPSERT (payload.status=disconnected).
|
|
99
|
+
* The row and stream remain for audit visibility in the account list. */
|
|
98
100
|
export const applyMailAccountDisconnected = applyMailAccountUpsert;
|
|
99
101
|
|
|
100
102
|
// =============================================================================
|
|
101
|
-
// inbound-message —
|
|
102
|
-
// aggregateId). INSERT-ignore
|
|
103
|
-
//
|
|
103
|
+
// inbound-message — exactly one received event per stream (deterministic
|
|
104
|
+
// aggregateId). INSERT-ignore makes replays no-ops on the primary key;
|
|
105
|
+
// there is no update case.
|
|
104
106
|
// =============================================================================
|
|
105
107
|
|
|
106
108
|
/** inbound-message-received → INSERT ... ON CONFLICT DO NOTHING. */
|
|
@@ -127,13 +129,13 @@ export const applyInboundMessageReceived = defineApply<InboundMessageEventPayloa
|
|
|
127
129
|
);
|
|
128
130
|
|
|
129
131
|
// =============================================================================
|
|
130
|
-
// mail-thread —
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
132
|
+
// mail-thread — rollup per (tenantId, threadKey). The write handler computes
|
|
133
|
+
// messageCount/lastMessageAt and appends the updated event with the NEW state.
|
|
134
|
+
// The apply performs a full UPSERT rather than incrementing, because
|
|
135
|
+
// replays would otherwise not be idempotent.
|
|
134
136
|
// =============================================================================
|
|
135
137
|
|
|
136
|
-
/** mail-thread-updated → UPSERT
|
|
138
|
+
/** mail-thread-updated → full UPSERT with the payload snapshot. */
|
|
137
139
|
export const applyMailThreadUpdated = defineApply<MailThreadEventPayload>(async (event, tx) => {
|
|
138
140
|
const p = event.payload;
|
|
139
141
|
const mutable = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// Provider
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// per
|
|
5
|
-
//
|
|
1
|
+
// Provider factory — mirrors mail-foundation's createTransportForTenant, including
|
|
2
|
+
// the three error paths (missing registry, unregistered provider, invalid plugin
|
|
3
|
+
// shape). Unlike the outbound pattern, there is no per-tenant config selector:
|
|
4
|
+
// the provider is specified per MailAccount (`account.provider`), so a tenant can
|
|
5
|
+
// use multiple providers in parallel.
|
|
6
6
|
|
|
7
7
|
import { INBOUND_MAIL_FOUNDATION_FEATURE, INBOUND_MAIL_PROVIDER_EXTENSION } from "./constants.ts";
|
|
8
8
|
import {
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
type MailAccountRecord,
|
|
13
13
|
} from "./types.ts";
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
15
|
+
/** Looks up a provider by key ("imap", "m365-graph", ...); used by OAuth
|
|
16
|
+
* connect routes before an account exists. */
|
|
17
17
|
export function resolveInboundProviderForKey(
|
|
18
18
|
ctx: InboundMailContext,
|
|
19
19
|
providerKey: string,
|
|
@@ -42,8 +42,8 @@ export function resolveInboundProviderForKey(
|
|
|
42
42
|
return usage.options;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
*
|
|
45
|
+
/** Looks up the provider for a specific account; the standard path for poll jobs
|
|
46
|
+
* and the watch supervisor. */
|
|
47
47
|
export function resolveInboundProviderForAccount(
|
|
48
48
|
ctx: InboundMailContext,
|
|
49
49
|
account: MailAccountRecord,
|