@cosmicdrift/kumiko-samples 0.389.0 → 0.390.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/bundled-features/package.json +27 -15
- package/packages/bundled-features/src/audit/feature.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +13 -1
- package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
- package/packages/bundled-features/src/auth-email-password/feature.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +7 -7
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.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 +9 -7
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +11 -7
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +9 -7
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +23 -16
- package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +3 -2
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +12 -8
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +4 -2
- package/packages/bundled-features/src/auth-email-password/handlers/token-request-handler.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +3 -2
- package/packages/bundled-features/src/auth-email-password/seeding.ts +14 -9
- package/packages/bundled-features/src/auth-foundation/feature.ts +13 -4
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +24 -14
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +9 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +6 -1
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start.write.ts +3 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +14 -9
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -4
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +25 -14
- package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +10 -4
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +9 -3
- package/packages/bundled-features/src/auth-mfa/verify-factor.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/changes.json +6 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +10 -7
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +15 -12
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-open-cancels.ts +22 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-provider-lock.ts +4 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +17 -58
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +10 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +18 -15
- package/packages/bundled-features/src/billing-foundation/events.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/feature.ts +8 -3
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/handlers/process-payment-event.write.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/projection.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/types.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/cap-counter/book-cap-usage.ts +5 -4
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +1 -1
- package/packages/bundled-features/src/cap-counter/constants.ts +1 -1
- package/packages/bundled-features/src/cap-counter/feature.ts +2 -2
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +1 -1
- package/packages/bundled-features/src/cap-counter/reservation-chain.ts +1 -1
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +4 -4
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -1
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +12 -7
- package/packages/bundled-features/src/config/feature.ts +6 -6
- package/packages/bundled-features/src/config/handlers/cascade.query.ts +1 -1
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +1 -1
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +23 -13
- package/packages/bundled-features/src/config/handlers/reset.write.ts +3 -3
- package/packages/bundled-features/src/config/handlers/selected-extensions.query.ts +1 -1
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/handlers/values.query.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +8 -8
- package/packages/bundled-features/src/crypto-shredding/resolve-file-bytes-deleter.ts +3 -3
- package/packages/bundled-features/src/custom-fields/changes.json +6 -0
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +1 -1
- package/packages/bundled-features/src/custom-fields/index.ts +4 -0
- package/packages/bundled-features/src/data-retention/feature.ts +1 -1
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +12 -2
- package/packages/bundled-features/src/delivery/attempt-log.ts +1 -1
- package/packages/bundled-features/src/delivery/delivery-service.ts +6 -5
- package/packages/bundled-features/src/delivery/feature.ts +2 -2
- package/packages/bundled-features/src/delivery/jobs.ts +11 -11
- package/packages/bundled-features/src/delivery/testing.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +5 -1
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +7 -5
- package/packages/bundled-features/src/file-foundation/feature.ts +1 -1
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -5
- package/packages/bundled-features/src/file-provider-s3/feature.ts +4 -1
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +8 -8
- package/packages/bundled-features/src/form-draft/feature.ts +1 -1
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +22 -12
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +3 -3
- package/packages/bundled-features/src/form-draft/handlers/get.query.ts +1 -1
- package/packages/bundled-features/src/foundation-shared/config-helpers.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +1 -1
- package/packages/bundled-features/src/inbound-provider-imap/changes.json +6 -0
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +4 -1
- package/packages/bundled-features/src/jobs/changes.json +6 -0
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/consumer.write.ts +7 -4
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +11 -5
- package/packages/bundled-features/src/jobs/handlers/retention-cleanup.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/stale-run-sweep.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +2 -2
- package/packages/bundled-features/src/jobs/job-run-logger.ts +139 -90
- package/packages/bundled-features/src/legal-pages/README.md +1 -1
- package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +12 -8
- package/packages/bundled-features/src/mail-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/mail-transport-smtp/changes.json +6 -0
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +4 -1
- package/packages/bundled-features/src/managed-pages/seeding.ts +13 -8
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/rate-limiting/handlers/status.query.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +4 -1
- package/packages/bundled-features/src/renderer-foundation/api.ts +3 -3
- package/packages/bundled-features/src/secrets/announce-secret-change.ts +4 -4
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/handlers/delete.write.ts +4 -3
- package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +13 -8
- package/packages/bundled-features/src/secrets/handlers/set.write.ts +4 -3
- package/packages/bundled-features/src/secrets/secrets-context.ts +16 -6
- package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
- package/packages/bundled-features/src/seo/feature.ts +1 -1
- package/packages/bundled-features/src/sessions/changes.json +12 -0
- package/packages/bundled-features/src/sessions/feature.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/cleanup.job.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/detail.query.ts +5 -2
- package/packages/bundled-features/src/sessions/handlers/list.query.ts +5 -2
- package/packages/bundled-features/src/sessions/handlers/mine.query.ts +5 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +3 -3
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/screens.ts +8 -4
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +1 -1
- package/packages/bundled-features/src/sessions/web/session-device-cell.tsx +10 -12
- package/packages/bundled-features/src/sessions/web/user-agent.ts +12 -0
- package/packages/bundled-features/src/shared/index.ts +15 -0
- package/packages/bundled-features/src/shared/purge-files-reaching-subject.ts +12 -2
- package/packages/bundled-features/src/shared/require-for-tenant.ts +7 -5
- package/packages/bundled-features/src/shared/stream-tenant-backfill.ts +201 -0
- package/packages/bundled-features/src/shared/stream-tenant-derived-state.ts +107 -0
- package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -1
- package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +1 -1
- package/packages/bundled-features/src/subscription-dodo/runtime.ts +7 -7
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +5 -3
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +7 -7
- package/packages/bundled-features/src/template-resolver/api.ts +3 -3
- package/packages/bundled-features/src/template-resolver/changes.json +18 -0
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +5 -4
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/send-test-shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +6 -2
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +4 -2
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/seeding.ts +12 -2
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +18 -13
- package/packages/bundled-features/src/template-resolver/template-resources.ts +4 -4
- package/packages/bundled-features/src/template-resolver/testing.ts +2 -2
- package/packages/bundled-features/src/template-resolver/web/document-insert-fields.tsx +222 -0
- package/packages/bundled-features/src/template-resolver/web/document-insert-model.ts +164 -0
- package/packages/bundled-features/src/template-resolver/web/document-insert-panel.tsx +115 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-bubble.tsx +177 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-content.tsx +38 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-context.ts +119 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +51 -1098
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-helpers.ts +161 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-layout.tsx +83 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-toolbar-groups.tsx +153 -0
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-toolbar.tsx +182 -0
- package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +18 -0
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +19 -6
- package/packages/bundled-features/src/template-resolver/web/use-document-tiptap-model.ts +138 -0
- package/packages/bundled-features/src/tenant/changes.json +19 -0
- package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +2 -2
- package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +1 -1
- package/packages/bundled-features/src/tenant/index.ts +5 -0
- package/packages/bundled-features/src/tenant/invited-membership.ts +6 -1
- package/packages/bundled-features/src/tenant/schema/tenant.ts +4 -1
- package/packages/bundled-features/src/tenant/seeding.ts +65 -62
- package/packages/bundled-features/src/tenant/stream-tenant-backfill.ts +115 -0
- package/packages/bundled-features/src/tenant/testing.ts +77 -0
- package/packages/bundled-features/src/tenant-handover/events.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +5 -5
- package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +22 -10
- package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +22 -11
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +23 -12
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +7 -3
- package/packages/bundled-features/src/tenant-lifecycle/testing.ts +9 -8
- package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
- package/packages/bundled-features/src/tier-engine/feature.ts +8 -3
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +3 -3
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +7 -1
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +3 -3
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +71 -97
- package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +2 -2
- package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -2
- package/packages/bundled-features/src/user/index.ts +2 -0
- package/packages/bundled-features/src/user/invited-global-roles.ts +6 -1
- package/packages/bundled-features/src/user/principal-status.ts +1 -1
- package/packages/bundled-features/src/user/seeding.ts +24 -6
- package/packages/bundled-features/src/user/testing.ts +22 -0
- package/packages/bundled-features/src/user-data-rights/COMPLIANCE.md +1 -1
- package/packages/bundled-features/src/user-data-rights/README.md +1 -1
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +12 -2
- package/packages/bundled-features/src/user-data-rights/changes.json +24 -0
- package/packages/bundled-features/src/user-data-rights/feature.ts +29 -24
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/deletion-grace-period.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +12 -6
- package/packages/bundled-features/src/user-data-rights/index.ts +2 -0
- package/packages/bundled-features/src/user-data-rights/lib/mail-transport-resolver.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/storage-provider-resolver.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +6 -1
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +8 -2
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +14 -3
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +11 -1
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +10 -0
- package/packages/bundled-features/src/user-data-rights/web/index.ts +6 -1
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +8 -6
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +2 -2
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +9 -4
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +6 -1
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +7 -1
- package/packages/bundled-features/src/workflow-runner/changes.json +6 -0
- package/packages/bundled-features/src/workflow-runner/db/queries/due-runs.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -3
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +2 -1
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +8 -8
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -4
- package/samples/apps/cap-billing-demo/package.json +1 -1
- package/samples/apps/cap-billing-demo/src/feature.ts +19 -5
- package/samples/apps/config-demo/src/app/server.ts +1 -1
- package/samples/apps/styleguide/src/app/server.ts +2 -2
- package/samples/apps/ui-walkthrough/package.json +1 -1
- package/samples/apps/use-all-bundled/feature-manifest.json +1 -1
- package/samples/apps/use-all-bundled/package.json +1 -1
- package/samples/apps/use-all-bundled/src/app/seed.ts +12 -2
- package/samples/apps/user-data-rights-demo/README.md +1 -1
- package/samples/apps/user-data-rights-demo/package.json +1 -1
- package/samples/apps/user-data-rights-demo/src/feature.ts +3 -2
- package/samples/recipes/api-worker-split/README.md +2 -1
- package/samples/recipes/api-worker-split/src/feature.ts +2 -1
- package/samples/recipes/cross-feature-events/README.md +5 -5
- package/samples/recipes/cross-feature-events/package.json +1 -1
- package/samples/recipes/cross-feature-events/src/feature.ts +4 -4
- package/samples/recipes/event-sourcing/README.md +5 -5
- package/samples/recipes/event-sourcing/package.json +1 -1
- package/samples/recipes/event-sourcing/src/feature.ts +15 -15
- package/samples/recipes/files-post-processing/README.md +1 -1
- package/samples/recipes/files-post-processing/package.json +1 -1
- package/samples/recipes/files-post-processing/src/feature.ts +6 -4
- package/samples/recipes/lane-routing/package.json +1 -1
- package/samples/recipes/legal-pages/README.md +2 -2
- package/samples/recipes/lifecycle-hooks/README.md +2 -2
- package/samples/recipes/lifecycle-hooks/src/feature.ts +1 -1
- package/samples/recipes/managed-config/README.md +3 -3
- package/samples/recipes/search/README.md +1 -1
- package/samples/recipes/search/src/feature.ts +3 -3
- package/samples/recipes/secrets-demo/README.md +1 -1
- package/samples/recipes/secrets-demo/src/feature.ts +5 -2
- package/samples/recipes/state-machine/src/events.ts +1 -1
- package/samples/recipes/state-machine/src/reducer.ts +1 -1
- package/samples/recipes/workflow-engine/src/resume-loop.ts +4 -4
- package/samples/recipes/workflow-engine/src/workflow-runner.ts +2 -2
|
@@ -77,7 +77,12 @@ async function releaseRowFileRefs(
|
|
|
77
77
|
isCreateMode,
|
|
78
78
|
);
|
|
79
79
|
const systemUser = createSystemUser(row.tenantId);
|
|
80
|
-
const tenantDb = createTenantDb({
|
|
80
|
+
const tenantDb = createTenantDb({
|
|
81
|
+
db,
|
|
82
|
+
tenantId: row.tenantId,
|
|
83
|
+
mode: "system",
|
|
84
|
+
reason: "stale-draft cleanup job removes drafts of each tenant, outside any request scope",
|
|
85
|
+
});
|
|
81
86
|
for (const ref of ownedRefs) {
|
|
82
87
|
const forgetResult = await fileRefExecutor.forget({ id: ref.id }, systemUser, tenantDb);
|
|
83
88
|
if (!forgetResult.isSuccess) {
|
|
@@ -137,7 +142,12 @@ export async function deleteStaleDraftsBatch(
|
|
|
137
142
|
const byId = new Map(batch.map((row) => [row.id, row]));
|
|
138
143
|
for (const [tenantId, ids] of groupStaleDraftIdsByTenant(batch)) {
|
|
139
144
|
const systemUser = createSystemUser(tenantId);
|
|
140
|
-
const tenantDb = createTenantDb({
|
|
145
|
+
const tenantDb = createTenantDb({
|
|
146
|
+
db,
|
|
147
|
+
tenantId,
|
|
148
|
+
mode: "system",
|
|
149
|
+
reason: "stale-draft cleanup job removes drafts of each tenant, outside any request scope",
|
|
150
|
+
});
|
|
141
151
|
for (const id of ids) {
|
|
142
152
|
// skip: an unreadable blob hides its FileRefs; deleting now would orphan them, so the next run retries.
|
|
143
153
|
if (byId.get(id)?.draftUnreadable) {
|
|
@@ -171,8 +181,8 @@ export async function cleanupDraftsJob(
|
|
|
171
181
|
ctx: JobContext,
|
|
172
182
|
db: DbConnection,
|
|
173
183
|
): Promise<void> {
|
|
174
|
-
const resolved = ctx.configResolver
|
|
175
|
-
? await ctx.configResolver.get(
|
|
184
|
+
const resolved = ctx.services.configResolver
|
|
185
|
+
? await ctx.services.configResolver.get(
|
|
176
186
|
FORM_DRAFT_RETENTION_DAYS_CONFIG_KEY,
|
|
177
187
|
formDraftRetentionDaysConfig,
|
|
178
188
|
SYSTEM_TENANT_ID,
|
|
@@ -184,26 +194,26 @@ export async function cleanupDraftsJob(
|
|
|
184
194
|
// configResolver missing is the legitimate no-config case (r.optionalRequires,
|
|
185
195
|
// see feature.ts) — nothing to warn about there. A resolver that IS wired but
|
|
186
196
|
// returns something unusable means an admin set an invalid value.
|
|
187
|
-
if (ctx.configResolver && !isValidRetention) {
|
|
188
|
-
ctx.log?.warn?.(
|
|
197
|
+
if (ctx.services.configResolver && !isValidRetention) {
|
|
198
|
+
ctx.obs.log?.warn?.(
|
|
189
199
|
`[form-draft:cleanup] configResolver returned invalid retention-days value=${String(resolved)} — falling back to default=${FORM_DRAFT_DEFAULT_RETENTION_DAYS}`,
|
|
190
200
|
);
|
|
191
201
|
}
|
|
192
202
|
const retentionDays = isValidRetention ? resolved : FORM_DRAFT_DEFAULT_RETENTION_DAYS;
|
|
193
203
|
|
|
194
|
-
const fileProviderResolver = ctx._fileProviderResolver;
|
|
204
|
+
const fileProviderResolver = ctx.services._fileProviderResolver;
|
|
195
205
|
|
|
196
206
|
let deleted = 0;
|
|
197
207
|
const deferred = new Set<string>();
|
|
198
208
|
while (true) {
|
|
199
|
-
if (ctx.signal?.aborted) break;
|
|
209
|
+
if (ctx.lifecycle.signal?.aborted) break;
|
|
200
210
|
const batch = await selectStaleDraftsBatch(db, retentionDays, DEFAULT_BATCH_SIZE, [
|
|
201
211
|
...deferred,
|
|
202
212
|
]);
|
|
203
213
|
if (batch.length === 0) break;
|
|
204
214
|
|
|
205
215
|
// Rows span arbitrary tenants (this job sweeps the whole table under
|
|
206
|
-
// SYSTEM_TENANT_ID, not per-tenant) — ctx.files is resolved for a single
|
|
216
|
+
// SYSTEM_TENANT_ID, not per-tenant) — ctx.services.files is resolved for a single
|
|
207
217
|
// tenant per job run and would be wrong here, so each row resolves its
|
|
208
218
|
// own tenant's provider via _fileProviderResolver instead. Skipped
|
|
209
219
|
// entirely for rows with no FileRefs in the blob, the common case.
|
|
@@ -213,11 +223,11 @@ export async function cleanupDraftsJob(
|
|
|
213
223
|
batch,
|
|
214
224
|
db,
|
|
215
225
|
retentionDays,
|
|
216
|
-
ctx.log,
|
|
226
|
+
ctx.obs.log,
|
|
217
227
|
);
|
|
218
228
|
for (const id of deferredIds) deferred.add(id);
|
|
219
229
|
for (const row of deletedRows) {
|
|
220
|
-
await releaseRowFileRefs(row, db, fileProviderResolver, ctx.log);
|
|
230
|
+
await releaseRowFileRefs(row, db, fileProviderResolver, ctx.obs.log);
|
|
221
231
|
}
|
|
222
232
|
deleted += deletedRows.length;
|
|
223
233
|
// A skipped row is no longer stale, so the next select drops it — a fully
|
|
@@ -229,5 +239,5 @@ export async function cleanupDraftsJob(
|
|
|
229
239
|
)
|
|
230
240
|
break;
|
|
231
241
|
}
|
|
232
|
-
ctx.log?.info?.(`[form-draft:cleanup] deleted=${deleted} retentionDays=${retentionDays}`);
|
|
242
|
+
ctx.obs.log?.info?.(`[form-draft:cleanup] deleted=${deleted} retentionDays=${retentionDays}`);
|
|
233
243
|
}
|
|
@@ -56,7 +56,7 @@ export const discardDraftWrite = defineWriteHandler({
|
|
|
56
56
|
// releaseFiles: a successful-submit discard must NOT release — the
|
|
57
57
|
// domain entity the submit just wrote carries the same storageKeys
|
|
58
58
|
// forward (see schemas.ts comment on discardDraftPayloadSchema).
|
|
59
|
-
const files = ctx.files;
|
|
59
|
+
const files = ctx.services.files;
|
|
60
60
|
if (files && event.payload.releaseFiles === true) {
|
|
61
61
|
const candidateKeys = collectDraftFileRefKeys(existing.draft);
|
|
62
62
|
// Only storageKeys with a real file_refs row owned by THIS caller are
|
|
@@ -87,8 +87,8 @@ export const discardDraftWrite = defineWriteHandler({
|
|
|
87
87
|
// Binary delete only after commit — in-tx delete would orphan pointers
|
|
88
88
|
// if the surrounding write transaction rolls back after this handler.
|
|
89
89
|
const keys = ownedRefs.map((ref) => ref.storageKey);
|
|
90
|
-
const log = ctx.log;
|
|
91
|
-
const schedule = ctx.
|
|
90
|
+
const log = ctx.obs.log;
|
|
91
|
+
const schedule = ctx.lifecycle.afterCommit;
|
|
92
92
|
const release = async (): Promise<void> => {
|
|
93
93
|
await releaseDraftFileRefs(
|
|
94
94
|
keys,
|
|
@@ -27,7 +27,7 @@ export const getDraftQuery = defineQueryHandler({
|
|
|
27
27
|
if (!row.draft) {
|
|
28
28
|
// Schema evolution or a corrupt/erased row: surface it to operators
|
|
29
29
|
// instead of silently making the user's draft vanish.
|
|
30
|
-
ctx.log?.warn?.(
|
|
30
|
+
ctx.obs.log?.warn?.(
|
|
31
31
|
`[form-draft:get] stored blob for draftKey=${query.payload.draftKey} failed schema or decryption, treating as absent`,
|
|
32
32
|
);
|
|
33
33
|
return { draft: null };
|
|
@@ -77,7 +77,7 @@ export function requireNonEmpty(
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
|
-
* Narrow a `ctx.secrets.get()` result → set secret. The secrets-counterpart
|
|
80
|
+
* Narrow a `ctx.services.secrets.get()` result → set secret. The secrets-counterpart
|
|
81
81
|
* to requireNonEmpty: a missing secret is a tenant-configuration gap, not a
|
|
82
82
|
* crash — same 422 contract, so clients route to the settings screen.
|
|
83
83
|
*
|
|
@@ -29,7 +29,7 @@ export const INBOUND_MESSAGE_AGGREGATE_TYPE = "inbound-message" as const;
|
|
|
29
29
|
export const MAIL_THREAD_AGGREGATE_TYPE = "mail-thread" as const;
|
|
30
30
|
|
|
31
31
|
// Event-name constants — short forms (for r.defineEvent) and qualified
|
|
32
|
-
// FQNs (for ctx.
|
|
32
|
+
// FQNs (for ctx.events.unsafeAppend and projection-apply keys).
|
|
33
33
|
export const MAIL_ACCOUNT_CONNECTED_EVENT_SHORT = "mail-account-connected" as const;
|
|
34
34
|
export const MAIL_ACCOUNT_UPDATED_EVENT_SHORT = "mail-account-updated" as const;
|
|
35
35
|
export const MAIL_ACCOUNT_DISCONNECTED_EVENT_SHORT = "mail-account-disconnected" as const;
|
|
@@ -254,7 +254,7 @@ export function createInboundMailFoundationFeature() {
|
|
|
254
254
|
const deleteBodyObject = async (bodyRef: string): Promise<void> => {
|
|
255
255
|
if (!providerPromise) {
|
|
256
256
|
providerPromise = createFileProviderForTenant(
|
|
257
|
-
{ config: ctx.config, registry: ctx.registry },
|
|
257
|
+
{ config: ctx.config, registry: ctx.registry, secrets: ctx.services.secrets },
|
|
258
258
|
tenantId,
|
|
259
259
|
);
|
|
260
260
|
}
|
|
@@ -13,10 +13,10 @@ import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
13
13
|
import type { MailAccountEventPayload } from "../events.ts";
|
|
14
14
|
|
|
15
15
|
export async function loadCurrentMailAccountPayload(
|
|
16
|
-
ctx: Pick<HandlerContext, "
|
|
16
|
+
ctx: { readonly events: Pick<HandlerContext["events"], "load"> },
|
|
17
17
|
accountId: string,
|
|
18
18
|
): Promise<MailAccountEventPayload | undefined> {
|
|
19
|
-
const events = await ctx.
|
|
19
|
+
const events = await ctx.events.load(accountId);
|
|
20
20
|
const last = events[events.length - 1];
|
|
21
21
|
// @cast-boundary engine-payload — eigene events, shape via defineEvent
|
|
22
22
|
return last?.payload as MailAccountEventPayload | undefined;
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts
CHANGED
|
@@ -104,7 +104,7 @@ export const connectAccountHandler: WriteHandlerDef = {
|
|
|
104
104
|
providerName: payload.provider,
|
|
105
105
|
reason: "connect_flow",
|
|
106
106
|
};
|
|
107
|
-
await ctx.
|
|
107
|
+
await ctx.events.unsafeAppend({
|
|
108
108
|
aggregateId: accountId,
|
|
109
109
|
aggregateType: MAIL_ACCOUNT_AGGREGATE_TYPE,
|
|
110
110
|
type: MAIL_ACCOUNT_CONNECTED_EVENT_QN,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts
CHANGED
|
@@ -56,7 +56,7 @@ export const disconnectAccountHandler: WriteHandlerDef = {
|
|
|
56
56
|
providerName: current.provider,
|
|
57
57
|
reason: payload.reason,
|
|
58
58
|
};
|
|
59
|
-
await ctx.
|
|
59
|
+
await ctx.events.unsafeAppend({
|
|
60
60
|
aggregateId: payload.accountId,
|
|
61
61
|
aggregateType: MAIL_ACCOUNT_AGGREGATE_TYPE,
|
|
62
62
|
type: MAIL_ACCOUNT_DISCONNECTED_EVENT_QN,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// both the event log AND projection contain ciphertext.
|
|
11
11
|
// 4. inbound-message-received append (inline projection writes
|
|
12
12
|
// read_inbound_messages in the same TX). Savepoint-scoped
|
|
13
|
-
// (ctx.
|
|
13
|
+
// (ctx.events.tryAppend) — a losing concurrent ingest for the same
|
|
14
14
|
// messageAggId returns { duplicate: true } instead of failing the TX.
|
|
15
15
|
// 5. Thread rollup: mail-thread-updated append with a recalculated
|
|
16
16
|
// snapshot (count+1, max(lastMessageAt)) — the apply is a
|
|
@@ -140,7 +140,7 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
140
140
|
data: { duplicate: true as const, inboundMessageAggregateId: messageAggId },
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
|
-
const existingEvents = await ctx.
|
|
143
|
+
const existingEvents = await ctx.events.load(messageAggId);
|
|
144
144
|
if (existingEvents.length > 0) {
|
|
145
145
|
// Stream existiert, Anchor fehlte → Anchor nachziehen, dann raus.
|
|
146
146
|
await ctx.db.insertOne(seenMessageTable, {
|
|
@@ -211,7 +211,7 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
211
211
|
providerName: payload.providerName,
|
|
212
212
|
providerCursor: payload.providerCursor,
|
|
213
213
|
};
|
|
214
|
-
const messageAppend = await ctx.
|
|
214
|
+
const messageAppend = await ctx.events.tryAppend({
|
|
215
215
|
aggregateId: messageAggId,
|
|
216
216
|
aggregateType: INBOUND_MESSAGE_AGGREGATE_TYPE,
|
|
217
217
|
type: INBOUND_MESSAGE_RECEIVED_EVENT_QN,
|
|
@@ -222,8 +222,8 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
222
222
|
// Lost the race against a concurrent ingest for the same messageAggId
|
|
223
223
|
// (Watch-Push vs. Poll-Reconciliation overlap). The winner already
|
|
224
224
|
// writes thread-rollup + seen-anchor for this message — steps 5+6
|
|
225
|
-
// skip here.
|
|
226
|
-
// the caught VersionConflictError (see ctx.
|
|
225
|
+
// skip here. events.tryAppend's savepoint keeps this TX usable despite
|
|
226
|
+
// the caught VersionConflictError (see ctx.events.tryAppend doc).
|
|
227
227
|
return {
|
|
228
228
|
isSuccess: true as const,
|
|
229
229
|
data: { duplicate: true as const, inboundMessageAggregateId: messageAggId },
|
|
@@ -232,7 +232,7 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
232
232
|
|
|
233
233
|
// ---------------------------------------------------------------
|
|
234
234
|
// 5. Thread-Rollup. New snapshot (live COUNT + max(lastMessageAt)) via
|
|
235
|
-
// ctx.
|
|
235
|
+
// ctx.events.tryAppend in a bounded retry loop — the apply stays a
|
|
236
236
|
// dumb, replay-idempotent UPSERT. lastMessageAtIso is not PII (a
|
|
237
237
|
// timestamp), so it stays plaintext-comparable; subject is
|
|
238
238
|
// encrypted once up front (constant across retries, doesn't
|
|
@@ -244,9 +244,9 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
244
244
|
// same thread arriving at once) converge on the true count.
|
|
245
245
|
// acquireNamespacedAdvisoryLock below serializes this whole
|
|
246
246
|
// countWhere+append section per threadAggId — transaction-scoped,
|
|
247
|
-
// so it survives
|
|
247
|
+
// so it survives events.tryAppend's inner SAVEPOINT and releases at
|
|
248
248
|
// the enclosing TX's commit/rollback. Without it, a concurrent
|
|
249
|
-
// commit landing between countWhere and
|
|
249
|
+
// commit landing between countWhere and events.tryAppend's own fresh
|
|
250
250
|
// version-read makes the append succeed with a stale count instead
|
|
251
251
|
// of a VersionConflictError, so the retry loop below never sees it
|
|
252
252
|
// as a conflict to retry (the original gap). Unlike step 4, a
|
|
@@ -280,7 +280,7 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
280
280
|
|
|
281
281
|
let threadAppendOk = false;
|
|
282
282
|
for (let attempt = 1; attempt <= THREAD_ROLLUP_MAX_ATTEMPTS && !threadAppendOk; attempt++) {
|
|
283
|
-
const threadEvents = await ctx.
|
|
283
|
+
const threadEvents = await ctx.events.load(threadAggId);
|
|
284
284
|
const lastThreadEvent = threadEvents[threadEvents.length - 1];
|
|
285
285
|
// @cast-boundary engine-payload — eigene events, shape via defineEvent
|
|
286
286
|
const previousThread = lastThreadEvent?.payload as MailThreadEventPayload | undefined;
|
|
@@ -298,7 +298,7 @@ export const ingestMessageHandler: WriteHandlerDef = {
|
|
|
298
298
|
lastMessageAtIso: newLastAt,
|
|
299
299
|
messageCount,
|
|
300
300
|
};
|
|
301
|
-
const threadAppend = await ctx.
|
|
301
|
+
const threadAppend = await ctx.events.tryAppend({
|
|
302
302
|
aggregateId: threadAggId,
|
|
303
303
|
aggregateType: MAIL_THREAD_AGGREGATE_TYPE,
|
|
304
304
|
type: MAIL_THREAD_UPDATED_EVENT_QN,
|
package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts
CHANGED
|
@@ -79,7 +79,7 @@ export const updateAccountHandler: WriteHandlerDef = {
|
|
|
79
79
|
providerName: current.provider,
|
|
80
80
|
reason: auditReasonFor(event.user, payload.reason),
|
|
81
81
|
};
|
|
82
|
-
await ctx.
|
|
82
|
+
await ctx.events.unsafeAppend({
|
|
83
83
|
aggregateId: payload.accountId,
|
|
84
84
|
aggregateType: MAIL_ACCOUNT_AGGREGATE_TYPE,
|
|
85
85
|
type: MAIL_ACCOUNT_UPDATED_EVENT_QN,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// inbound-message → read_inbound_messages (INSERT-ignore, append-only)
|
|
4
4
|
// mail-thread → read_mail_threads (UPSERT, rollup)
|
|
5
5
|
//
|
|
6
|
-
// Apply runs in the same transaction as ctx.
|
|
6
|
+
// Apply runs in the same transaction as ctx.events.unsafeAppend, providing
|
|
7
7
|
// read-your-own-write without waiting for a dispatcher tick (as in
|
|
8
8
|
// billing-foundation).
|
|
9
9
|
//
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
// **Documented deviation:** the poll was originally intended as an `r.job`
|
|
9
9
|
// cron trigger. JobContext previously had no dispatcher (see
|
|
10
|
-
// run-export-jobs.ts), but now has one (`ctx.write`/`ctx.queryAs`,
|
|
10
|
+
// run-export-jobs.ts), but now has one (`ctx.dispatch.write`/`ctx.dispatch.queryAs`,
|
|
11
11
|
// job-runner.ts). Converting the poll to a cron job is a separate migration
|
|
12
12
|
// because it changes the concurrency model, so this dispatcher contract
|
|
13
13
|
// remains in place. The app owner wires the supervisor in bin/server.ts:
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.390.1",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "mailparser moved to a version without known nodemailer advisories",
|
|
6
|
+
"detail": "mailparser moves to ^3.12.4, which pins nodemailer 10.2.1, so apps no longer get nodemailer 10.0.13 through it."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.370.0",
|
|
4
10
|
"type": "breaking",
|
|
@@ -64,7 +64,10 @@ async function readCredentialDocument(
|
|
|
64
64
|
ctx: InboundMailContext,
|
|
65
65
|
account: MailAccountRecord,
|
|
66
66
|
): Promise<ImapCredentialDocument> {
|
|
67
|
-
const secrets = requireSecretsContext(
|
|
67
|
+
const secrets = requireSecretsContext(
|
|
68
|
+
{ secrets: ctx.secrets, auditUserId: ctx.auditUserId },
|
|
69
|
+
FEATURE_NAME,
|
|
70
|
+
);
|
|
68
71
|
const secret = await secrets.get(account.tenantId, inboundCredentialSecretKey(account.id));
|
|
69
72
|
if (!secret) {
|
|
70
73
|
throw new InboundAuthError(
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.390.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Tenant job run rows are written in the tenant's scope",
|
|
6
|
+
"detail": "With row level security on, the queued, started and finished rows of tenant-visible job runs were rejected by Postgres when the job was dispatched outside a request scope, and the logger only logged the error. The logger now scopes its tenant writes to the job's tenant and logs a rejected write as a missing row-level-security scope instead of a generic write failure."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.388.0",
|
|
4
10
|
"type": "improvement",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// backed jobRun's event-store payloads (r.defineEvent + inline projections);
|
|
3
3
|
// now job-run-logger.ts parses against them before writing straight into
|
|
4
4
|
// jobRunsTable/jobRunLogsTable, so an out-of-dispatcher write still gets the
|
|
5
|
-
// same validation guarantee ctx.
|
|
5
|
+
// same validation guarantee ctx.events.append used to give it.
|
|
6
6
|
|
|
7
7
|
import * as z from "zod";
|
|
8
8
|
|
|
@@ -65,10 +65,13 @@ function defineConsumerWrite(name: string, description: string, transition: Cons
|
|
|
65
65
|
? rejected(JobErrors.consumerUnknown, "jobs.errors.consumerUnknown")
|
|
66
66
|
: rejected(JobErrors.consumerWrongStatus, "jobs.errors.consumerWrongStatus");
|
|
67
67
|
}
|
|
68
|
-
ctx.log?.error(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
ctx.obs.log?.error(
|
|
69
|
+
`jobs:write:${name} failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
70
|
+
{
|
|
71
|
+
consumer: event.payload.name,
|
|
72
|
+
instanceId: event.payload.instanceId,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
72
75
|
return rejected(JobErrors.consumerTransitionFailed, "jobs.errors.consumerTransitionFailed");
|
|
73
76
|
}
|
|
74
77
|
},
|
|
@@ -36,7 +36,7 @@ export const projectionRebuildJob: JobHandlerFn = async (rawPayload, ctx): Promi
|
|
|
36
36
|
registry: ctx.registry,
|
|
37
37
|
...(skipApplyErrors === true && { errorPolicy: { skipApplyErrors: true } }),
|
|
38
38
|
});
|
|
39
|
-
ctx.log?.info?.(
|
|
39
|
+
ctx.obs.log?.info?.(
|
|
40
40
|
`[jobs:projection-rebuild] rebuilt ${projection}: ${result.eventsProcessed} events` +
|
|
41
41
|
`${result.eventsSkipped > 0 ? ` (${result.eventsSkipped} quarantined)` : ""} in ${result.durationMs}ms`,
|
|
42
42
|
);
|
|
@@ -20,16 +20,16 @@ export const reindexEntityJob: JobHandlerFn = async (rawPayload, ctx): Promise<v
|
|
|
20
20
|
message: "[jobs:reindex-entity] ctx.registry missing — job context requires the registry.",
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
if (!ctx.searchAdapter) {
|
|
23
|
+
if (!ctx.services.searchAdapter) {
|
|
24
24
|
throw new InternalError({
|
|
25
25
|
message:
|
|
26
|
-
"[jobs:reindex-entity] ctx.searchAdapter missing — mount a search adapter to run this job.",
|
|
26
|
+
"[jobs:reindex-entity] ctx.services.searchAdapter missing — mount a search adapter to run this job.",
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
// perTenant fan-out — the job-runner enqueues one child run per active
|
|
30
30
|
// tenant with ctx.systemUser scoped to it; a run without one (e.g.
|
|
31
31
|
// misconfigured manual dispatch outside the fan-out) has nothing scoped
|
|
32
|
-
// to reindex. ctx.
|
|
32
|
+
// to reindex. ctx.user.tenantId is never populated per-dispatch (only
|
|
33
33
|
// ctx.systemUser is), so it is not a valid fallback here.
|
|
34
34
|
const tenantId = ctx.systemUser?.tenantId;
|
|
35
35
|
if (tenantId === undefined) {
|
|
@@ -48,8 +48,14 @@ export const reindexEntityJob: JobHandlerFn = async (rawPayload, ctx): Promise<v
|
|
|
48
48
|
const db = ctx.systemDb.unsafeRaw(
|
|
49
49
|
"reindexEntity filters WHERE tenant_id = $1 itself with this job's tenantId",
|
|
50
50
|
);
|
|
51
|
-
const result = await reindexEntity(
|
|
52
|
-
|
|
51
|
+
const result = await reindexEntity(
|
|
52
|
+
db,
|
|
53
|
+
ctx.registry,
|
|
54
|
+
ctx.services.searchAdapter,
|
|
55
|
+
entity,
|
|
56
|
+
tenantId,
|
|
57
|
+
);
|
|
58
|
+
ctx.obs.log?.info?.(
|
|
53
59
|
`[jobs:reindex-entity] tenant=${tenantId} reindexed ${entity}: ${result.indexedRows}/${result.scannedRows} rows indexed` +
|
|
54
60
|
`${result.failures.length > 0 ? ` (${result.failures.length} failed)` : ""}`,
|
|
55
61
|
);
|
|
@@ -18,6 +18,6 @@ export function createRetentionCleanupJob(retentionDays: number): JobHandlerFn {
|
|
|
18
18
|
"store_job_runs retention purges finished runs of every tenant",
|
|
19
19
|
) as DbConnection; // @cast-boundary db-operator — DbRunner narrows to DbConnection, jobs never run inside a DbTx
|
|
20
20
|
const result = await deleteStaleJobRuns(db, retentionDays);
|
|
21
|
-
ctx.log?.info?.(`[jobs:retention-cleanup] complete: ${JSON.stringify(result)}`);
|
|
21
|
+
ctx.obs.log?.info?.(`[jobs:retention-cleanup] complete: ${JSON.stringify(result)}`);
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -37,7 +37,7 @@ export const retryWrite = defineWriteHandler({
|
|
|
37
37
|
}
|
|
38
38
|
const db = ctx.systemDb.acknowledgeCrossTenant("cross-tenant job monitoring");
|
|
39
39
|
// @cast-boundary engine-payload — JobRunner attached by app-boot via ctx-extension
|
|
40
|
-
const jobRunner = ctx
|
|
40
|
+
const jobRunner = ctx.services.jobRunner as JobRunner;
|
|
41
41
|
|
|
42
42
|
const run = await fetchOne<JobRunRow>(db, jobRunsTable, { id: event.payload.runId });
|
|
43
43
|
|
|
@@ -28,6 +28,6 @@ export function createStaleRunSweepJob(
|
|
|
28
28
|
"stale-run sweep marks stuck runs of every tenant as failed",
|
|
29
29
|
) as DbConnection; // @cast-boundary db-operator — DbRunner narrows to DbConnection, jobs never run inside a DbTx
|
|
30
30
|
const result = await markStaleJobRunsFailed(db, timeoutHours, queuedRetentionDays);
|
|
31
|
-
ctx.log?.info?.(`[jobs:stale-run-sweep] complete: ${JSON.stringify(result)}`);
|
|
31
|
+
ctx.obs.log?.info?.(`[jobs:stale-run-sweep] complete: ${JSON.stringify(result)}`);
|
|
32
32
|
};
|
|
33
33
|
}
|
|
@@ -28,8 +28,8 @@ export const triggerWrite = defineWriteHandler({
|
|
|
28
28
|
access: { roles: ["SystemAdmin"] },
|
|
29
29
|
handler: async (event, ctx) => {
|
|
30
30
|
const registry = ctx.registry;
|
|
31
|
-
// `jobRunner` is
|
|
32
|
-
const jobRunner = ctx
|
|
31
|
+
// `services.jobRunner` is typed as the handleEvent-only JobRunnerRef; dispatch lives on the concrete runner.
|
|
32
|
+
const jobRunner = ctx.services.jobRunner as JobRunner; // @cast-boundary engine-bridge
|
|
33
33
|
|
|
34
34
|
const jobDef = registry.getJob(event.payload.jobName);
|
|
35
35
|
if (!jobDef) {
|