@flowdular/sdk 0.2.4 → 0.3.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/.ai/agents/sandbox/business-manager.md +5 -1
- package/.ai/blueprints/author-spec/README.md +1 -1
- package/.ai/blueprints/author-spec/spec-requirements.yaml +44 -0
- package/.ai/blueprints/author-spec/steps.yaml +5 -5
- package/.ai/blueprints/author-spec/templates/module.yaml +99 -3
- package/.ai/blueprints/edit-module/gates.yaml +4 -0
- package/.ai/blueprints/edit-module/required-files.yaml +9 -0
- package/.ai/blueprints/new-module/gates.yaml +4 -0
- package/.ai/blueprints/new-module/spec-requirements.yaml +2 -2
- package/.ai/blueprints/release/gates.yaml +4 -0
- package/.ai/platform-capabilities.md +128 -0
- package/.ai/policies/capabilities.yaml +130 -3
- package/.ai/policies/path-ownership.yaml +5 -2
- package/.ai/policies/task-budgets.yaml +5 -3
- package/.ai/references/catalog/module.json +4 -4
- package/.ai/references/catalog/package.json +2 -2
- package/.ai/references/catalog/spec/module.yaml +5 -3
- package/.ai/references/catalog/src/platform.ts +2 -0
- package/.ai/references/catalog/src/services/catalog-service.ts +89 -1
- package/.ai/references/catalog/src/services/data-classes.ts +47 -0
- package/.ai/references/catalog/src/services/database-repository.ts +98 -1
- package/.ai/references/catalog/src/services/repository.ts +22 -1
- package/.ai/references/catalog/tests/data-classes.test.ts +157 -0
- package/.ai/references/catalog.provenance.json +12 -10
- package/.ai/skills/README.md +10 -0
- package/.ai/skills/agent-tool-design/SKILL.md +1 -2
- package/.ai/skills/auth-security-review/SKILL.md +1 -1
- package/.ai/skills/business-agent-design/SKILL.md +0 -1
- package/.ai/skills/cli-extension/SKILL.md +1 -1
- package/.ai/skills/deploy-operate/SKILL.md +119 -0
- package/.ai/skills/module-new/SKILL.md +29 -3
- package/.ai/skills/module-update/SKILL.md +9 -3
- package/.ai/skills/perf-audit/SKILL.md +0 -1
- package/.ai/skills/release-eject-pr/SKILL.md +0 -1
- package/.ai/skills/spec-interview/SKILL.md +120 -0
- package/.ai/skills/test-hardening/SKILL.md +1 -0
- package/.ai/skills/ux-design/SKILL.md +34 -3
- package/.ai/skills/variables/SKILL.md +0 -2
- package/.ai/skills/workflow-development/SKILL.md +0 -1
- package/AGENTS.md +4 -0
- package/docs/agent-contract.md +2 -2
- package/docs/design-system.md +185 -31
- package/modules/access/migrations/0001_access_core.down.sql +1 -0
- package/modules/access/migrations/0001_access_core.up.sql +28 -0
- package/modules/access/migrations/README.md +3 -0
- package/modules/access/module.json +33 -0
- package/modules/access/package.json +43 -0
- package/modules/access/spec/module.yaml +225 -0
- package/modules/access/src/acl/permissions.ts +6 -0
- package/modules/access/src/api/endpoints.ts +244 -0
- package/modules/access/src/client/ActivityView.tsrx +245 -0
- package/modules/access/src/client/AttestationsView.tsrx +176 -0
- package/modules/access/src/client/ReviewView.tsrx +586 -0
- package/modules/access/src/client/api.ts +132 -0
- package/modules/access/src/client/contribution.tsrx +41 -0
- package/modules/access/src/client/index.ts +41 -0
- package/modules/access/src/client/navigation.ts +57 -0
- package/modules/access/src/client/presentation.ts +69 -0
- package/modules/access/src/client/state.ts +72 -0
- package/modules/access/src/domain/types.ts +189 -0
- package/modules/access/src/index.ts +38 -0
- package/modules/access/src/platform.ts +60 -0
- package/modules/access/src/server/index.ts +42 -0
- package/modules/access/src/server/runtime.ts +105 -0
- package/modules/access/src/services/access-service.ts +298 -0
- package/modules/access/src/services/audit-window.ts +78 -0
- package/modules/access/src/services/auth-directory.ts +72 -0
- package/modules/access/src/services/changes.ts +91 -0
- package/modules/access/src/services/data-classes.ts +28 -0
- package/modules/access/src/services/database-repository.ts +185 -0
- package/modules/access/src/services/directory.ts +102 -0
- package/modules/access/src/services/index.ts +33 -0
- package/modules/access/src/services/list-exports.ts +150 -0
- package/modules/access/src/services/migration.ts +54 -0
- package/modules/access/src/services/repository.ts +30 -0
- package/modules/access/src/services/review.ts +178 -0
- package/modules/access/translations/en.json +155 -0
- package/modules/access/translations/pl.json +155 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.down.sql +2 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.up.sql +7 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.down.sql +2 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.up.sql +9 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.down.sql +3 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.up.sql +22 -0
- package/modules/agents/migrations/0025_agent_list_indexes.down.sql +3 -0
- package/modules/agents/migrations/0025_agent_list_indexes.up.sql +11 -0
- package/modules/agents/module.json +30 -4
- package/modules/agents/package.json +2 -1
- package/modules/agents/spec/module.yaml +63 -5
- package/modules/agents/src/api/endpoints.ts +291 -33
- package/modules/agents/src/cli/commands.json +11 -0
- package/modules/agents/src/cli/index.ts +45 -0
- package/modules/agents/src/client/AgentDashboardWidget.tsrx +19 -11
- package/modules/agents/src/client/AgentDefinitionList.tsrx +53 -10
- package/modules/agents/src/client/AgentPlaygroundView.tsrx +4 -4
- package/modules/agents/src/client/AgentProceduresView.tsrx +2 -2
- package/modules/agents/src/client/AgentRunsView.tsrx +143 -40
- package/modules/agents/src/client/AgentsView.tsrx +109 -33
- package/modules/agents/src/client/api.ts +99 -21
- package/modules/agents/src/client/state.ts +97 -0
- package/modules/agents/src/domain/types.ts +44 -4
- package/modules/agents/src/platform.ts +42 -0
- package/modules/agents/src/server/action-execution.ts +201 -106
- package/modules/agents/src/server/runtime.ts +32 -0
- package/modules/agents/src/services/agent-service.ts +158 -30
- package/modules/agents/src/services/credential-rotation.ts +185 -0
- package/modules/agents/src/services/credential-vault.ts +71 -46
- package/modules/agents/src/services/data-classes.ts +176 -0
- package/modules/agents/src/services/database-repository.ts +393 -101
- package/modules/agents/src/services/metering.ts +111 -0
- package/modules/agents/src/services/migration.ts +109 -0
- package/modules/agents/src/services/module-agent-preflight.ts +17 -9
- package/modules/agents/src/services/notifications.ts +98 -0
- package/modules/agents/src/services/provider-repository.ts +9 -18
- package/modules/agents/src/services/provider-service.ts +1 -9
- package/modules/agents/src/services/reports.ts +107 -0
- package/modules/agents/src/services/repository.ts +86 -6
- package/modules/agents/src/services/usage-service.ts +2 -0
- package/modules/agents/src/services/worker.ts +114 -4
- package/modules/agents/src/settings.ts +14 -3
- package/modules/agents/translations/en.json +14 -4
- package/modules/agents/translations/pl.json +14 -4
- package/modules/approvals/migrations/0001_approvals_core.down.sql +3 -0
- package/modules/approvals/migrations/0001_approvals_core.up.sql +78 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.down.sql +2 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.up.sql +19 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.down.sql +6 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.up.sql +14 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.down.sql +5 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.up.sql +12 -0
- package/modules/approvals/migrations/0005_approvals_grant_audit.down.sql +4 -0
- package/modules/approvals/migrations/0005_approvals_grant_audit.up.sql +20 -0
- package/modules/approvals/migrations/README.md +3 -0
- package/modules/approvals/module.json +34 -0
- package/modules/approvals/package.json +43 -0
- package/modules/approvals/spec/module.yaml +327 -0
- package/modules/approvals/src/acl/permissions.ts +7 -0
- package/modules/approvals/src/api/endpoints.ts +457 -0
- package/modules/approvals/src/client/ApprovalRequestDrawer.tsrx +138 -0
- package/modules/approvals/src/client/ApprovalsView.tsrx +562 -0
- package/modules/approvals/src/client/PendingCountWidget.tsrx +52 -0
- package/modules/approvals/src/client/api.ts +203 -0
- package/modules/approvals/src/client/approvals.css +51 -0
- package/modules/approvals/src/client/contribution.tsrx +44 -0
- package/modules/approvals/src/client/index.ts +26 -0
- package/modules/approvals/src/client/navigation.ts +39 -0
- package/modules/approvals/src/client/pending-count.ts +26 -0
- package/modules/approvals/src/client/presentation.ts +52 -0
- package/modules/approvals/src/client/state.ts +141 -0
- package/modules/approvals/src/domain/capability.ts +107 -0
- package/modules/approvals/src/domain/grant.ts +69 -0
- package/modules/approvals/src/domain/types.ts +168 -0
- package/modules/approvals/src/index.ts +61 -0
- package/modules/approvals/src/platform.ts +136 -0
- package/modules/approvals/src/server/index.ts +42 -0
- package/modules/approvals/src/server/runtime.ts +185 -0
- package/modules/approvals/src/services/approvals-service.ts +637 -0
- package/modules/approvals/src/services/callbacks.ts +75 -0
- package/modules/approvals/src/services/data-classes.ts +167 -0
- package/modules/approvals/src/services/database-repository.ts +783 -0
- package/modules/approvals/src/services/eligibility.ts +121 -0
- package/modules/approvals/src/services/expiry-runner.ts +81 -0
- package/modules/approvals/src/services/index.ts +31 -0
- package/modules/approvals/src/services/migration.ts +256 -0
- package/modules/approvals/src/services/notifications.ts +95 -0
- package/modules/approvals/src/services/repository.ts +169 -0
- package/modules/approvals/src/services/service-error.ts +70 -0
- package/modules/approvals/src/settings.ts +102 -0
- package/modules/approvals/translations/en.json +104 -0
- package/modules/approvals/translations/pl.json +104 -0
- package/modules/audit/migrations/0001_audit_core.down.sql +8 -0
- package/modules/audit/migrations/0001_audit_core.up.sql +107 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.down.sql +2 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.up.sql +21 -0
- package/modules/audit/migrations/0003_audit_export_request.down.sql +12 -0
- package/modules/audit/migrations/0003_audit_export_request.up.sql +40 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.down.sql +17 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.up.sql +192 -0
- package/modules/audit/migrations/0005_audit_event_format.down.sql +17 -0
- package/modules/audit/migrations/0005_audit_event_format.up.sql +60 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.down.sql +3 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.up.sql +14 -0
- package/modules/audit/migrations/README.md +3 -0
- package/modules/audit/module.json +32 -0
- package/modules/audit/package.json +49 -0
- package/modules/audit/spec/module.yaml +809 -0
- package/modules/audit/src/acl/permissions.ts +7 -0
- package/modules/audit/src/api/endpoints.ts +315 -0
- package/modules/audit/src/cli/commands.json +95 -0
- package/modules/audit/src/cli/index.ts +658 -0
- package/modules/audit/src/client/DataClassesView.tsrx +420 -0
- package/modules/audit/src/client/ExportsView.tsrx +256 -0
- package/modules/audit/src/client/HoldsView.tsrx +604 -0
- package/modules/audit/src/client/SweepsView.tsrx +251 -0
- package/modules/audit/src/client/api.ts +185 -0
- package/modules/audit/src/client/contribution.tsrx +52 -0
- package/modules/audit/src/client/index.ts +23 -0
- package/modules/audit/src/client/navigation.ts +74 -0
- package/modules/audit/src/client/presentation.ts +105 -0
- package/modules/audit/src/client/state.ts +86 -0
- package/modules/audit/src/domain/data-classes.ts +16 -0
- package/modules/audit/src/domain/types.ts +339 -0
- package/modules/audit/src/index.ts +76 -0
- package/modules/audit/src/platform.ts +44 -0
- package/modules/audit/src/server/index.ts +177 -0
- package/modules/audit/src/server/runtime.ts +303 -0
- package/modules/audit/src/services/anchor-key.ts +143 -0
- package/modules/audit/src/services/anchor-rotation.ts +147 -0
- package/modules/audit/src/services/audit-runners.ts +278 -0
- package/modules/audit/src/services/backup-guard.ts +95 -0
- package/modules/audit/src/services/database-repository.ts +1946 -0
- package/modules/audit/src/services/declared-classes.ts +64 -0
- package/modules/audit/src/services/erasure-port.ts +126 -0
- package/modules/audit/src/services/erasure-service.ts +770 -0
- package/modules/audit/src/services/export-directory.ts +106 -0
- package/modules/audit/src/services/export-service.ts +714 -0
- package/modules/audit/src/services/hold-service.ts +295 -0
- package/modules/audit/src/services/index.ts +17 -0
- package/modules/audit/src/services/migration.ts +658 -0
- package/modules/audit/src/services/own-classes.ts +318 -0
- package/modules/audit/src/services/platform-version.ts +23 -0
- package/modules/audit/src/services/repository.ts +495 -0
- package/modules/audit/src/services/retention-service.ts +191 -0
- package/modules/audit/src/services/seal-service.ts +769 -0
- package/modules/audit/src/services/service-error.ts +61 -0
- package/modules/audit/src/services/subject-keys.ts +90 -0
- package/modules/audit/src/services/sweep-service.ts +298 -0
- package/modules/audit/src/services/zip.ts +217 -0
- package/modules/audit/src/settings.ts +69 -0
- package/modules/audit/translations/en.json +210 -0
- package/modules/audit/translations/pl.json +210 -0
- package/modules/auth/README.md +77 -29
- package/modules/auth/migrations/0016_external_identities.up.sql +16 -0
- package/modules/auth/migrations/0017_mfa_key_id.up.sql +8 -0
- package/modules/auth/migrations/0018_retire_bundled_module_scopes.up.sql +29 -0
- package/modules/auth/migrations/0019_notifications_member_scopes.up.sql +44 -0
- package/modules/auth/migrations/0020_identity_providers.up.sql +61 -0
- package/modules/auth/migrations/0021_membership_status.up.sql +19 -0
- package/modules/auth/migrations/0022_auth_provider_scopes.up.sql +45 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.down.sql +19 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.up.sql +71 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.down.sql +22 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.up.sql +48 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.down.sql +21 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.up.sql +47 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.down.sql +6 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.up.sql +15 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.down.sql +34 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.up.sql +72 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.down.sql +6 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.up.sql +21 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.down.sql +22 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.up.sql +56 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.down.sql +4 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.up.sql +10 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.down.sql +4 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.up.sql +31 -0
- package/modules/auth/migrations/0032_audit_actor_service.down.sql +9 -0
- package/modules/auth/migrations/0032_audit_actor_service.up.sql +10 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.down.sql +5 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.up.sql +23 -0
- package/modules/auth/module.json +3 -3
- package/modules/auth/package.json +2 -1
- package/modules/auth/spec/module.yaml +372 -3
- package/modules/auth/src/acl/scopes.ts +50 -6
- package/modules/auth/src/cli/commands.json +11 -0
- package/modules/auth/src/cli/greenfield.ts +2 -2
- package/modules/auth/src/cli/index.ts +14 -0
- package/modules/auth/src/cli/secrets.ts +114 -0
- package/modules/auth/src/client/AuthenticationCore.tsrx +61 -8
- package/modules/auth/src/client/api.ts +72 -6
- package/modules/auth/src/client/contribution.tsrx +23 -0
- package/modules/auth/src/client/index.ts +6 -0
- package/modules/auth/src/client/providers/IdentityProviderForm.tsrx +191 -0
- package/modules/auth/src/client/providers/IdentityProvidersView.tsrx +358 -0
- package/modules/auth/src/client/providers/api.ts +128 -0
- package/modules/auth/src/client/providers/provider-columns.tsrx +60 -0
- package/modules/auth/src/client/providers/state.ts +35 -0
- package/modules/auth/src/client/security/SecurityView.tsrx +9 -1
- package/modules/auth/src/client/state.ts +15 -1
- package/modules/auth/src/domain/types.ts +55 -0
- package/modules/auth/src/index.ts +11 -1
- package/modules/auth/src/middleware/authentication.ts +4 -0
- package/modules/auth/src/server/endpoints.ts +467 -171
- package/modules/auth/src/server/http.ts +3 -2
- package/modules/auth/src/server/index.ts +22 -1
- package/modules/auth/src/server/membership-endpoints.ts +62 -0
- package/modules/auth/src/server/mfa-enforcement.ts +156 -0
- package/modules/auth/src/server/oidc.ts +389 -0
- package/modules/auth/src/server/provider-endpoints.ts +246 -0
- package/modules/auth/src/server/provider-host.ts +77 -0
- package/modules/auth/src/server/runtime.ts +231 -55
- package/modules/auth/src/services/auth-service-error.ts +7 -2
- package/modules/auth/src/services/auth-service.ts +948 -51
- package/modules/auth/src/services/data-classes.ts +236 -0
- package/modules/auth/src/services/database-repository.ts +853 -71
- package/modules/auth/src/services/identity-provider-service.ts +571 -0
- package/modules/auth/src/services/mail-delivery.ts +16 -16
- package/modules/auth/src/services/mail-message.ts +54 -0
- package/modules/auth/src/services/mail-port.ts +24 -0
- package/modules/auth/src/services/mail-smtp.ts +85 -0
- package/modules/auth/src/services/mfa-rotation.ts +144 -0
- package/modules/auth/src/services/migration.ts +810 -0
- package/modules/auth/src/services/password.ts +14 -0
- package/modules/auth/src/services/provider-secret-rotation.ts +169 -0
- package/modules/auth/src/services/provider-secrets.ts +136 -0
- package/modules/auth/src/services/repository.ts +321 -5
- package/modules/auth/src/services/session-sweep-runner.ts +73 -0
- package/modules/auth/src/services/settings-store.ts +10 -83
- package/modules/auth/src/services/totp.ts +88 -62
- package/modules/auth/src/services/validation.ts +194 -7
- package/modules/auth/src/settings.ts +18 -0
- package/modules/auth/translations/en.json +84 -1
- package/modules/auth/translations/pl.json +84 -1
- package/modules/automations/migrations/0005_secret_rotation_inventory.down.sql +1 -0
- package/modules/automations/migrations/0005_secret_rotation_inventory.up.sql +6 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.down.sql +4 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.up.sql +11 -0
- package/modules/automations/module.json +24 -6
- package/modules/automations/package.json +4 -1
- package/modules/automations/spec/module.yaml +81 -7
- package/modules/automations/src/api/endpoints.ts +202 -28
- package/modules/automations/src/cli/commands.json +17 -0
- package/modules/automations/src/cli/index.ts +114 -0
- package/modules/automations/src/client/AutomationScheduleForm.tsrx +77 -19
- package/modules/automations/src/client/AutomationSchedulesView.tsrx +144 -40
- package/modules/automations/src/client/AutomationTriggersView.tsrx +131 -32
- package/modules/automations/src/client/api.ts +62 -19
- package/modules/automations/src/client/presentation.ts +20 -2
- package/modules/automations/src/client/state.ts +84 -0
- package/modules/automations/src/domain/cadence.ts +99 -3
- package/modules/automations/src/domain/cron.ts +366 -0
- package/modules/automations/src/domain/time-zone.ts +61 -0
- package/modules/automations/src/platform.ts +38 -4
- package/modules/automations/src/server/index.ts +11 -0
- package/modules/automations/src/server/runtime.ts +46 -22
- package/modules/{automations-workflows-integration/src/server/adapter.ts → automations/src/server/workflow-target.ts} +13 -14
- package/modules/{automations-workflows-integration/src/server/tools.ts → automations/src/server/workflow-tools.ts} +0 -0
- package/modules/automations/src/services/data-classes.ts +62 -0
- package/modules/automations/src/services/database-repository.ts +152 -38
- package/modules/automations/src/services/migration.ts +119 -9
- package/modules/automations/src/services/repository.ts +52 -1
- package/modules/automations/src/services/schedule-runner.ts +84 -0
- package/modules/automations/src/services/schedule-service.ts +152 -26
- package/modules/automations/src/services/secret-rotation.ts +176 -0
- package/modules/automations/src/services/secret-vault.ts +68 -41
- package/modules/automations/src/services/trigger-service.ts +13 -10
- package/modules/automations/translations/en.json +15 -2
- package/modules/automations/translations/pl.json +15 -2
- package/modules/connectors/migrations/0001_connectors_core.down.sql +3 -0
- package/modules/connectors/migrations/0001_connectors_core.up.sql +72 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.down.sql +3 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.up.sql +18 -0
- package/modules/connectors/migrations/0003_connectors_rotation_inventory.down.sql +2 -0
- package/modules/connectors/migrations/0003_connectors_rotation_inventory.up.sql +19 -0
- package/modules/connectors/migrations/README.md +3 -0
- package/modules/connectors/module.json +32 -0
- package/modules/{automations-workflows-integration → connectors}/package.json +28 -26
- package/modules/connectors/spec/module.yaml +448 -0
- package/modules/connectors/src/acl/permissions.ts +6 -0
- package/modules/connectors/src/agent/tools.ts +180 -0
- package/modules/connectors/src/api/endpoints.ts +572 -0
- package/modules/connectors/src/cli/commands.json +17 -0
- package/modules/connectors/src/cli/index.ts +126 -0
- package/modules/connectors/src/client/ConnectorCallsView.tsrx +358 -0
- package/modules/connectors/src/client/ConnectorForm.tsrx +424 -0
- package/modules/connectors/src/client/ConnectorsView.tsrx +711 -0
- package/modules/connectors/src/client/api.ts +281 -0
- package/modules/connectors/src/client/consent.ts +48 -0
- package/modules/connectors/src/client/contribution.tsrx +37 -0
- package/modules/connectors/src/client/index.ts +22 -0
- package/modules/connectors/src/client/navigation.ts +42 -0
- package/modules/connectors/src/client/presentation.ts +38 -0
- package/modules/connectors/src/client/state.ts +175 -0
- package/modules/connectors/src/domain/calls.ts +70 -0
- package/modules/connectors/src/domain/definitions.ts +190 -0
- package/modules/connectors/src/domain/http-json.ts +68 -0
- package/modules/connectors/src/domain/types.ts +185 -0
- package/modules/connectors/src/index.ts +64 -0
- package/modules/connectors/src/platform.ts +56 -0
- package/modules/connectors/src/server/index.ts +66 -0
- package/modules/connectors/src/server/runtime.ts +163 -0
- package/modules/connectors/src/services/call-service.ts +903 -0
- package/modules/connectors/src/services/connectors-service.ts +653 -0
- package/modules/connectors/src/services/credential-rotation.ts +221 -0
- package/modules/connectors/src/services/credential-vault.ts +194 -0
- package/modules/connectors/src/services/data-classes.ts +158 -0
- package/modules/connectors/src/services/database-repository.ts +897 -0
- package/modules/connectors/src/services/egress.ts +261 -0
- package/modules/connectors/src/services/index.ts +19 -0
- package/modules/connectors/src/services/migration.ts +202 -0
- package/modules/connectors/src/services/repository.ts +175 -0
- package/modules/connectors/src/services/service-error.ts +46 -0
- package/modules/connectors/src/settings.ts +69 -0
- package/modules/connectors/translations/en.json +191 -0
- package/modules/connectors/translations/pl.json +191 -0
- package/modules/directory/migrations/0001_directory_core.down.sql +5 -0
- package/modules/directory/migrations/0001_directory_core.up.sql +111 -0
- package/modules/directory/migrations/README.md +3 -0
- package/modules/directory/module.json +27 -0
- package/modules/directory/package.json +46 -0
- package/modules/directory/spec/module.yaml +351 -0
- package/modules/directory/src/acl/permissions.ts +7 -0
- package/modules/directory/src/api/endpoints.ts +478 -0
- package/modules/directory/src/api/scim-endpoints.ts +516 -0
- package/modules/directory/src/client/GroupMappingsView.tsrx +430 -0
- package/modules/directory/src/client/ProvisioningLogView.tsrx +248 -0
- package/modules/directory/src/client/ScimTokensView.tsrx +587 -0
- package/modules/directory/src/client/api.ts +222 -0
- package/modules/directory/src/client/contribution.tsrx +46 -0
- package/modules/directory/src/client/index.ts +22 -0
- package/modules/directory/src/client/navigation.ts +57 -0
- package/modules/directory/src/client/presentation.ts +143 -0
- package/modules/directory/src/client/state.ts +173 -0
- package/modules/directory/src/domain/scim.ts +346 -0
- package/modules/directory/src/domain/types.ts +166 -0
- package/modules/directory/src/index.ts +44 -0
- package/modules/directory/src/platform.ts +43 -0
- package/modules/directory/src/server/index.ts +17 -0
- package/modules/directory/src/server/runtime.ts +124 -0
- package/modules/directory/src/services/auth-port.ts +127 -0
- package/modules/directory/src/services/data-classes.ts +41 -0
- package/modules/directory/src/services/database-repository.ts +1067 -0
- package/modules/directory/src/services/directory-service.ts +311 -0
- package/modules/directory/src/services/index.ts +43 -0
- package/modules/directory/src/services/migration.ts +146 -0
- package/modules/directory/src/services/provisioning-service.ts +1420 -0
- package/modules/directory/src/services/rate-limiter.ts +103 -0
- package/modules/directory/src/services/repository.ts +208 -0
- package/modules/directory/src/services/service-error.ts +42 -0
- package/modules/directory/src/services/token-service.ts +215 -0
- package/modules/directory/src/settings.ts +86 -0
- package/modules/directory/translations/en.json +185 -0
- package/modules/directory/translations/pl.json +185 -0
- package/modules/documents/migrations/0001_documents_core.down.sql +1 -0
- package/modules/documents/migrations/0001_documents_core.up.sql +35 -0
- package/modules/documents/migrations/0002_documents_files_page.down.sql +1 -0
- package/modules/documents/migrations/0002_documents_files_page.up.sql +6 -0
- package/modules/documents/migrations/0003_documents_rotation_inventory.down.sql +2 -0
- package/modules/documents/migrations/0003_documents_rotation_inventory.up.sql +18 -0
- package/modules/documents/migrations/README.md +3 -0
- package/modules/documents/module.json +32 -0
- package/modules/documents/package.json +50 -0
- package/modules/documents/spec/module.yaml +248 -0
- package/modules/documents/src/acl/permissions.ts +6 -0
- package/modules/documents/src/api/endpoints.ts +401 -0
- package/modules/documents/src/cli/commands.json +17 -0
- package/modules/documents/src/cli/index.ts +145 -0
- package/modules/documents/src/client/DocumentUploader.tsrx +148 -0
- package/modules/documents/src/client/DocumentsView.tsrx +540 -0
- package/modules/documents/src/client/api.ts +209 -0
- package/modules/documents/src/client/contribution.tsrx +29 -0
- package/modules/documents/src/client/download.ts +70 -0
- package/modules/documents/src/client/index.ts +22 -0
- package/modules/documents/src/client/navigation.ts +25 -0
- package/modules/documents/src/client/presentation.ts +110 -0
- package/modules/documents/src/client/state.ts +117 -0
- package/modules/documents/src/domain/attachments.ts +84 -0
- package/modules/documents/src/domain/types.ts +80 -0
- package/modules/documents/src/index.ts +46 -0
- package/modules/documents/src/platform.ts +61 -0
- package/modules/documents/src/server/index.ts +30 -0
- package/modules/documents/src/server/runtime.ts +107 -0
- package/modules/documents/src/services/attachments.ts +39 -0
- package/modules/documents/src/services/data-classes.ts +25 -0
- package/modules/documents/src/services/database-repository.ts +270 -0
- package/modules/documents/src/services/documents-service.ts +590 -0
- package/modules/documents/src/services/index.ts +18 -0
- package/modules/documents/src/services/migration.ts +117 -0
- package/modules/documents/src/services/repository.ts +58 -0
- package/modules/documents/src/services/storage-rotation.ts +157 -0
- package/modules/documents/src/settings.ts +107 -0
- package/modules/documents/translations/en.json +111 -0
- package/modules/documents/translations/pl.json +111 -0
- package/modules/exports/migrations/0001_exports_core.down.sql +2 -0
- package/modules/exports/migrations/0001_exports_core.up.sql +28 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.down.sql +4 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.up.sql +21 -0
- package/modules/exports/migrations/0003_exports_rotation_inventory.down.sql +1 -0
- package/modules/exports/migrations/0003_exports_rotation_inventory.up.sql +9 -0
- package/modules/exports/migrations/README.md +3 -0
- package/modules/exports/module.json +32 -0
- package/modules/exports/package.json +45 -0
- package/modules/exports/spec/module.yaml +230 -0
- package/modules/exports/src/acl/permissions.ts +6 -0
- package/modules/exports/src/api/endpoints.ts +211 -0
- package/modules/exports/src/cli/commands.json +17 -0
- package/modules/exports/src/cli/index.ts +145 -0
- package/modules/exports/src/client/ExportsView.tsrx +327 -0
- package/modules/exports/src/client/api.ts +133 -0
- package/modules/exports/src/client/contribution.tsrx +31 -0
- package/modules/exports/src/client/index.ts +20 -0
- package/modules/exports/src/client/navigation.ts +25 -0
- package/modules/exports/src/client/presentation.ts +53 -0
- package/modules/exports/src/client/state.ts +56 -0
- package/modules/exports/src/domain/lists.ts +29 -0
- package/modules/exports/src/domain/types.ts +120 -0
- package/modules/exports/src/index.ts +41 -0
- package/modules/exports/src/platform.ts +80 -0
- package/modules/exports/src/server/index.ts +50 -0
- package/modules/exports/src/server/runtime.ts +160 -0
- package/modules/exports/src/services/data-classes.ts +59 -0
- package/modules/exports/src/services/database-repository.ts +403 -0
- package/modules/exports/src/services/export-runner.ts +123 -0
- package/modules/exports/src/services/export-service.ts +356 -0
- package/modules/exports/src/services/index.ts +6 -0
- package/modules/exports/src/services/list-registry.ts +105 -0
- package/modules/exports/src/services/migration.ts +116 -0
- package/modules/exports/src/services/repository.ts +96 -0
- package/modules/exports/src/services/storage-rotation.ts +138 -0
- package/modules/exports/src/settings.ts +70 -0
- package/modules/exports/translations/en.json +69 -0
- package/modules/exports/translations/pl.json +69 -0
- package/modules/import/migrations/0001_import_core.down.sql +6 -0
- package/modules/import/migrations/0001_import_core.up.sql +61 -0
- package/modules/import/migrations/0002_import_job_routing_role.down.sql +4 -0
- package/modules/import/migrations/0002_import_job_routing_role.up.sql +20 -0
- package/modules/import/migrations/0003_import_jobs_export_index.down.sql +1 -0
- package/modules/import/migrations/0003_import_jobs_export_index.up.sql +7 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.down.sql +1 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.up.sql +7 -0
- package/modules/import/migrations/README.md +3 -0
- package/modules/import/module.json +37 -0
- package/modules/import/package.json +50 -0
- package/modules/import/spec/module.yaml +335 -0
- package/modules/import/src/acl/permissions.ts +6 -0
- package/modules/import/src/api/endpoints.ts +400 -0
- package/modules/import/src/client/ImportJobDrawer.tsrx +229 -0
- package/modules/import/src/client/ImportsView.tsrx +455 -0
- package/modules/import/src/client/NewImportForm.tsrx +274 -0
- package/modules/import/src/client/api.ts +243 -0
- package/modules/import/src/client/contribution.tsrx +29 -0
- package/modules/import/src/client/index.ts +23 -0
- package/modules/import/src/client/navigation.ts +25 -0
- package/modules/import/src/client/presentation.ts +59 -0
- package/modules/import/src/client/state.ts +43 -0
- package/modules/import/src/domain/csv.ts +258 -0
- package/modules/import/src/domain/ports.ts +157 -0
- package/modules/import/src/domain/types.ts +179 -0
- package/modules/import/src/index.ts +58 -0
- package/modules/import/src/platform.ts +60 -0
- package/modules/import/src/server/index.ts +49 -0
- package/modules/import/src/server/runtime.ts +158 -0
- package/modules/import/src/services/csv-source.ts +121 -0
- package/modules/import/src/services/data-classes.ts +63 -0
- package/modules/import/src/services/database-repository.ts +780 -0
- package/modules/import/src/services/import-runner.ts +127 -0
- package/modules/import/src/services/import-service.ts +872 -0
- package/modules/import/src/services/index.ts +6 -0
- package/modules/import/src/services/migration.ts +156 -0
- package/modules/import/src/services/port-registry.ts +158 -0
- package/modules/import/src/services/repository.ts +147 -0
- package/modules/import/src/settings.ts +70 -0
- package/modules/import/translations/en.json +175 -0
- package/modules/import/translations/pl.json +175 -0
- package/modules/metering/migrations/0001_metering_core.down.sql +6 -0
- package/modules/metering/migrations/0001_metering_core.up.sql +119 -0
- package/modules/metering/migrations/0002_metering_bucket_export.down.sql +3 -0
- package/modules/metering/migrations/0002_metering_bucket_export.up.sql +5 -0
- package/modules/metering/migrations/README.md +3 -0
- package/modules/metering/module.json +46 -0
- package/modules/metering/package.json +50 -0
- package/modules/metering/spec/module.yaml +269 -0
- package/modules/metering/src/acl/permissions.ts +5 -0
- package/modules/metering/src/api/endpoints.ts +104 -0
- package/modules/metering/src/cli/commands.json +28 -0
- package/modules/metering/src/cli/index.ts +246 -0
- package/modules/metering/src/client/LimitsView.tsrx +170 -0
- package/modules/metering/src/client/UsageSummaryWidget.tsrx +63 -0
- package/modules/metering/src/client/UsageView.tsrx +205 -0
- package/modules/metering/src/client/api.ts +91 -0
- package/modules/metering/src/client/contribution.tsrx +42 -0
- package/modules/metering/src/client/index.ts +26 -0
- package/modules/metering/src/client/navigation.ts +54 -0
- package/modules/metering/src/client/presentation.ts +63 -0
- package/modules/metering/src/client/state.ts +31 -0
- package/modules/metering/src/domain/meters.ts +100 -0
- package/modules/metering/src/domain/types.ts +71 -0
- package/modules/metering/src/index.ts +51 -0
- package/modules/metering/src/platform.ts +84 -0
- package/modules/metering/src/server/index.ts +40 -0
- package/modules/metering/src/server/runtime.ts +165 -0
- package/modules/metering/src/services/data-classes.ts +34 -0
- package/modules/metering/src/services/database-repository.ts +574 -0
- package/modules/metering/src/services/index.ts +9 -0
- package/modules/metering/src/services/meter-registry.ts +145 -0
- package/modules/metering/src/services/metering-service.ts +441 -0
- package/modules/metering/src/services/migration.ts +183 -0
- package/modules/metering/src/services/notifications.ts +75 -0
- package/modules/metering/src/services/reports.ts +105 -0
- package/modules/metering/src/services/repository.ts +132 -0
- package/modules/metering/src/services/service-error.ts +46 -0
- package/modules/metering/src/settings.ts +47 -0
- package/modules/metering/translations/en.json +68 -0
- package/modules/metering/translations/pl.json +68 -0
- package/modules/notifications/migrations/0001_notifications_core.down.sql +1 -0
- package/modules/notifications/migrations/0001_notifications_core.up.sql +26 -0
- package/modules/notifications/migrations/0002_notifications_preferences.down.sql +1 -0
- package/modules/notifications/migrations/0002_notifications_preferences.up.sql +17 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.down.sql +1 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.up.sql +30 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.down.sql +1 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.up.sql +35 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.down.sql +2 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.up.sql +17 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.down.sql +1 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.up.sql +11 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.down.sql +2 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.up.sql +19 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.down.sql +8 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.up.sql +19 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.down.sql +16 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.up.sql +18 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.down.sql +16 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.up.sql +18 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.down.sql +5 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.up.sql +15 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.down.sql +12 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.up.sql +38 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.down.sql +5 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.up.sql +13 -0
- package/modules/notifications/migrations/README.md +3 -0
- package/modules/notifications/module.json +32 -0
- package/modules/notifications/package.json +49 -0
- package/modules/notifications/spec/module.yaml +718 -0
- package/modules/notifications/src/acl/permissions.ts +11 -0
- package/modules/notifications/src/api/endpoints.ts +814 -0
- package/modules/notifications/src/cli/commands.json +17 -0
- package/modules/notifications/src/cli/index.ts +126 -0
- package/modules/notifications/src/client/DeliveriesView.tsrx +483 -0
- package/modules/notifications/src/client/FactList.tsrx +24 -0
- package/modules/notifications/src/client/NotificationPreferencesView.tsrx +240 -0
- package/modules/notifications/src/client/NotificationsInboxView.tsrx +592 -0
- package/modules/notifications/src/client/UnreadCountWidget.tsrx +62 -0
- package/modules/notifications/src/client/WebhookForm.tsrx +297 -0
- package/modules/notifications/src/client/WebhooksView.tsrx +637 -0
- package/modules/notifications/src/client/api.ts +382 -0
- package/modules/notifications/src/client/contribution.tsrx +83 -0
- package/modules/notifications/src/client/inbox.ts +41 -0
- package/modules/notifications/src/client/index.ts +29 -0
- package/modules/notifications/src/client/navigation.ts +92 -0
- package/modules/notifications/src/client/notifications.css +70 -0
- package/modules/notifications/src/client/presentation.ts +81 -0
- package/modules/notifications/src/client/state.ts +246 -0
- package/modules/notifications/src/client/unread-count.ts +26 -0
- package/modules/notifications/src/domain/locale.ts +47 -0
- package/modules/notifications/src/domain/publish.ts +46 -0
- package/modules/notifications/src/domain/types.ts +186 -0
- package/modules/notifications/src/index.ts +62 -0
- package/modules/notifications/src/platform.ts +85 -0
- package/modules/notifications/src/server/index.ts +82 -0
- package/modules/notifications/src/server/runtime.ts +251 -0
- package/modules/notifications/src/services/data-classes.ts +139 -0
- package/modules/notifications/src/services/database-repository.ts +1334 -0
- package/modules/notifications/src/services/delivery-payload.ts +93 -0
- package/modules/notifications/src/services/delivery-runner.ts +170 -0
- package/modules/notifications/src/services/delivery-service.ts +811 -0
- package/modules/notifications/src/services/egress.ts +239 -0
- package/modules/notifications/src/services/email-channel.ts +93 -0
- package/modules/notifications/src/services/index.ts +23 -0
- package/modules/notifications/src/services/migration.ts +572 -0
- package/modules/notifications/src/services/notifications-service.ts +297 -0
- package/modules/notifications/src/services/paging.ts +60 -0
- package/modules/notifications/src/services/publish-service.ts +133 -0
- package/modules/notifications/src/services/repository.ts +342 -0
- package/modules/notifications/src/services/secret-rotation.ts +177 -0
- package/modules/notifications/src/services/secret-vault.ts +168 -0
- package/modules/notifications/src/services/service-error.ts +67 -0
- package/modules/notifications/src/services/signature.ts +81 -0
- package/modules/notifications/src/services/webhook-service.ts +307 -0
- package/modules/notifications/src/settings.ts +130 -0
- package/modules/notifications/translations/en.json +255 -0
- package/modules/notifications/translations/pl.json +255 -0
- package/modules/profile/module.json +3 -3
- package/modules/profile/package.json +1 -1
- package/modules/profile/spec/module.yaml +3 -3
- package/modules/profile/src/services/database-repository.ts +3 -13
- package/modules/reports/module.json +28 -0
- package/modules/reports/package.json +42 -0
- package/modules/reports/spec/module.yaml +231 -0
- package/modules/reports/src/acl/permissions.ts +5 -0
- package/modules/reports/src/api/endpoints.ts +72 -0
- package/modules/reports/src/client/ReportsSummaryWidget.tsrx +52 -0
- package/modules/reports/src/client/ReportsView.tsrx +246 -0
- package/modules/reports/src/client/api.ts +65 -0
- package/modules/reports/src/client/contribution.tsrx +36 -0
- package/modules/reports/src/client/index.ts +18 -0
- package/modules/reports/src/client/navigation.ts +39 -0
- package/modules/reports/src/client/presentation.ts +123 -0
- package/modules/reports/src/client/state.ts +28 -0
- package/modules/reports/src/domain/providers.ts +115 -0
- package/modules/reports/src/domain/types.ts +44 -0
- package/modules/reports/src/index.ts +47 -0
- package/modules/reports/src/platform.ts +37 -0
- package/modules/reports/src/server/index.ts +21 -0
- package/modules/reports/src/server/runtime.ts +40 -0
- package/modules/reports/src/services/index.ts +17 -0
- package/modules/reports/src/services/provider-registry.ts +144 -0
- package/modules/reports/src/services/range.ts +65 -0
- package/modules/reports/src/services/reports-service.ts +316 -0
- package/modules/reports/src/services/service-error.ts +26 -0
- package/modules/reports/src/settings.ts +49 -0
- package/modules/reports/translations/en.json +35 -0
- package/modules/reports/translations/pl.json +35 -0
- package/modules/sandbox/module.json +4 -4
- package/modules/sandbox/package.json +1 -1
- package/modules/sandbox/spec/module.yaml +3 -3
- package/modules/sandbox/src/services/database-repository.ts +14 -23
- package/modules/sandbox/src/services/directory.ts +16 -0
- package/modules/sandbox/src/services/sandbox-service.ts +13 -11
- package/modules/search/migrations/0001_search_core.down.sql +1 -0
- package/modules/search/migrations/0001_search_core.up.sql +22 -0
- package/modules/search/migrations/0002_search_recent_export.down.sql +3 -0
- package/modules/search/migrations/0002_search_recent_export.up.sql +5 -0
- package/modules/search/migrations/README.md +3 -0
- package/modules/search/module.json +28 -0
- package/modules/search/package.json +43 -0
- package/modules/search/spec/module.yaml +177 -0
- package/modules/search/src/acl/permissions.ts +5 -0
- package/modules/search/src/api/endpoints.ts +221 -0
- package/modules/search/src/client/SearchView.tsrx +346 -0
- package/modules/search/src/client/api.ts +157 -0
- package/modules/search/src/client/contribution.tsrx +31 -0
- package/modules/search/src/client/index.ts +17 -0
- package/modules/search/src/client/navigation.ts +97 -0
- package/modules/search/src/client/search.css +56 -0
- package/modules/search/src/client/state.ts +113 -0
- package/modules/search/src/domain/data-classes.ts +73 -0
- package/modules/search/src/domain/providers.ts +88 -0
- package/modules/search/src/domain/types.ts +56 -0
- package/modules/search/src/index.ts +46 -0
- package/modules/search/src/platform.ts +42 -0
- package/modules/search/src/server/index.ts +25 -0
- package/modules/search/src/server/runtime.ts +123 -0
- package/modules/search/src/services/database-repository.ts +163 -0
- package/modules/search/src/services/index.ts +21 -0
- package/modules/search/src/services/migration.ts +65 -0
- package/modules/search/src/services/provider-registry.ts +137 -0
- package/modules/search/src/services/repository.ts +43 -0
- package/modules/search/src/services/search-service.ts +442 -0
- package/modules/search/src/services/service-error.ts +35 -0
- package/modules/search/src/settings.ts +68 -0
- package/modules/search/translations/en.json +45 -0
- package/modules/search/translations/pl.json +45 -0
- package/modules/system/module.json +2 -2
- package/modules/system/package.json +1 -1
- package/modules/system/spec/module.yaml +30 -3
- package/modules/system/src/client/FlagsPanel.tsrx +127 -0
- package/modules/system/src/client/ModuleSettingRow.tsrx +17 -7
- package/modules/system/src/client/ModuleSettingsSection.tsrx +10 -71
- package/modules/system/src/client/ModulesView.tsrx +91 -65
- package/modules/system/src/client/flags.ts +35 -0
- package/modules/system/src/client/index.ts +8 -0
- package/modules/system/src/client/navigation.ts +8 -0
- package/modules/system/src/client/settings-state.ts +159 -0
- package/modules/system/src/client/state.ts +2 -0
- package/modules/system/src/domain/time-zone.ts +105 -0
- package/modules/system/src/index.ts +12 -0
- package/modules/system/src/platform.ts +5 -1
- package/modules/system/src/server/endpoints.ts +72 -21
- package/modules/system/src/settings.ts +28 -0
- package/modules/system/translations/en.json +17 -0
- package/modules/system/translations/pl.json +17 -0
- package/modules/users/module.json +30 -4
- package/modules/users/package.json +4 -1
- package/modules/users/spec/module.yaml +290 -7
- package/modules/users/src/api/endpoints.ts +228 -15
- package/modules/users/src/client/InviteMemberForm.tsrx +2 -2
- package/modules/users/src/client/MemberDrawer.tsrx +142 -26
- package/modules/users/src/client/UserAccountForm.tsrx +2 -2
- package/modules/users/src/client/UsersView.tsrx +432 -71
- package/modules/users/src/client/api.ts +106 -12
- package/modules/users/src/client/contribution.tsrx +5 -0
- package/modules/users/src/client/member-columns.tsrx +22 -9
- package/modules/users/src/client/state.ts +172 -7
- package/modules/users/src/domain/lists.ts +9 -0
- package/modules/users/src/index.ts +11 -0
- package/modules/users/src/platform.ts +50 -1
- package/modules/users/src/services/member-export.ts +51 -0
- package/modules/users/src/services/member-import.ts +249 -0
- package/modules/users/src/services/member-search.ts +145 -0
- package/modules/users/src/services/users-service.ts +117 -4
- package/modules/users/translations/en.json +57 -8
- package/modules/users/translations/pl.json +57 -8
- package/modules/workflows/migrations/0004_payload_rotation_inventory.up.sql +17 -0
- package/modules/workflows/migrations/0005_workflows_human_approval.up.sql +28 -0
- package/modules/workflows/migrations/0006_workflows_retention_indexes.up.sql +11 -0
- package/modules/workflows/migrations/0007_workflows_erasure_subject_indexes.up.sql +17 -0
- package/modules/workflows/migrations/0008_workflows_subject_account.up.sql +24 -0
- package/modules/workflows/migrations/0009_workflows_definition_list_indexes.up.sql +9 -0
- package/modules/workflows/module.json +34 -6
- package/modules/workflows/package.json +2 -1
- package/modules/workflows/spec/module.yaml +26 -9
- package/modules/workflows/src/api/endpoints.ts +131 -25
- package/modules/workflows/src/cli/commands.json +17 -0
- package/modules/workflows/src/cli/index.ts +114 -0
- package/modules/workflows/src/client/WorkflowExecutionHistory.tsrx +36 -27
- package/modules/workflows/src/client/WorkflowInspector.tsrx +116 -0
- package/modules/workflows/src/client/WorkflowNodePalette.tsrx +1 -0
- package/modules/workflows/src/client/WorkflowsView.tsrx +236 -99
- package/modules/workflows/src/client/api.ts +54 -34
- package/modules/workflows/src/client/canvas-model.ts +12 -0
- package/modules/workflows/src/client/state.ts +95 -0
- package/modules/workflows/src/domain/events.ts +25 -11
- package/modules/workflows/src/domain/graph.ts +135 -1
- package/modules/workflows/src/domain/types.ts +91 -4
- package/modules/workflows/src/platform.ts +12 -0
- package/modules/workflows/src/server/runtime.ts +78 -5
- package/modules/workflows/src/services/approvals.ts +62 -0
- package/modules/workflows/src/services/cursors.ts +37 -0
- package/modules/workflows/src/services/data-classes.ts +232 -0
- package/modules/workflows/src/services/database-repository.ts +660 -171
- package/modules/workflows/src/services/migration.ts +240 -0
- package/modules/workflows/src/services/notifications.ts +98 -0
- package/modules/workflows/src/services/payload-codec.ts +51 -28
- package/modules/workflows/src/services/payload-rotation.ts +171 -0
- package/modules/workflows/src/services/repository.ts +123 -8
- package/modules/workflows/src/services/simulation.ts +7 -0
- package/modules/workflows/src/services/worker.ts +446 -25
- package/modules/workflows/src/services/workflows-service.ts +264 -103
- package/modules/workflows/translations/en.json +12 -4
- package/modules/workflows/translations/pl.json +12 -4
- package/modules.json +48 -4
- package/package.json +64 -6
- package/packages/client/package.json +1 -0
- package/packages/client/src/ApplicationShell.tsrx +43 -0
- package/packages/client/src/contributions.ts +55 -0
- package/packages/client/src/i18n/locales/en.json +5 -0
- package/packages/client/src/i18n/locales/pl.json +5 -0
- package/packages/client/src/index.ts +13 -1
- package/packages/client/src/routing.ts +22 -0
- package/packages/client/src/shell/CommandPalette.tsrx +223 -11
- package/packages/client/src/shell/command-search.ts +126 -0
- package/packages/client/src/shell/command.ts +30 -0
- package/packages/client/src/shell/navigation.ts +12 -0
- package/packages/client/src/shell/palette-keys.ts +27 -0
- package/packages/client/src/shell/shell.css +7 -0
- package/packages/contracts/schemas/module-spec.schema.json +287 -1
- package/packages/contracts/schemas/module.schema.json +25 -0
- package/packages/contracts/src/index.ts +144 -1
- package/packages/database/src/backup.ts +180 -0
- package/packages/database/src/decoders.ts +25 -0
- package/packages/database/src/index.ts +17 -0
- package/packages/database/src/migrations.ts +7 -0
- package/packages/database/src/record-history.ts +5 -14
- package/packages/harness/src/index.ts +2 -0
- package/packages/harness/src/runtime.ts +378 -2
- package/packages/harness/src/tool-adapters.ts +20 -9
- package/packages/kernel/src/acl.ts +179 -0
- package/packages/kernel/src/approval-grant.ts +310 -0
- package/packages/kernel/src/capability-registry.ts +69 -2
- package/packages/kernel/src/data-class-registry.ts +354 -0
- package/packages/kernel/src/index.ts +85 -4
- package/packages/kernel/src/keyring.ts +208 -0
- package/packages/kernel/src/module-compatibility.ts +35 -4
- package/packages/kernel/src/module-registry.ts +49 -2
- package/packages/kernel/src/module-settings.ts +189 -27
- package/packages/server/package.json +2 -1
- package/packages/server/src/composition.ts +38 -0
- package/packages/server/src/endpoint.ts +104 -47
- package/packages/server/src/export/csv.ts +34 -0
- package/packages/server/src/export/definition.ts +346 -0
- package/packages/server/src/export/index.ts +61 -0
- package/packages/server/src/export/run.ts +116 -0
- package/packages/server/src/index.ts +155 -0
- package/packages/server/src/jobs/index.ts +93 -0
- package/packages/server/src/jobs/runner.ts +486 -0
- package/packages/server/src/log.ts +291 -0
- package/packages/server/src/mail/config.ts +184 -0
- package/packages/server/src/mail/contracts.ts +251 -0
- package/packages/server/src/mail/index.ts +31 -0
- package/packages/server/src/mail/port.ts +101 -0
- package/packages/server/src/mail/smtp.ts +191 -0
- package/packages/server/src/mail/template.ts +105 -0
- package/packages/server/src/metrics.ts +447 -0
- package/packages/server/src/pagination.ts +246 -0
- package/packages/server/src/trace/context.ts +103 -0
- package/packages/server/src/trace/egress.ts +66 -0
- package/packages/server/src/trace/error-sink.ts +296 -0
- package/packages/server/src/trace/exporter.ts +295 -0
- package/packages/server/src/trace/index.ts +60 -0
- package/packages/server/src/trace/job-sink.ts +172 -0
- package/packages/server/src/trace/tracer.ts +338 -0
- package/packages/server/src/web.ts +5 -1
- package/packages/storage/package.json +40 -0
- package/packages/storage/src/config.ts +189 -0
- package/packages/storage/src/content-type.ts +124 -0
- package/packages/storage/src/contracts.ts +112 -0
- package/packages/storage/src/envelope.ts +238 -0
- package/packages/storage/src/index.ts +49 -0
- package/packages/storage/src/local.ts +75 -0
- package/packages/storage/src/port.ts +262 -0
- package/packages/storage/src/read-token.ts +130 -0
- package/packages/storage/src/reseal.ts +128 -0
- package/packages/storage/src/s3.ts +144 -0
- package/packages/storage/src/scanner.ts +22 -0
- package/packages/storage/src/sigv4.ts +104 -0
- package/packages/storage/src/store.ts +13 -0
- package/packages/ui/package.json +1 -0
- package/packages/ui/src/components/Button.tsrx +3 -0
- package/packages/ui/src/components/ConfirmDialog.tsrx +13 -2
- package/packages/ui/src/components/DateField.tsrx +92 -0
- package/packages/ui/src/components/DatePicker.tsrx +525 -0
- package/packages/ui/src/components/DateRangeField.tsrx +93 -0
- package/packages/ui/src/components/Drawer.tsrx +10 -1
- package/packages/ui/src/components/FileUpload.tsrx +158 -0
- package/packages/ui/src/components/Pagination.tsrx +130 -0
- package/packages/ui/src/components/Select.tsrx +78 -0
- package/packages/ui/src/components/Table.tsrx +498 -81
- package/packages/ui/src/components/Tabs.tsrx +53 -0
- package/packages/ui/src/components/ToastHost.tsrx +48 -0
- package/packages/ui/src/components/calendar.ts +243 -0
- package/packages/ui/src/components/date-field.ts +62 -0
- package/packages/ui/src/components/file-upload.ts +49 -0
- package/packages/ui/src/components/focus-trap.ts +62 -0
- package/packages/ui/src/components/pagination.ts +68 -0
- package/packages/ui/src/components/table-sorting.ts +49 -0
- package/packages/ui/src/components/tabs.ts +61 -0
- package/packages/ui/src/components/toast-store.ts +116 -0
- package/packages/ui/src/icons/Icon.tsrx +5 -0
- package/packages/ui/src/index.ts +45 -0
- package/packages/ui/src/styles/components.css +598 -0
- package/modules/automations-workflows-integration/module.json +0 -27
- package/modules/automations-workflows-integration/spec/module.yaml +0 -93
- package/modules/automations-workflows-integration/src/index.ts +0 -14
- package/modules/automations-workflows-integration/src/platform.ts +0 -24
- package/modules/automations-workflows-integration/src/server/index.ts +0 -11
- package/modules/automations-workflows-integration/translations/en.json +0 -21
- package/modules/automations-workflows-integration/translations/pl.json +0 -21
- package/modules/workflows/src/services/cursor-codec.ts +0 -62
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import {
|
|
3
|
+
integer,
|
|
3
4
|
runDatabaseMigrations,
|
|
4
5
|
type DatabaseHandle,
|
|
5
6
|
type DatabaseTransaction,
|
|
6
7
|
} from '@flowdular/sdk/database';
|
|
7
8
|
import type { Actor, UserActor } from '@flowdular/sdk/kernel';
|
|
9
|
+
import { keysetWhere } from '@flowdular/sdk/server';
|
|
8
10
|
import type {
|
|
9
11
|
JsonValue,
|
|
10
12
|
WorkflowAuditEvent,
|
|
@@ -23,9 +25,9 @@ import type {
|
|
|
23
25
|
WorkflowRunDetail,
|
|
24
26
|
WorkflowRunEventTypeV1,
|
|
25
27
|
WorkflowRunEventV1,
|
|
26
|
-
WorkflowRunFilters,
|
|
27
|
-
WorkflowRunPage,
|
|
28
28
|
WorkflowRunStatus,
|
|
29
|
+
WorkflowRunSummary,
|
|
30
|
+
WorkflowSortDirection,
|
|
29
31
|
WorkflowUsageRollupV1,
|
|
30
32
|
} from '../domain/types.ts';
|
|
31
33
|
import { WORKFLOW_LIMITS } from '../domain/types.ts';
|
|
@@ -38,11 +40,18 @@ import { databaseMigrations } from './migration.ts';
|
|
|
38
40
|
import type { WorkflowPayloadCodec } from './payload-codec.ts';
|
|
39
41
|
import type {
|
|
40
42
|
CreateWorkflowRunWrite,
|
|
43
|
+
ExportedWorkflowDefinition,
|
|
44
|
+
ExportedWorkflowRun,
|
|
41
45
|
SettleAttemptWrite,
|
|
42
46
|
SettleEdgeWrite,
|
|
43
47
|
StartAttemptWrite,
|
|
44
|
-
|
|
48
|
+
WorkflowAuditListRead,
|
|
49
|
+
WorkflowDefinitionExportCursor,
|
|
50
|
+
WorkflowDefinitionListRead,
|
|
45
51
|
WorkflowDefinitionWrite,
|
|
52
|
+
WorkflowKeysetPage,
|
|
53
|
+
WorkflowRunExportCursor,
|
|
54
|
+
WorkflowRunListRead,
|
|
46
55
|
WorkflowRunRecord,
|
|
47
56
|
WorkflowsRepository,
|
|
48
57
|
} from './repository.ts';
|
|
@@ -54,20 +63,11 @@ const TERMINAL_RUNS = new Set<WorkflowRunStatus>([
|
|
|
54
63
|
'cancelled',
|
|
55
64
|
]);
|
|
56
65
|
|
|
57
|
-
/* PostgreSQL returns BIGINT as a string, so every integer column is
|
|
58
|
-
normalized on the way out of a row. */
|
|
59
|
-
function integer(value: number | bigint | string): number {
|
|
60
|
-
const normalized = Number(value);
|
|
61
|
-
if (!Number.isSafeInteger(normalized)) {
|
|
62
|
-
throw new Error('The workflows database returned an invalid integer.');
|
|
63
|
-
}
|
|
64
|
-
return normalized;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
66
|
function optionalInteger(
|
|
68
67
|
value: number | bigint | string | null,
|
|
68
|
+
field: string,
|
|
69
69
|
): number | null {
|
|
70
|
-
return value === null ? null : integer(value);
|
|
70
|
+
return value === null ? null : integer(value, field);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
type Int = number | bigint | string;
|
|
@@ -97,6 +97,19 @@ interface RevisionRow {
|
|
|
97
97
|
published_actor_json: string | null;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/** A definition and the revision it publishes, read in one statement. */
|
|
101
|
+
interface ExportDefinitionRow extends DefinitionRow {
|
|
102
|
+
revision_id: string;
|
|
103
|
+
revision_workflow_id: string;
|
|
104
|
+
revision_number: Int;
|
|
105
|
+
graph_json: string;
|
|
106
|
+
graph_checksum: string;
|
|
107
|
+
compiler_version: Int;
|
|
108
|
+
compiled_order_json: string;
|
|
109
|
+
published_at: Int | null;
|
|
110
|
+
published_actor_json: string | null;
|
|
111
|
+
}
|
|
112
|
+
|
|
100
113
|
interface RunRow {
|
|
101
114
|
id: string;
|
|
102
115
|
tenant_id: string;
|
|
@@ -179,6 +192,19 @@ interface EdgeRow {
|
|
|
179
192
|
settled_at: Int;
|
|
180
193
|
}
|
|
181
194
|
|
|
195
|
+
/** The run id a page of child rows carries, so one query serves many runs. */
|
|
196
|
+
interface ExportNodeStateRow extends NodeStateRow {
|
|
197
|
+
run_id: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
interface ExportAttemptRow extends AttemptRow {
|
|
201
|
+
run_id: string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
interface ExportEdgeRow extends EdgeRow {
|
|
205
|
+
run_id: string;
|
|
206
|
+
}
|
|
207
|
+
|
|
182
208
|
interface EventRow {
|
|
183
209
|
event_id: string;
|
|
184
210
|
tenant_id: string;
|
|
@@ -229,10 +255,16 @@ function definitionFromRow(row: DefinitionRow): WorkflowDefinition {
|
|
|
229
255
|
name: row.name,
|
|
230
256
|
description: row.description,
|
|
231
257
|
status: row.status,
|
|
232
|
-
currentDraftRevision: integer(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
258
|
+
currentDraftRevision: integer(
|
|
259
|
+
row.current_draft_revision,
|
|
260
|
+
'current_draft_revision',
|
|
261
|
+
),
|
|
262
|
+
publishedRevision: optionalInteger(
|
|
263
|
+
row.published_revision,
|
|
264
|
+
'published_revision',
|
|
265
|
+
),
|
|
266
|
+
createdAt: integer(row.created_at, 'created_at'),
|
|
267
|
+
updatedAt: integer(row.updated_at, 'updated_at'),
|
|
236
268
|
};
|
|
237
269
|
}
|
|
238
270
|
|
|
@@ -240,12 +272,12 @@ function revisionFromRow(row: RevisionRow): WorkflowRevision {
|
|
|
240
272
|
return {
|
|
241
273
|
id: row.id,
|
|
242
274
|
workflowId: row.workflow_id,
|
|
243
|
-
revision: integer(row.revision),
|
|
275
|
+
revision: integer(row.revision, 'revision'),
|
|
244
276
|
graph: parse<WorkflowGraphV1>(row.graph_json),
|
|
245
277
|
graphChecksum: row.graph_checksum,
|
|
246
|
-
compilerVersion: integer(row.compiler_version) as 1,
|
|
278
|
+
compilerVersion: integer(row.compiler_version, 'compiler_version') as 1,
|
|
247
279
|
compiledOrder: parse<readonly string[]>(row.compiled_order_json),
|
|
248
|
-
publishedAt: optionalInteger(row.published_at),
|
|
280
|
+
publishedAt: optionalInteger(row.published_at, 'published_at'),
|
|
249
281
|
publishedBy:
|
|
250
282
|
row.published_actor_json === null
|
|
251
283
|
? null
|
|
@@ -253,16 +285,51 @@ function revisionFromRow(row: RevisionRow): WorkflowRevision {
|
|
|
253
285
|
};
|
|
254
286
|
}
|
|
255
287
|
|
|
288
|
+
function nodeExecutionFromRow(
|
|
289
|
+
row: NodeStateRow,
|
|
290
|
+
attempts: readonly WorkflowNodeAttempt[],
|
|
291
|
+
): WorkflowNodeExecution {
|
|
292
|
+
return {
|
|
293
|
+
nodeId: row.node_id,
|
|
294
|
+
status: row.status,
|
|
295
|
+
latestAttempt: integer(row.latest_attempt, 'latest_attempt'),
|
|
296
|
+
selectedOutcomePort: row.selected_outcome_port,
|
|
297
|
+
nextAttemptAt: optionalInteger(row.next_attempt_at, 'next_attempt_at'),
|
|
298
|
+
readyAt: optionalInteger(row.ready_at, 'ready_at'),
|
|
299
|
+
startedAt: optionalInteger(row.started_at, 'started_at'),
|
|
300
|
+
settledAt: optionalInteger(row.settled_at, 'settled_at'),
|
|
301
|
+
attempts,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function edgeFromRow(row: EdgeRow): WorkflowEdgeTransfer {
|
|
306
|
+
return {
|
|
307
|
+
edgeId: row.edge_id,
|
|
308
|
+
sourceNodeId: row.source_node_id,
|
|
309
|
+
sourcePort: row.source_port,
|
|
310
|
+
sourceAttempt: optionalInteger(row.source_attempt, 'source_attempt'),
|
|
311
|
+
targetNodeId: row.target_node_id,
|
|
312
|
+
targetPort: row.target_port,
|
|
313
|
+
state: row.state,
|
|
314
|
+
reason: row.reason,
|
|
315
|
+
evidence: parse<WorkflowPayloadEvidenceV1>(row.evidence_json),
|
|
316
|
+
settledAt: integer(row.settled_at, 'settled_at'),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
256
320
|
function runFromRow(row: RunRow): WorkflowRunRecord {
|
|
257
|
-
const queuedAt = integer(row.queued_at);
|
|
258
|
-
const completedAt = optionalInteger(row.completed_at);
|
|
321
|
+
const queuedAt = integer(row.queued_at, 'queued_at');
|
|
322
|
+
const completedAt = optionalInteger(row.completed_at, 'completed_at');
|
|
259
323
|
return {
|
|
260
324
|
id: row.id,
|
|
261
325
|
tenantId: row.tenant_id,
|
|
262
326
|
workflowId: row.workflow_id,
|
|
263
327
|
workflowKey: row.workflow_key,
|
|
264
328
|
workflowName: row.workflow_name,
|
|
265
|
-
workflowRevision: optionalInteger(
|
|
329
|
+
workflowRevision: optionalInteger(
|
|
330
|
+
row.workflow_revision,
|
|
331
|
+
'workflow_revision',
|
|
332
|
+
),
|
|
266
333
|
graphChecksum: row.graph_checksum,
|
|
267
334
|
graph: parse<WorkflowGraphV1>(row.graph_json),
|
|
268
335
|
compiledOrder: parse<readonly string[]>(row.compiled_order_json),
|
|
@@ -280,24 +347,27 @@ function runFromRow(row: RunRow): WorkflowRunRecord {
|
|
|
280
347
|
inputPayloadId: row.input_payload_id,
|
|
281
348
|
idempotencyKey: row.idempotency_key,
|
|
282
349
|
leaseOwner: row.lease_owner,
|
|
283
|
-
leaseExpiresAt: optionalInteger(row.lease_expires_at),
|
|
284
|
-
completedNodes: integer(row.completed_nodes),
|
|
285
|
-
totalNodes: integer(row.total_nodes),
|
|
350
|
+
leaseExpiresAt: optionalInteger(row.lease_expires_at, 'lease_expires_at'),
|
|
351
|
+
completedNodes: integer(row.completed_nodes, 'completed_nodes'),
|
|
352
|
+
totalNodes: integer(row.total_nodes, 'total_nodes'),
|
|
286
353
|
usage: parse<WorkflowUsageRollupV1>(row.usage_json),
|
|
287
354
|
cost: parse<WorkflowCostRollupV1>(row.cost_json),
|
|
288
355
|
failureCode: row.failure_code,
|
|
289
356
|
queuedAt,
|
|
290
|
-
startedAt: optionalInteger(row.started_at),
|
|
357
|
+
startedAt: optionalInteger(row.started_at, 'started_at'),
|
|
291
358
|
completedAt,
|
|
292
359
|
durationMs: completedAt === null ? null : completedAt - queuedAt,
|
|
293
|
-
cancellationRequestedAt: optionalInteger(
|
|
360
|
+
cancellationRequestedAt: optionalInteger(
|
|
361
|
+
row.cancellation_requested_at,
|
|
362
|
+
'cancellation_requested_at',
|
|
363
|
+
),
|
|
294
364
|
};
|
|
295
365
|
}
|
|
296
366
|
|
|
297
367
|
function attemptFromRow(row: AttemptRow): WorkflowNodeAttempt {
|
|
298
368
|
return {
|
|
299
369
|
nodeId: row.node_id,
|
|
300
|
-
attempt: integer(row.attempt),
|
|
370
|
+
attempt: integer(row.attempt, 'attempt'),
|
|
301
371
|
nodeType: row.node_type,
|
|
302
372
|
status: row.status,
|
|
303
373
|
outcomePort: row.outcome_port,
|
|
@@ -309,27 +379,34 @@ function attemptFromRow(row: AttemptRow): WorkflowNodeAttempt {
|
|
|
309
379
|
childId: row.child_id,
|
|
310
380
|
childObservationDeadlineAt: optionalInteger(
|
|
311
381
|
row.child_observation_deadline_at,
|
|
382
|
+
'child_observation_deadline_at',
|
|
312
383
|
),
|
|
313
384
|
failureCode: row.failure_code,
|
|
314
385
|
retryClassification: row.retry_classification,
|
|
315
|
-
selectedBackoffMs: optionalInteger(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
386
|
+
selectedBackoffMs: optionalInteger(
|
|
387
|
+
row.selected_backoff_ms,
|
|
388
|
+
'selected_backoff_ms',
|
|
389
|
+
),
|
|
390
|
+
nextAttemptAt: optionalInteger(row.next_attempt_at, 'next_attempt_at'),
|
|
391
|
+
startedAt: integer(row.started_at, 'started_at'),
|
|
392
|
+
completedAt: optionalInteger(row.completed_at, 'completed_at'),
|
|
393
|
+
durationMs: optionalInteger(row.duration_ms, 'duration_ms'),
|
|
320
394
|
};
|
|
321
395
|
}
|
|
322
396
|
|
|
323
397
|
function eventFromRow(row: EventRow): WorkflowRunEventV1 {
|
|
324
|
-
const virtualOffsetMs = optionalInteger(
|
|
398
|
+
const virtualOffsetMs = optionalInteger(
|
|
399
|
+
row.virtual_offset_ms,
|
|
400
|
+
'virtual_offset_ms',
|
|
401
|
+
);
|
|
325
402
|
return {
|
|
326
403
|
eventId: row.event_id,
|
|
327
404
|
schemaVersion: 1,
|
|
328
405
|
tenantId: row.tenant_id,
|
|
329
406
|
runId: row.run_id,
|
|
330
|
-
sequence: integer(row.sequence),
|
|
407
|
+
sequence: integer(row.sequence, 'sequence'),
|
|
331
408
|
type: row.event_type,
|
|
332
|
-
recordedAt: integer(row.recorded_at),
|
|
409
|
+
recordedAt: integer(row.recorded_at, 'recorded_at'),
|
|
333
410
|
...(virtualOffsetMs === null ? {} : { virtualOffsetMs }),
|
|
334
411
|
payload: parse<Readonly<Record<string, JsonValue>>>(row.payload_json),
|
|
335
412
|
};
|
|
@@ -337,14 +414,14 @@ function eventFromRow(row: EventRow): WorkflowRunEventV1 {
|
|
|
337
414
|
|
|
338
415
|
function auditFromRow(row: AuditRow): WorkflowAuditEvent {
|
|
339
416
|
return {
|
|
340
|
-
sequence: integer(row.sequence),
|
|
417
|
+
sequence: integer(row.sequence, 'sequence'),
|
|
341
418
|
actor: parse<Actor>(row.actor_json),
|
|
342
419
|
origin: parse<WorkflowExecutionOrigin>(row.origin_json),
|
|
343
420
|
action: row.action,
|
|
344
421
|
subjectType: row.subject_type,
|
|
345
422
|
subjectId: row.subject_id,
|
|
346
423
|
metadata: parse<Readonly<Record<string, JsonValue>>>(row.metadata_json),
|
|
347
|
-
occurredAt: integer(row.occurred_at),
|
|
424
|
+
occurredAt: integer(row.occurred_at, 'occurred_at'),
|
|
348
425
|
previousHash: row.previous_hash,
|
|
349
426
|
eventHash: row.event_hash,
|
|
350
427
|
};
|
|
@@ -373,6 +450,64 @@ function jsonKind(column: string): string {
|
|
|
373
450
|
return `${column}::jsonb ->> 'kind'`;
|
|
374
451
|
}
|
|
375
452
|
|
|
453
|
+
/* A search term is matched as a substring, so the three characters LIKE reads
|
|
454
|
+
as syntax are escaped with PostgreSQL's default escape character. */
|
|
455
|
+
function likePattern(term: string): string {
|
|
456
|
+
return '%' + term.replace(/[\\%_]/g, (character) => '\\' + character) + '%';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const ORDER: Readonly<Record<WorkflowSortDirection, 'ASC' | 'DESC'>> = {
|
|
460
|
+
asc: 'ASC',
|
|
461
|
+
desc: 'DESC',
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
/* The direction reaches the statement text, so anything but the two words the
|
|
465
|
+
type allows is refused before it is interpolated. */
|
|
466
|
+
function orderDirection(direction: WorkflowSortDirection): 'ASC' | 'DESC' {
|
|
467
|
+
const order = ORDER[direction];
|
|
468
|
+
if (!order) throw new Error('A list direction is asc or desc.');
|
|
469
|
+
return order;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** Numbered parameters for a statement assembled from optional predicates. */
|
|
473
|
+
function binder() {
|
|
474
|
+
const parameters: Array<string | number> = [];
|
|
475
|
+
return {
|
|
476
|
+
parameters,
|
|
477
|
+
bind(value: string | number): string {
|
|
478
|
+
parameters.push(value);
|
|
479
|
+
return `$${parameters.length}`;
|
|
480
|
+
},
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* The person behind a run, in the order migration 0008 backfilled the column:
|
|
486
|
+
* the account a service actor was configured by, then the delegated
|
|
487
|
+
* authorization subject, then the actor itself. It must stay that order, or a
|
|
488
|
+
* run written now would answer an erasure differently from one backfilled.
|
|
489
|
+
*/
|
|
490
|
+
function subjectAccountId(
|
|
491
|
+
actor: Actor,
|
|
492
|
+
authorizationSubject: UserActor | null,
|
|
493
|
+
): string {
|
|
494
|
+
if (actor.kind === 'service') return actor.configuredBy.id;
|
|
495
|
+
return authorizationSubject?.id ?? actor.id;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** Appends into the bucket `key` names, creating it on first use. */
|
|
499
|
+
function bucketed<T>(map: Map<string, T[]>, key: string, value: T): void {
|
|
500
|
+
const bucket = map.get(key);
|
|
501
|
+
if (bucket) bucket.push(value);
|
|
502
|
+
else map.set(key, [value]);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/* One node of one run. A run id is a UUID and a node id is a dotted
|
|
506
|
+
identifier, so neither can hold the separator and two pairs never collide. */
|
|
507
|
+
function nodeKey(runId: string, nodeId: string): string {
|
|
508
|
+
return `${runId} ${nodeId}`;
|
|
509
|
+
}
|
|
510
|
+
|
|
376
511
|
/* Marks a stored evidence document expired without touching its hash or
|
|
377
512
|
byte size, so the audit of what was there survives the redaction. */
|
|
378
513
|
function expire(column: string): string {
|
|
@@ -397,8 +532,6 @@ const SQL = Object.freeze({
|
|
|
397
532
|
(id, tenant_id, run_id, kind, schema_id, payload_hash,
|
|
398
533
|
original_byte_size, ciphertext, encryption_key_id, created_at)
|
|
399
534
|
VALUES ($1, $2, $3, 'execution', $4, $5, $6, $7, $8, $9)`,
|
|
400
|
-
listDefinitions: `SELECT * FROM workflow_definitions WHERE tenant_id = $1
|
|
401
|
-
ORDER BY lower(name), id`,
|
|
402
535
|
findDefinition: `SELECT * FROM workflow_definitions
|
|
403
536
|
WHERE tenant_id = $1 AND id = $2`,
|
|
404
537
|
findDefinitionByKey: `SELECT * FROM workflow_definitions
|
|
@@ -445,13 +578,13 @@ const SQL = Object.freeze({
|
|
|
445
578
|
(id, tenant_id, workflow_id, workflow_key, workflow_name,
|
|
446
579
|
workflow_revision, graph_checksum, compiler_version, graph_json,
|
|
447
580
|
compiled_order_json, mode, status, actor_json, authorization_subject_json, origin_json,
|
|
448
|
-
permission_snapshot_json, permission_digest, input_hash,
|
|
581
|
+
subject_account_id, permission_snapshot_json, permission_digest, input_hash,
|
|
449
582
|
input_payload_id, input_evidence_json, output_evidence_json,
|
|
450
583
|
idempotency_key, limits_json, lease_owner, lease_expires_at,
|
|
451
584
|
completed_nodes, total_nodes, usage_json, cost_json, failure_code,
|
|
452
585
|
queued_at, started_at, completed_at, cancellation_requested_at)
|
|
453
586
|
VALUES ($1, $2, $3, $4, $5, $6, $7, 1, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19,
|
|
454
|
-
NULL, $
|
|
587
|
+
$20, NULL, $21, $22, NULL, NULL, 0, $23, $24, $25, NULL, $26, NULL, NULL, NULL)`,
|
|
455
588
|
insertNodeState: `INSERT INTO workflow_node_states
|
|
456
589
|
(tenant_id, run_id, node_id, status, latest_attempt)
|
|
457
590
|
VALUES ($1, $2, $3, 'pending', 0)`,
|
|
@@ -469,6 +602,11 @@ const SQL = Object.freeze({
|
|
|
469
602
|
SELECT 1 FROM workflow_node_states n
|
|
470
603
|
WHERE n.tenant_id = workflow_runs.tenant_id AND n.run_id = workflow_runs.id
|
|
471
604
|
AND n.status = 'waiting-retry' AND n.next_attempt_at <= $3
|
|
605
|
+
))
|
|
606
|
+
OR (status = 'waiting-approval' AND (lease_expires_at IS NULL OR lease_expires_at <= $6) AND EXISTS (
|
|
607
|
+
SELECT 1 FROM workflow_node_states n
|
|
608
|
+
WHERE n.tenant_id = workflow_runs.tenant_id AND n.run_id = workflow_runs.id
|
|
609
|
+
AND n.status = 'waiting-child' AND n.next_attempt_at <= $7
|
|
472
610
|
))
|
|
473
611
|
OR (status = 'cancel-requested' AND (lease_expires_at IS NULL OR lease_expires_at <= $4))
|
|
474
612
|
)
|
|
@@ -492,8 +630,11 @@ const SQL = Object.freeze({
|
|
|
492
630
|
semantic_group, side_effect_idempotency_key, input_payload_id,
|
|
493
631
|
input_evidence_json, output_evidence_json, started_at)
|
|
494
632
|
VALUES ($1, $2, $3, $4, $5, 'running', $6, $7, $8, $9, $10, $11)`,
|
|
633
|
+
/* The recheck a retry armed has fired by the time the attempt starts.
|
|
634
|
+
Leaving it set would keep the node matching the claim poll's due-work
|
|
635
|
+
predicate, which reads this column for every waiting state. */
|
|
495
636
|
startNodeState: `UPDATE workflow_node_states
|
|
496
|
-
SET status = 'running', latest_attempt = $1,
|
|
637
|
+
SET status = 'running', latest_attempt = $1, next_attempt_at = NULL,
|
|
497
638
|
ready_at = coalesce(ready_at, $2), started_at = coalesce(started_at, $3)
|
|
498
639
|
WHERE tenant_id = $4 AND run_id = $5 AND node_id = $6`,
|
|
499
640
|
markAttemptWaitingChild: `UPDATE workflow_node_attempts
|
|
@@ -501,10 +642,29 @@ const SQL = Object.freeze({
|
|
|
501
642
|
child_observation_deadline_at = $3
|
|
502
643
|
WHERE tenant_id = $4 AND run_id = $5 AND node_id = $6 AND attempt = $7
|
|
503
644
|
AND status = 'running'`,
|
|
504
|
-
|
|
645
|
+
/* An agent or an action child is polled while the run stays claimable on its
|
|
646
|
+
own status, so such a node arms no recheck: only an approval does, and it
|
|
647
|
+
arms it right after this. */
|
|
648
|
+
markNodeWaitingChild: `UPDATE workflow_node_states
|
|
649
|
+
SET status = 'waiting-child', next_attempt_at = NULL
|
|
505
650
|
WHERE tenant_id = $1 AND run_id = $2 AND node_id = $3`,
|
|
506
651
|
markRunWaitingAgent: `UPDATE workflow_runs SET status = 'waiting-agent'
|
|
507
652
|
WHERE tenant_id = $1 AND id = $2 AND status = 'running'`,
|
|
653
|
+
markRunWaitingApproval: `UPDATE workflow_runs SET status = 'waiting-approval'
|
|
654
|
+
WHERE tenant_id = $1 AND id = $2 AND status IN ('running', 'waiting-approval')`,
|
|
655
|
+
armNodeRecheck: `UPDATE workflow_node_states SET next_attempt_at = $1
|
|
656
|
+
WHERE tenant_id = $2 AND run_id = $3 AND node_id = $4
|
|
657
|
+
AND status = 'waiting-child'`,
|
|
658
|
+
wakeApprovalRun: `UPDATE workflow_node_states SET next_attempt_at = $1
|
|
659
|
+
FROM workflow_node_attempts a
|
|
660
|
+
WHERE workflow_node_states.tenant_id = $2
|
|
661
|
+
AND workflow_node_states.run_id = $3
|
|
662
|
+
AND workflow_node_states.status = 'waiting-child'
|
|
663
|
+
AND a.tenant_id = workflow_node_states.tenant_id
|
|
664
|
+
AND a.run_id = workflow_node_states.run_id
|
|
665
|
+
AND a.node_id = workflow_node_states.node_id
|
|
666
|
+
AND a.attempt = workflow_node_states.latest_attempt
|
|
667
|
+
AND a.child_kind = 'approval' AND a.child_id = $4`,
|
|
508
668
|
getAttempt: `SELECT * FROM workflow_node_attempts
|
|
509
669
|
WHERE tenant_id = $1 AND run_id = $2 AND node_id = $3 AND attempt = $4`,
|
|
510
670
|
settleAttempt: `UPDATE workflow_node_attempts
|
|
@@ -562,17 +722,17 @@ const SQL = Object.freeze({
|
|
|
562
722
|
target_node_id, target_port, state, reason, evidence_json, settled_at
|
|
563
723
|
FROM workflow_edge_transfers WHERE tenant_id = $1 AND run_id = $2
|
|
564
724
|
ORDER BY edge_id`,
|
|
565
|
-
listAudit: `SELECT sequence, actor_json, origin_json, action, subject_type,
|
|
566
|
-
subject_id, metadata_json, occurred_at, previous_hash, event_hash
|
|
567
|
-
FROM workflow_audit_events WHERE tenant_id = $1
|
|
568
|
-
ORDER BY sequence DESC LIMIT $2`,
|
|
569
|
-
listAuditBefore: `SELECT sequence, actor_json, origin_json, action, subject_type,
|
|
570
|
-
subject_id, metadata_json, occurred_at, previous_hash, event_hash
|
|
571
|
-
FROM workflow_audit_events WHERE tenant_id = $1 AND sequence < $2
|
|
572
|
-
ORDER BY sequence DESC LIMIT $3`,
|
|
573
725
|
auditChain: `SELECT sequence, actor_json, origin_json, action, subject_type,
|
|
574
726
|
subject_id, metadata_json, occurred_at, previous_hash, event_hash
|
|
575
727
|
FROM workflow_audit_events WHERE tenant_id = $1 ORDER BY sequence`,
|
|
728
|
+
/* Chain order, which is the primary key's own order, so the export walk is
|
|
729
|
+
an index range scan and an event appended during it lands ahead of the
|
|
730
|
+
cursor rather than being visited twice. */
|
|
731
|
+
exportAuditEventsPage: `SELECT sequence, actor_json, origin_json, action,
|
|
732
|
+
subject_type, subject_id, metadata_json, occurred_at, previous_hash,
|
|
733
|
+
event_hash FROM workflow_audit_events
|
|
734
|
+
WHERE tenant_id = $1 AND sequence > $2
|
|
735
|
+
ORDER BY sequence LIMIT $3`,
|
|
576
736
|
/* Cross-tenant, routing columns only: the retention writes that follow
|
|
577
737
|
run under the tenant each row named. */
|
|
578
738
|
retentionCandidates: `SELECT p.id, p.tenant_id, p.run_id, p.payload_hash
|
|
@@ -597,6 +757,77 @@ const SQL = Object.freeze({
|
|
|
597
757
|
CASE WHEN output_evidence_json IS NULL THEN NULL ELSE ${expire('output_evidence_json')} END
|
|
598
758
|
WHERE tenant_id = $1 AND id = $2`,
|
|
599
759
|
countRuns: `SELECT count(*) AS count FROM workflow_runs WHERE tenant_id = $1`,
|
|
760
|
+
/* The order workflow_runs_tenant_queue_idx already carries, so the export
|
|
761
|
+
walk is an index range scan and a run queued during it lands ahead of the
|
|
762
|
+
cursor rather than being visited twice. */
|
|
763
|
+
exportRunsPage: `SELECT * FROM workflow_runs WHERE tenant_id = $1
|
|
764
|
+
ORDER BY queued_at DESC, id DESC LIMIT $2`,
|
|
765
|
+
exportRunsPageAfter: `SELECT * FROM workflow_runs WHERE tenant_id = $1
|
|
766
|
+
AND (queued_at < $2 OR (queued_at = $3 AND id < $4))
|
|
767
|
+
ORDER BY queued_at DESC, id DESC LIMIT $5`,
|
|
768
|
+
exportNodeStates: `SELECT run_id, node_id, status, latest_attempt,
|
|
769
|
+
selected_outcome_port, next_attempt_at, ready_at, started_at, settled_at
|
|
770
|
+
FROM workflow_node_states
|
|
771
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])
|
|
772
|
+
ORDER BY run_id, node_id`,
|
|
773
|
+
exportAttempts: `SELECT run_id, node_id, attempt, node_type, status,
|
|
774
|
+
outcome_port, semantic_group, side_effect_idempotency_key,
|
|
775
|
+
input_evidence_json, output_evidence_json, child_kind, child_id,
|
|
776
|
+
child_observation_deadline_at, failure_code, retry_classification,
|
|
777
|
+
selected_backoff_ms, next_attempt_at, started_at, completed_at,
|
|
778
|
+
duration_ms FROM workflow_node_attempts
|
|
779
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])
|
|
780
|
+
ORDER BY run_id, node_id, attempt`,
|
|
781
|
+
exportEdges: `SELECT run_id, edge_id, source_node_id, source_port,
|
|
782
|
+
source_attempt, target_node_id, target_port, state, reason,
|
|
783
|
+
evidence_json, settled_at FROM workflow_edge_transfers
|
|
784
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])
|
|
785
|
+
ORDER BY run_id, edge_id`,
|
|
786
|
+
/* The inner select applies the batch limit; the child rows of the runs it
|
|
787
|
+
names are removed with them in the same transaction. */
|
|
788
|
+
settledRunsBefore: `SELECT id FROM workflow_runs
|
|
789
|
+
WHERE tenant_id = $1 AND completed_at < $2
|
|
790
|
+
AND status IN ('succeeded', 'failed', 'refused', 'cancelled')
|
|
791
|
+
ORDER BY completed_at LIMIT $3`,
|
|
792
|
+
/* One plain equality on the column 0008 resolves at write time, which is
|
|
793
|
+
what makes an erasure an index range scan on the connection it runs on.
|
|
794
|
+
Reading the person out of the actor document instead cannot use an index
|
|
795
|
+
there: the jsonb extraction is not leakproof, so the forced row level
|
|
796
|
+
security policy is applied first and the comparison stays a filter. */
|
|
797
|
+
runsOfSubject: `SELECT id FROM workflow_runs
|
|
798
|
+
WHERE tenant_id = $1 AND subject_account_id = $2
|
|
799
|
+
ORDER BY id LIMIT $3`,
|
|
800
|
+
deleteRunNodeStates: `DELETE FROM workflow_node_states
|
|
801
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])`,
|
|
802
|
+
deleteRunAttempts: `DELETE FROM workflow_node_attempts
|
|
803
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])`,
|
|
804
|
+
deleteRunEdges: `DELETE FROM workflow_edge_transfers
|
|
805
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])`,
|
|
806
|
+
deleteRunEvents: `DELETE FROM workflow_run_events
|
|
807
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])`,
|
|
808
|
+
deleteRunPayloads: `DELETE FROM workflow_payloads
|
|
809
|
+
WHERE tenant_id = $1 AND run_id = ANY($2::text[])`,
|
|
810
|
+
deleteRunRows: `DELETE FROM workflow_runs
|
|
811
|
+
WHERE tenant_id = $1 AND id = ANY($2::text[])`,
|
|
812
|
+
exportPublishedDefinitions: `SELECT d.*, r.id AS revision_id,
|
|
813
|
+
r.workflow_id AS revision_workflow_id, r.revision AS revision_number,
|
|
814
|
+
r.graph_json, r.graph_checksum, r.compiler_version,
|
|
815
|
+
r.compiled_order_json, r.published_at, r.published_actor_json
|
|
816
|
+
FROM workflow_definitions d
|
|
817
|
+
JOIN workflow_revisions r ON r.tenant_id = d.tenant_id
|
|
818
|
+
AND r.workflow_id = d.id AND r.revision = d.published_revision
|
|
819
|
+
WHERE d.tenant_id = $1 AND d.published_revision IS NOT NULL
|
|
820
|
+
ORDER BY d.name, d.id LIMIT $2`,
|
|
821
|
+
exportPublishedDefinitionsAfter: `SELECT d.*, r.id AS revision_id,
|
|
822
|
+
r.workflow_id AS revision_workflow_id, r.revision AS revision_number,
|
|
823
|
+
r.graph_json, r.graph_checksum, r.compiler_version,
|
|
824
|
+
r.compiled_order_json, r.published_at, r.published_actor_json
|
|
825
|
+
FROM workflow_definitions d
|
|
826
|
+
JOIN workflow_revisions r ON r.tenant_id = d.tenant_id
|
|
827
|
+
AND r.workflow_id = d.id AND r.revision = d.published_revision
|
|
828
|
+
WHERE d.tenant_id = $1 AND d.published_revision IS NOT NULL
|
|
829
|
+
AND (d.name > $2 OR (d.name = $3 AND d.id > $4))
|
|
830
|
+
ORDER BY d.name, d.id LIMIT $5`,
|
|
600
831
|
});
|
|
601
832
|
|
|
602
833
|
export async function migrateWorkflowsDatabase(
|
|
@@ -685,7 +916,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
685
916
|
)
|
|
686
917
|
)[0];
|
|
687
918
|
const base = {
|
|
688
|
-
sequence: (previous ? integer(previous.sequence) : 0) + 1,
|
|
919
|
+
sequence: (previous ? integer(previous.sequence, 'sequence') : 0) + 1,
|
|
689
920
|
actor,
|
|
690
921
|
origin,
|
|
691
922
|
action,
|
|
@@ -728,7 +959,8 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
728
959
|
[tenantId, runId],
|
|
729
960
|
)
|
|
730
961
|
)[0];
|
|
731
|
-
const sequence =
|
|
962
|
+
const sequence =
|
|
963
|
+
(optionalInteger(previous?.sequence ?? null, 'sequence') ?? 0) + 1;
|
|
732
964
|
if (sequence > WORKFLOW_LIMITS.maxRunEvents) {
|
|
733
965
|
throw new Error('WORKFLOW_LIMIT_EXCEEDED');
|
|
734
966
|
}
|
|
@@ -853,16 +1085,54 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
853
1085
|
]);
|
|
854
1086
|
}
|
|
855
1087
|
|
|
1088
|
+
/* The name order is lower(name), which 0009 indexes as an expression. The
|
|
1089
|
+
keyset predicate compares plain columns, so the subquery names that
|
|
1090
|
+
expression once and the planner folds it back onto the index. */
|
|
856
1091
|
async listDefinitions(
|
|
857
1092
|
tenantId: string,
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
1093
|
+
read: WorkflowDefinitionListRead,
|
|
1094
|
+
): Promise<WorkflowKeysetPage<WorkflowDefinition>> {
|
|
1095
|
+
const { parameters, bind } = binder();
|
|
1096
|
+
const clauses = [`tenant_id = ${bind(tenantId)}`];
|
|
1097
|
+
if (read.status) clauses.push(`status = ${bind(read.status)}`);
|
|
1098
|
+
if (read.search) {
|
|
1099
|
+
const pattern = bind(likePattern(read.search));
|
|
1100
|
+
clauses.push(`(name ILIKE ${pattern} OR workflow_key ILIKE ${pattern})`);
|
|
1101
|
+
}
|
|
1102
|
+
const sortColumn = read.sort === 'name' ? 'sort_name' : 'updated_at';
|
|
1103
|
+
const order = orderDirection(read.direction);
|
|
1104
|
+
let text = `SELECT * FROM (SELECT *, lower(name) AS sort_name
|
|
1105
|
+
FROM workflow_definitions WHERE ${clauses.join(' AND ')}) d`;
|
|
1106
|
+
if (read.after) {
|
|
1107
|
+
const keyset = keysetWhere(
|
|
1108
|
+
[sortColumn, 'id'],
|
|
1109
|
+
[read.after.key, read.after.id],
|
|
1110
|
+
{ direction: read.direction, parameterOffset: parameters.length },
|
|
1111
|
+
);
|
|
1112
|
+
text += ` WHERE ${keyset.text}`;
|
|
1113
|
+
parameters.push(...keyset.parameters);
|
|
1114
|
+
}
|
|
1115
|
+
text += ` ORDER BY ${sortColumn} ${order}, id ${order} LIMIT ${bind(read.limit)}`;
|
|
1116
|
+
const rows = await this.#tx(tenantId, 'read', (transaction) =>
|
|
1117
|
+
this.#query<DefinitionRow & { sort_name: string }>(
|
|
1118
|
+
transaction,
|
|
1119
|
+
text,
|
|
1120
|
+
parameters,
|
|
1121
|
+
),
|
|
865
1122
|
);
|
|
1123
|
+
const last = rows.at(-1);
|
|
1124
|
+
return {
|
|
1125
|
+
items: rows.map(definitionFromRow),
|
|
1126
|
+
last: last
|
|
1127
|
+
? {
|
|
1128
|
+
key:
|
|
1129
|
+
read.sort === 'name'
|
|
1130
|
+
? last.sort_name
|
|
1131
|
+
: integer(last.updated_at, 'updated_at'),
|
|
1132
|
+
id: last.id,
|
|
1133
|
+
}
|
|
1134
|
+
: null,
|
|
1135
|
+
};
|
|
866
1136
|
}
|
|
867
1137
|
|
|
868
1138
|
async findDefinition(
|
|
@@ -1093,7 +1363,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1093
1363
|
)[0];
|
|
1094
1364
|
if (
|
|
1095
1365
|
definition.publishedRevision !== null ||
|
|
1096
|
-
integer(runs?.count ?? 0) > 0
|
|
1366
|
+
integer(runs?.count ?? 0, 'count') > 0
|
|
1097
1367
|
) {
|
|
1098
1368
|
return 'in-use';
|
|
1099
1369
|
}
|
|
@@ -1136,7 +1406,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1136
1406
|
id: row.id,
|
|
1137
1407
|
key: row.workflow_key,
|
|
1138
1408
|
name: row.name,
|
|
1139
|
-
revision: integer(row.published_revision),
|
|
1409
|
+
revision: integer(row.published_revision, 'published_revision'),
|
|
1140
1410
|
graphChecksum: row.graph_checksum,
|
|
1141
1411
|
})),
|
|
1142
1412
|
);
|
|
@@ -1168,6 +1438,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1168
1438
|
JSON.stringify(run.actor),
|
|
1169
1439
|
JSON.stringify(run.authorizationSubject),
|
|
1170
1440
|
JSON.stringify(run.origin),
|
|
1441
|
+
subjectAccountId(run.actor, run.authorizationSubject),
|
|
1171
1442
|
JSON.stringify(run.permissionSnapshot),
|
|
1172
1443
|
run.permissionDigest,
|
|
1173
1444
|
run.inputHash,
|
|
@@ -1247,72 +1518,48 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1247
1518
|
|
|
1248
1519
|
async listRuns(
|
|
1249
1520
|
tenantId: string,
|
|
1250
|
-
|
|
1251
|
-
): Promise<
|
|
1252
|
-
const
|
|
1253
|
-
Math.max(1, Math.trunc(filters.limit ?? 50)),
|
|
1254
|
-
WORKFLOW_LIMITS.maxInteractivePage,
|
|
1255
|
-
);
|
|
1256
|
-
const parameters: Array<string | number> = [];
|
|
1257
|
-
const bind = (value: string | number) => {
|
|
1258
|
-
parameters.push(value);
|
|
1259
|
-
return `$${parameters.length}`;
|
|
1260
|
-
};
|
|
1521
|
+
read: WorkflowRunListRead,
|
|
1522
|
+
): Promise<WorkflowKeysetPage<WorkflowRunSummary>> {
|
|
1523
|
+
const { parameters, bind } = binder();
|
|
1261
1524
|
const clauses = [`tenant_id = ${bind(tenantId)}`];
|
|
1262
|
-
if (
|
|
1263
|
-
clauses.push(`workflow_id = ${bind(
|
|
1525
|
+
if (read.workflowId) {
|
|
1526
|
+
clauses.push(`workflow_id = ${bind(read.workflowId)}`);
|
|
1264
1527
|
}
|
|
1265
|
-
if (
|
|
1266
|
-
if (
|
|
1267
|
-
if (
|
|
1268
|
-
clauses.push(`${jsonKind('actor_json')} = ${bind(
|
|
1528
|
+
if (read.mode) clauses.push(`mode = ${bind(read.mode)}`);
|
|
1529
|
+
if (read.status) clauses.push(`status = ${bind(read.status)}`);
|
|
1530
|
+
if (read.actorKind) {
|
|
1531
|
+
clauses.push(`${jsonKind('actor_json')} = ${bind(read.actorKind)}`);
|
|
1269
1532
|
}
|
|
1270
|
-
if (
|
|
1271
|
-
clauses.push(`${jsonKind('origin_json')} = ${bind(
|
|
1533
|
+
if (read.originKind) {
|
|
1534
|
+
clauses.push(`${jsonKind('origin_json')} = ${bind(read.originKind)}`);
|
|
1272
1535
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (filters.cursor) {
|
|
1276
|
-
const [snapshotRaw, positionRaw, extra] = filters.cursor.split('|');
|
|
1277
|
-
const parseBoundary = (raw: string | undefined) => {
|
|
1278
|
-
const separator = raw?.indexOf(':') ?? -1;
|
|
1279
|
-
const queuedAt = Number(raw?.slice(0, separator));
|
|
1280
|
-
const id = raw?.slice(separator + 1) ?? '';
|
|
1281
|
-
if (separator < 1 || !Number.isSafeInteger(queuedAt) || !id) {
|
|
1282
|
-
throw new Error('WORKFLOW_CURSOR_INVALID');
|
|
1283
|
-
}
|
|
1284
|
-
return { queuedAt, id };
|
|
1285
|
-
};
|
|
1286
|
-
if (extra !== undefined) throw new Error('WORKFLOW_CURSOR_INVALID');
|
|
1287
|
-
snapshot = parseBoundary(snapshotRaw);
|
|
1288
|
-
const position = parseBoundary(positionRaw);
|
|
1536
|
+
if (read.search) {
|
|
1537
|
+
const pattern = bind(likePattern(read.search));
|
|
1289
1538
|
clauses.push(
|
|
1290
|
-
`(
|
|
1291
|
-
|
|
1292
|
-
)} AND id <= ${bind(snapshot.id)}))`,
|
|
1539
|
+
`(workflow_name ILIKE ${pattern} OR workflow_key ILIKE ${pattern}
|
|
1540
|
+
OR id ILIKE ${pattern} OR actor_json::jsonb ->> 'label' ILIKE ${pattern})`,
|
|
1293
1541
|
);
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1542
|
+
}
|
|
1543
|
+
if (read.after) {
|
|
1544
|
+
const keyset = keysetWhere(
|
|
1545
|
+
['queued_at', 'id'],
|
|
1546
|
+
[read.after.key, read.after.id],
|
|
1547
|
+
{ direction: read.direction, parameterOffset: parameters.length },
|
|
1298
1548
|
);
|
|
1549
|
+
clauses.push(keyset.text);
|
|
1550
|
+
parameters.push(...keyset.parameters);
|
|
1299
1551
|
}
|
|
1552
|
+
const order = orderDirection(read.direction);
|
|
1300
1553
|
const text = `SELECT * FROM workflow_runs WHERE ${clauses.join(' AND ')}
|
|
1301
|
-
ORDER BY queued_at
|
|
1554
|
+
ORDER BY queued_at ${order}, id ${order} LIMIT ${bind(read.limit)}`;
|
|
1302
1555
|
const rows = await this.#tx(tenantId, 'read', (transaction) =>
|
|
1303
1556
|
this.#query<RunRow>(transaction, text, parameters),
|
|
1304
1557
|
);
|
|
1305
|
-
const
|
|
1306
|
-
const
|
|
1307
|
-
const last = page.at(-1);
|
|
1308
|
-
const highWaterMark =
|
|
1309
|
-
snapshot ?? (first ? { queuedAt: first.queuedAt, id: first.id } : null);
|
|
1558
|
+
const items = rows.map(runFromRow);
|
|
1559
|
+
const last = items.at(-1);
|
|
1310
1560
|
return {
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
rows.length > limit && last && highWaterMark
|
|
1314
|
-
? `${highWaterMark.queuedAt}:${highWaterMark.id}|${last.queuedAt}:${last.id}`
|
|
1315
|
-
: null,
|
|
1561
|
+
items,
|
|
1562
|
+
last: last ? { key: last.queuedAt, id: last.id } : null,
|
|
1316
1563
|
};
|
|
1317
1564
|
}
|
|
1318
1565
|
|
|
@@ -1412,7 +1659,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1412
1659
|
(transaction) =>
|
|
1413
1660
|
transaction.query<RunRoutingRow>({
|
|
1414
1661
|
text: SQL.claimCandidates,
|
|
1415
|
-
parameters: [now, now, now, now, 20] as never,
|
|
1662
|
+
parameters: [now, now, now, now, 20, now, now] as never,
|
|
1416
1663
|
}),
|
|
1417
1664
|
{ access: 'read' },
|
|
1418
1665
|
)
|
|
@@ -1443,7 +1690,8 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1443
1690
|
)[0];
|
|
1444
1691
|
if (!row) return null;
|
|
1445
1692
|
const leaseExpired =
|
|
1446
|
-
row.lease_expires_at === null ||
|
|
1693
|
+
row.lease_expires_at === null ||
|
|
1694
|
+
integer(row.lease_expires_at, 'lease_expires_at') <= now;
|
|
1447
1695
|
const claimable =
|
|
1448
1696
|
row.mode === 'live' &&
|
|
1449
1697
|
(row.status === 'queued' ||
|
|
@@ -1451,7 +1699,8 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1451
1699
|
row.status,
|
|
1452
1700
|
) &&
|
|
1453
1701
|
leaseExpired) ||
|
|
1454
|
-
(
|
|
1702
|
+
(['waiting-retry', 'waiting-approval'].includes(row.status) &&
|
|
1703
|
+
leaseExpired));
|
|
1455
1704
|
if (!claimable) return null;
|
|
1456
1705
|
const priorLease = row.lease_owner;
|
|
1457
1706
|
const recovering = priorLease !== null && row.status !== 'queued';
|
|
@@ -1459,7 +1708,9 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1459
1708
|
after its node starts would make the new waiting-child projection
|
|
1460
1709
|
unreachable by the next claim. */
|
|
1461
1710
|
const status =
|
|
1462
|
-
row.status === 'queued' ||
|
|
1711
|
+
row.status === 'queued' ||
|
|
1712
|
+
row.status === 'waiting-retry' ||
|
|
1713
|
+
row.status === 'waiting-approval'
|
|
1463
1714
|
? 'running'
|
|
1464
1715
|
: row.status;
|
|
1465
1716
|
const changed = await this.#exec(transaction, SQL.claimRun, [
|
|
@@ -1711,10 +1962,11 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1711
1962
|
runId: string,
|
|
1712
1963
|
nodeId: string,
|
|
1713
1964
|
attempt: number,
|
|
1714
|
-
childKind: 'agent' | 'action',
|
|
1965
|
+
childKind: 'agent' | 'action' | 'approval',
|
|
1715
1966
|
childId: string,
|
|
1716
1967
|
observationDeadlineAt: number,
|
|
1717
1968
|
recordedAt: number,
|
|
1969
|
+
recheckAt?: number,
|
|
1718
1970
|
): Promise<void> {
|
|
1719
1971
|
await this.#tx(tenantId, 'write', async (transaction) => {
|
|
1720
1972
|
const changed = await this.#exec(
|
|
@@ -1742,6 +1994,20 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1742
1994
|
runId,
|
|
1743
1995
|
]);
|
|
1744
1996
|
}
|
|
1997
|
+
/* An approval takes the run out of the claim queue entirely, so the
|
|
1998
|
+
recheck it arms is the only thing that brings it back on its own. */
|
|
1999
|
+
if (childKind === 'approval') {
|
|
2000
|
+
await this.#exec(transaction, SQL.armNodeRecheck, [
|
|
2001
|
+
recheckAt ?? recordedAt,
|
|
2002
|
+
tenantId,
|
|
2003
|
+
runId,
|
|
2004
|
+
nodeId,
|
|
2005
|
+
]);
|
|
2006
|
+
await this.#exec(transaction, SQL.markRunWaitingApproval, [
|
|
2007
|
+
tenantId,
|
|
2008
|
+
runId,
|
|
2009
|
+
]);
|
|
2010
|
+
}
|
|
1745
2011
|
await this.#appendEvent(
|
|
1746
2012
|
transaction,
|
|
1747
2013
|
tenantId,
|
|
@@ -1753,6 +2019,53 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1753
2019
|
});
|
|
1754
2020
|
}
|
|
1755
2021
|
|
|
2022
|
+
/**
|
|
2023
|
+
* Re-arms the wait on an approval the worker found still pending. It records
|
|
2024
|
+
* no event and touches no attempt: the run simply goes back to sleep with a
|
|
2025
|
+
* later recheck than the one that woke it.
|
|
2026
|
+
*/
|
|
2027
|
+
async suspendApproval(
|
|
2028
|
+
tenantId: string,
|
|
2029
|
+
runId: string,
|
|
2030
|
+
nodeId: string,
|
|
2031
|
+
recheckAt: number,
|
|
2032
|
+
): Promise<void> {
|
|
2033
|
+
await this.#tx(tenantId, 'write', async (transaction) => {
|
|
2034
|
+
await this.#exec(transaction, SQL.armNodeRecheck, [
|
|
2035
|
+
recheckAt,
|
|
2036
|
+
tenantId,
|
|
2037
|
+
runId,
|
|
2038
|
+
nodeId,
|
|
2039
|
+
]);
|
|
2040
|
+
await this.#exec(transaction, SQL.markRunWaitingApproval, [
|
|
2041
|
+
tenantId,
|
|
2042
|
+
runId,
|
|
2043
|
+
]);
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
/**
|
|
2048
|
+
* Brings a sleeping run back into the claim queue the moment approvals.core
|
|
2049
|
+
* reports a decision, by making the node's recheck due now. It matches on the
|
|
2050
|
+
* request id, so a callback for a request the run has moved past changes
|
|
2051
|
+
* nothing.
|
|
2052
|
+
*/
|
|
2053
|
+
async wakeApproval(
|
|
2054
|
+
tenantId: string,
|
|
2055
|
+
runId: string,
|
|
2056
|
+
requestId: string,
|
|
2057
|
+
now: number,
|
|
2058
|
+
): Promise<void> {
|
|
2059
|
+
await this.#tx(tenantId, 'write', async (transaction) => {
|
|
2060
|
+
await this.#exec(transaction, SQL.wakeApprovalRun, [
|
|
2061
|
+
now,
|
|
2062
|
+
tenantId,
|
|
2063
|
+
runId,
|
|
2064
|
+
requestId,
|
|
2065
|
+
]);
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
|
|
1756
2069
|
async settleAttempt(
|
|
1757
2070
|
write: SettleAttemptWrite,
|
|
1758
2071
|
actor: Actor,
|
|
@@ -1783,7 +2096,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
1783
2096
|
);
|
|
1784
2097
|
const duration = Math.max(
|
|
1785
2098
|
0,
|
|
1786
|
-
write.recordedAt - integer(prior.started_at),
|
|
2099
|
+
write.recordedAt - integer(prior.started_at, 'started_at'),
|
|
1787
2100
|
);
|
|
1788
2101
|
await this.#exec(transaction, SQL.settleAttempt, [
|
|
1789
2102
|
write.status,
|
|
@@ -2214,19 +2527,14 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
2214
2527
|
SQL.readAttempts,
|
|
2215
2528
|
[tenantId, runId],
|
|
2216
2529
|
);
|
|
2217
|
-
return states.map((state) =>
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
settledAt: optionalInteger(state.settled_at),
|
|
2226
|
-
attempts: attempts
|
|
2227
|
-
.filter((attempt) => attempt.node_id === state.node_id)
|
|
2228
|
-
.map(attemptFromRow),
|
|
2229
|
-
}));
|
|
2530
|
+
return states.map((state) =>
|
|
2531
|
+
nodeExecutionFromRow(
|
|
2532
|
+
state,
|
|
2533
|
+
attempts
|
|
2534
|
+
.filter((attempt) => attempt.node_id === state.node_id)
|
|
2535
|
+
.map(attemptFromRow),
|
|
2536
|
+
),
|
|
2537
|
+
);
|
|
2230
2538
|
});
|
|
2231
2539
|
}
|
|
2232
2540
|
|
|
@@ -2240,46 +2548,50 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
2240
2548
|
tenantId,
|
|
2241
2549
|
runId,
|
|
2242
2550
|
])
|
|
2243
|
-
).map(
|
|
2244
|
-
edgeId: row.edge_id,
|
|
2245
|
-
sourceNodeId: row.source_node_id,
|
|
2246
|
-
sourcePort: row.source_port,
|
|
2247
|
-
sourceAttempt: optionalInteger(row.source_attempt),
|
|
2248
|
-
targetNodeId: row.target_node_id,
|
|
2249
|
-
targetPort: row.target_port,
|
|
2250
|
-
state: row.state,
|
|
2251
|
-
reason: row.reason,
|
|
2252
|
-
evidence: parse<WorkflowPayloadEvidenceV1>(row.evidence_json),
|
|
2253
|
-
settledAt: integer(row.settled_at),
|
|
2254
|
-
})),
|
|
2551
|
+
).map(edgeFromRow),
|
|
2255
2552
|
);
|
|
2256
2553
|
}
|
|
2257
2554
|
|
|
2555
|
+
/* The chain order is the sequence; the time order rides the index 0001 made
|
|
2556
|
+
for it, with the sequence as the tie breaker in both. */
|
|
2258
2557
|
async listAudit(
|
|
2259
2558
|
tenantId: string,
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
const
|
|
2559
|
+
read: WorkflowAuditListRead,
|
|
2560
|
+
): Promise<WorkflowKeysetPage<WorkflowAuditEvent>> {
|
|
2561
|
+
const { parameters, bind } = binder();
|
|
2562
|
+
const clauses = [`tenant_id = ${bind(tenantId)}`];
|
|
2563
|
+
const columns =
|
|
2564
|
+
read.sort === 'sequence' ? ['sequence'] : ['occurred_at', 'sequence'];
|
|
2565
|
+
if (read.after) {
|
|
2566
|
+
const keyset = keysetWhere(
|
|
2567
|
+
columns,
|
|
2568
|
+
read.sort === 'sequence'
|
|
2569
|
+
? [read.after.id]
|
|
2570
|
+
: [read.after.key, read.after.id],
|
|
2571
|
+
{ direction: read.direction, parameterOffset: parameters.length },
|
|
2572
|
+
);
|
|
2573
|
+
clauses.push(keyset.text);
|
|
2574
|
+
parameters.push(...keyset.parameters);
|
|
2575
|
+
}
|
|
2576
|
+
const order = orderDirection(read.direction);
|
|
2577
|
+
const text = `SELECT sequence, actor_json, origin_json, action, subject_type,
|
|
2578
|
+
subject_id, metadata_json, occurred_at, previous_hash, event_hash
|
|
2579
|
+
FROM workflow_audit_events WHERE ${clauses.join(' AND ')}
|
|
2580
|
+
ORDER BY ${columns.map((column) => `${column} ${order}`).join(', ')}
|
|
2581
|
+
LIMIT ${bind(read.limit)}`;
|
|
2264
2582
|
const rows = await this.#tx(tenantId, 'read', (transaction) =>
|
|
2265
|
-
|
|
2266
|
-
? this.#query<AuditRow>(transaction, SQL.listAudit, [
|
|
2267
|
-
tenantId,
|
|
2268
|
-
bounded + 1,
|
|
2269
|
-
])
|
|
2270
|
-
: this.#query<AuditRow>(transaction, SQL.listAuditBefore, [
|
|
2271
|
-
tenantId,
|
|
2272
|
-
beforeSequence,
|
|
2273
|
-
bounded + 1,
|
|
2274
|
-
]),
|
|
2583
|
+
this.#query<AuditRow>(transaction, text, parameters),
|
|
2275
2584
|
);
|
|
2276
|
-
const
|
|
2585
|
+
const items = rows.map(auditFromRow);
|
|
2586
|
+
const last = items.at(-1);
|
|
2277
2587
|
return {
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2588
|
+
items,
|
|
2589
|
+
last: last
|
|
2590
|
+
? {
|
|
2591
|
+
key: read.sort === 'sequence' ? last.sequence : last.occurredAt,
|
|
2592
|
+
id: last.sequence,
|
|
2593
|
+
}
|
|
2594
|
+
: null,
|
|
2283
2595
|
};
|
|
2284
2596
|
}
|
|
2285
2597
|
|
|
@@ -2378,7 +2690,7 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
2378
2690
|
[row.tenant_id, row.run_id],
|
|
2379
2691
|
)
|
|
2380
2692
|
)[0];
|
|
2381
|
-
if (integer(remaining?.count ?? 0) === 0) {
|
|
2693
|
+
if (integer(remaining?.count ?? 0, 'count') === 0) {
|
|
2382
2694
|
await this.#exec(transaction, SQL.expireRunOutputEvidence, [
|
|
2383
2695
|
row.tenant_id,
|
|
2384
2696
|
row.run_id,
|
|
@@ -2400,7 +2712,184 @@ export class DatabaseWorkflowsRepository implements WorkflowsRepository {
|
|
|
2400
2712
|
])
|
|
2401
2713
|
)[0],
|
|
2402
2714
|
);
|
|
2403
|
-
return integer(row?.count ?? 0);
|
|
2715
|
+
return integer(row?.count ?? 0, 'count');
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
/* The operations behind the declared data classes. Each runs on this
|
|
2719
|
+
module's own lease, inside its own tenant-scoped transaction. */
|
|
2720
|
+
|
|
2721
|
+
async exportRunsPage(
|
|
2722
|
+
tenantId: string,
|
|
2723
|
+
after: WorkflowRunExportCursor | null,
|
|
2724
|
+
limit: number,
|
|
2725
|
+
): Promise<readonly ExportedWorkflowRun[]> {
|
|
2726
|
+
return this.#tx(tenantId, 'read', async (transaction) => {
|
|
2727
|
+
const runs =
|
|
2728
|
+
after === null
|
|
2729
|
+
? await this.#query<RunRow>(transaction, SQL.exportRunsPage, [
|
|
2730
|
+
tenantId,
|
|
2731
|
+
limit,
|
|
2732
|
+
])
|
|
2733
|
+
: await this.#query<RunRow>(transaction, SQL.exportRunsPageAfter, [
|
|
2734
|
+
tenantId,
|
|
2735
|
+
after.queuedAt,
|
|
2736
|
+
after.queuedAt,
|
|
2737
|
+
after.id,
|
|
2738
|
+
limit,
|
|
2739
|
+
]);
|
|
2740
|
+
if (runs.length === 0) return [];
|
|
2741
|
+
/* Three queries for the whole page: a run is a row, not four round
|
|
2742
|
+
trips. */
|
|
2743
|
+
const ids = runs.map((run) => run.id);
|
|
2744
|
+
const states = await this.#query<ExportNodeStateRow>(
|
|
2745
|
+
transaction,
|
|
2746
|
+
SQL.exportNodeStates,
|
|
2747
|
+
[tenantId, ids],
|
|
2748
|
+
);
|
|
2749
|
+
const attempts = await this.#query<ExportAttemptRow>(
|
|
2750
|
+
transaction,
|
|
2751
|
+
SQL.exportAttempts,
|
|
2752
|
+
[tenantId, ids],
|
|
2753
|
+
);
|
|
2754
|
+
const edges = await this.#query<ExportEdgeRow>(
|
|
2755
|
+
transaction,
|
|
2756
|
+
SQL.exportEdges,
|
|
2757
|
+
[tenantId, ids],
|
|
2758
|
+
);
|
|
2759
|
+
/* One pass per result set into its buckets, so assembling a page costs
|
|
2760
|
+
O(runs + states + attempts + edges). Scanning each child set once per
|
|
2761
|
+
run is what turns a page of long runs quadratic. Each bucket keeps
|
|
2762
|
+
the order its query returned. */
|
|
2763
|
+
const statesByRun = new Map<string, ExportNodeStateRow[]>();
|
|
2764
|
+
for (const state of states) bucketed(statesByRun, state.run_id, state);
|
|
2765
|
+
const attemptsByNode = new Map<string, ExportAttemptRow[]>();
|
|
2766
|
+
for (const attempt of attempts) {
|
|
2767
|
+
bucketed(
|
|
2768
|
+
attemptsByNode,
|
|
2769
|
+
nodeKey(attempt.run_id, attempt.node_id),
|
|
2770
|
+
attempt,
|
|
2771
|
+
);
|
|
2772
|
+
}
|
|
2773
|
+
const edgesByRun = new Map<string, ExportEdgeRow[]>();
|
|
2774
|
+
for (const edge of edges) bucketed(edgesByRun, edge.run_id, edge);
|
|
2775
|
+
return runs.map((run) => ({
|
|
2776
|
+
run: runFromRow(run),
|
|
2777
|
+
nodes: (statesByRun.get(run.id) ?? []).map((state) =>
|
|
2778
|
+
nodeExecutionFromRow(
|
|
2779
|
+
state,
|
|
2780
|
+
(attemptsByNode.get(nodeKey(run.id, state.node_id)) ?? []).map(
|
|
2781
|
+
attemptFromRow,
|
|
2782
|
+
),
|
|
2783
|
+
),
|
|
2784
|
+
),
|
|
2785
|
+
edges: (edgesByRun.get(run.id) ?? []).map(edgeFromRow),
|
|
2786
|
+
}));
|
|
2787
|
+
});
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
async exportAuditEventsPage(
|
|
2791
|
+
tenantId: string,
|
|
2792
|
+
afterSequence: number,
|
|
2793
|
+
limit: number,
|
|
2794
|
+
): Promise<readonly WorkflowAuditEvent[]> {
|
|
2795
|
+
return this.#tx(tenantId, 'read', async (transaction) =>
|
|
2796
|
+
(
|
|
2797
|
+
await this.#query<AuditRow>(transaction, SQL.exportAuditEventsPage, [
|
|
2798
|
+
tenantId,
|
|
2799
|
+
afterSequence,
|
|
2800
|
+
limit,
|
|
2801
|
+
])
|
|
2802
|
+
).map(auditFromRow),
|
|
2803
|
+
);
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
async deleteRunsSettledBefore(
|
|
2807
|
+
tenantId: string,
|
|
2808
|
+
before: number,
|
|
2809
|
+
limit: number,
|
|
2810
|
+
): Promise<number> {
|
|
2811
|
+
return this.#tx(tenantId, 'write', async (transaction) => {
|
|
2812
|
+
const rows = await this.#query<{ id: string }>(
|
|
2813
|
+
transaction,
|
|
2814
|
+
SQL.settledRunsBefore,
|
|
2815
|
+
[tenantId, before, limit],
|
|
2816
|
+
);
|
|
2817
|
+
return this.#deleteRunsIn(transaction, tenantId, rows);
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
/* A run this removes while a worker holds it takes its lease with it: the
|
|
2822
|
+
next renewal finds no row and the worker stops as it does for any lease
|
|
2823
|
+
it lost. */
|
|
2824
|
+
async deleteRunsOfSubject(
|
|
2825
|
+
tenantId: string,
|
|
2826
|
+
accountId: string,
|
|
2827
|
+
limit: number,
|
|
2828
|
+
): Promise<number> {
|
|
2829
|
+
return this.#tx(tenantId, 'write', async (transaction) => {
|
|
2830
|
+
const rows = await this.#query<{ id: string }>(
|
|
2831
|
+
transaction,
|
|
2832
|
+
SQL.runsOfSubject,
|
|
2833
|
+
[tenantId, accountId, limit],
|
|
2834
|
+
);
|
|
2835
|
+
return this.#deleteRunsIn(transaction, tenantId, rows);
|
|
2836
|
+
});
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
/* No foreign key hangs off a run, so the child rows are named here. A run
|
|
2840
|
+
and its evidence leave in one transaction or not at all. */
|
|
2841
|
+
async #deleteRunsIn(
|
|
2842
|
+
transaction: DatabaseTransaction,
|
|
2843
|
+
tenantId: string,
|
|
2844
|
+
rows: readonly { readonly id: string }[],
|
|
2845
|
+
): Promise<number> {
|
|
2846
|
+
if (rows.length === 0) return 0;
|
|
2847
|
+
const ids = rows.map((row) => row.id);
|
|
2848
|
+
for (const statement of [
|
|
2849
|
+
SQL.deleteRunNodeStates,
|
|
2850
|
+
SQL.deleteRunAttempts,
|
|
2851
|
+
SQL.deleteRunEdges,
|
|
2852
|
+
SQL.deleteRunEvents,
|
|
2853
|
+
SQL.deleteRunPayloads,
|
|
2854
|
+
]) {
|
|
2855
|
+
await this.#exec(transaction, statement, [tenantId, ids]);
|
|
2856
|
+
}
|
|
2857
|
+
return this.#exec(transaction, SQL.deleteRunRows, [tenantId, ids]);
|
|
2858
|
+
}
|
|
2859
|
+
|
|
2860
|
+
async exportPublishedDefinitionsPage(
|
|
2861
|
+
tenantId: string,
|
|
2862
|
+
after: WorkflowDefinitionExportCursor | null,
|
|
2863
|
+
limit: number,
|
|
2864
|
+
): Promise<readonly ExportedWorkflowDefinition[]> {
|
|
2865
|
+
return this.#tx(tenantId, 'read', async (transaction) => {
|
|
2866
|
+
const rows =
|
|
2867
|
+
after === null
|
|
2868
|
+
? await this.#query<ExportDefinitionRow>(
|
|
2869
|
+
transaction,
|
|
2870
|
+
SQL.exportPublishedDefinitions,
|
|
2871
|
+
[tenantId, limit],
|
|
2872
|
+
)
|
|
2873
|
+
: await this.#query<ExportDefinitionRow>(
|
|
2874
|
+
transaction,
|
|
2875
|
+
SQL.exportPublishedDefinitionsAfter,
|
|
2876
|
+
[tenantId, after.name, after.name, after.id, limit],
|
|
2877
|
+
);
|
|
2878
|
+
return rows.map((row) => ({
|
|
2879
|
+
definition: definitionFromRow(row),
|
|
2880
|
+
revision: revisionFromRow({
|
|
2881
|
+
id: row.revision_id,
|
|
2882
|
+
workflow_id: row.revision_workflow_id,
|
|
2883
|
+
revision: row.revision_number,
|
|
2884
|
+
graph_json: row.graph_json,
|
|
2885
|
+
graph_checksum: row.graph_checksum,
|
|
2886
|
+
compiler_version: row.compiler_version,
|
|
2887
|
+
compiled_order_json: row.compiled_order_json,
|
|
2888
|
+
published_at: row.published_at,
|
|
2889
|
+
published_actor_json: row.published_actor_json,
|
|
2890
|
+
}),
|
|
2891
|
+
}));
|
|
2892
|
+
});
|
|
2404
2893
|
}
|
|
2405
2894
|
|
|
2406
2895
|
async close(): Promise<void> {}
|