@flowdular/sdk 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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 +100 -0
- 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/deploy-operate/SKILL.md +114 -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 +3 -2
- 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/README.md +3 -0
- package/modules/approvals/module.json +34 -0
- package/modules/approvals/package.json +43 -0
- package/modules/approvals/spec/module.yaml +318 -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 +95 -0
- package/modules/approvals/src/domain/types.ts +154 -0
- package/modules/approvals/src/index.ts +52 -0
- package/modules/approvals/src/platform.ts +128 -0
- package/modules/approvals/src/server/index.ts +42 -0
- package/modules/approvals/src/server/runtime.ts +181 -0
- package/modules/approvals/src/services/approvals-service.ts +557 -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 +724 -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 +222 -0
- package/modules/approvals/src/services/notifications.ts +95 -0
- package/modules/approvals/src/services/repository.ts +161 -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 +3 -2
- 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 +5 -2
- 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/README.md +3 -0
- package/modules/connectors/module.json +28 -0
- package/modules/{automations-workflows-integration → connectors}/package.json +27 -26
- package/modules/connectors/spec/module.yaml +447 -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/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-vault.ts +188 -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 +166 -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/README.md +3 -0
- package/modules/documents/module.json +28 -0
- package/modules/documents/package.json +49 -0
- package/modules/documents/spec/module.yaml +247 -0
- package/modules/documents/src/acl/permissions.ts +6 -0
- package/modules/documents/src/api/endpoints.ts +401 -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 +259 -0
- package/modules/documents/src/services/documents-service.ts +586 -0
- package/modules/documents/src/services/index.ts +18 -0
- package/modules/documents/src/services/migration.ts +82 -0
- package/modules/documents/src/services/repository.ts +48 -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/README.md +3 -0
- package/modules/exports/module.json +28 -0
- package/modules/exports/package.json +44 -0
- package/modules/exports/spec/module.yaml +229 -0
- package/modules/exports/src/acl/permissions.ts +6 -0
- package/modules/exports/src/api/endpoints.ts +211 -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 +51 -0
- package/modules/exports/src/server/runtime.ts +160 -0
- package/modules/exports/src/services/data-classes.ts +56 -0
- package/modules/exports/src/services/database-repository.ts +405 -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 +89 -0
- package/modules/exports/src/services/repository.ts +97 -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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +5 -2
- 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 +3 -2
- 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 +66 -7
- package/packages/client/package.json +2 -1
- 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 +179 -0
- package/packages/database/src/decoders.ts +25 -0
- package/packages/database/src/index.ts +17 -0
- package/packages/database/src/record-history.ts +5 -14
- package/packages/dev-console/package.json +2 -1
- package/packages/dev-console/src/brand.d.mts +8 -0
- package/packages/dev-console/src/brand.mjs +33 -0
- package/packages/dev-console/src/index.mjs +2 -1
- package/packages/harness/src/index.ts +2 -0
- package/packages/harness/src/runtime.ts +218 -1
- package/packages/harness/src/tool-adapters.ts +19 -1
- package/packages/kernel/src/acl.ts +179 -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 +65 -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 +189 -0
- package/packages/storage/src/index.ts +43 -0
- package/packages/storage/src/local.ts +75 -0
- package/packages/storage/src/port.ts +251 -0
- package/packages/storage/src/read-token.ts +130 -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
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createJobRunner,
|
|
3
|
+
createJobTraceSink,
|
|
4
|
+
jobBackoff,
|
|
5
|
+
serverLogger,
|
|
6
|
+
type JobEvent,
|
|
7
|
+
type JobRunner,
|
|
8
|
+
type Tracer,
|
|
9
|
+
} from '@flowdular/sdk/server';
|
|
10
|
+
import type { AutomationScheduleService } from './schedule-service.ts';
|
|
11
|
+
import type {
|
|
12
|
+
AutomationScheduleRouting,
|
|
13
|
+
AutomationsRepository,
|
|
14
|
+
} from './repository.ts';
|
|
15
|
+
|
|
16
|
+
/** Schedules one pass fires, and the page the cross-tenant poll answers. */
|
|
17
|
+
export const SCHEDULE_POLL_PAGE = 20;
|
|
18
|
+
|
|
19
|
+
export interface AutomationScheduleRunnerOptions {
|
|
20
|
+
readonly repository: () => Promise<AutomationsRepository>;
|
|
21
|
+
readonly service: () => Promise<AutomationScheduleService>;
|
|
22
|
+
/** The platform setting, read once when the loop starts. */
|
|
23
|
+
readonly intervalMs: number;
|
|
24
|
+
readonly now?: (() => number) | undefined;
|
|
25
|
+
/** Absent turns every pass into spans; a sink of its own replaces that. */
|
|
26
|
+
readonly onEvent?: ((event: JobEvent) => void) | undefined;
|
|
27
|
+
/** Defaults to the process tracer, which is the one `context.tracer` carries. */
|
|
28
|
+
readonly tracer?: Tracer | undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The scheduler pass as the platform runner sees it: a claim over routing
|
|
33
|
+
* columns and one due schedule fired per claim. The loop, its bound, the guard
|
|
34
|
+
* against overlapping passes, the isolation of one schedule from the next and
|
|
35
|
+
* the drain are the runner's (`@flowdular/sdk/server`); the cross-tenant poll, the
|
|
36
|
+
* re-read under the workspace it named and the slot advance stay here.
|
|
37
|
+
*/
|
|
38
|
+
export function createAutomationScheduleRunner(
|
|
39
|
+
options: AutomationScheduleRunnerOptions,
|
|
40
|
+
): JobRunner {
|
|
41
|
+
/* The poll crosses workspaces on the background role and answers routing
|
|
42
|
+
columns alone. It refills only once the page it filled is drained, and a
|
|
43
|
+
page shorter than the bound means nothing further was due, so a pass reads
|
|
44
|
+
it at most twice however many schedules it fires. */
|
|
45
|
+
let queue: AutomationScheduleRouting[] = [];
|
|
46
|
+
let refillable = true;
|
|
47
|
+
|
|
48
|
+
return createJobRunner<AutomationScheduleRouting>({
|
|
49
|
+
name: 'automations.core',
|
|
50
|
+
intervalMs: options.intervalMs,
|
|
51
|
+
/* A schedule claims nothing: the next run time the advance compares and
|
|
52
|
+
swaps, and the slot key the run carries, are its fence, so no lease is
|
|
53
|
+
held and no renewal runs. */
|
|
54
|
+
staleAfterMs: options.intervalMs,
|
|
55
|
+
backoff: jobBackoff(options.intervalMs),
|
|
56
|
+
batchLimit: SCHEDULE_POLL_PAGE,
|
|
57
|
+
logger: serverLogger,
|
|
58
|
+
now: options.now,
|
|
59
|
+
onEvent:
|
|
60
|
+
options.onEvent ??
|
|
61
|
+
createJobTraceSink(options.tracer ? { tracer: options.tracer } : {}),
|
|
62
|
+
claim: async (at) => {
|
|
63
|
+
if (queue.length === 0) {
|
|
64
|
+
if (!refillable) {
|
|
65
|
+
refillable = true;
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const repository = await options.repository();
|
|
69
|
+
const page = await repository.listDueSchedules(at, SCHEDULE_POLL_PAGE);
|
|
70
|
+
refillable = page.length === SCHEDULE_POLL_PAGE;
|
|
71
|
+
queue = [...page];
|
|
72
|
+
}
|
|
73
|
+
const routing = queue.shift();
|
|
74
|
+
if (!routing) {
|
|
75
|
+
refillable = true;
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return routing;
|
|
79
|
+
},
|
|
80
|
+
perform: async (routing) => {
|
|
81
|
+
await (await options.service()).fireDue(routing);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -22,10 +22,13 @@ import {
|
|
|
22
22
|
} from '../domain/variables.ts';
|
|
23
23
|
import {
|
|
24
24
|
InvalidCadenceError,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
firstCadenceSlot,
|
|
26
|
+
nextCadenceSlot,
|
|
27
27
|
normalizeCadence,
|
|
28
|
+
parseCadence,
|
|
29
|
+
type Cadence,
|
|
28
30
|
} from '../domain/cadence.ts';
|
|
31
|
+
import { DEFAULT_TIME_ZONE } from '../domain/time-zone.ts';
|
|
29
32
|
import {
|
|
30
33
|
createAutomationTargetRegistry,
|
|
31
34
|
type AutomationTargetJsonValue,
|
|
@@ -33,6 +36,9 @@ import {
|
|
|
33
36
|
} from '../server/targets.ts';
|
|
34
37
|
import { AutomationsServiceError } from './automations-service.ts';
|
|
35
38
|
import type {
|
|
39
|
+
AutomationListPage,
|
|
40
|
+
AutomationListQuery,
|
|
41
|
+
AutomationScheduleRouting,
|
|
36
42
|
AutomationsRepository,
|
|
37
43
|
StoredAutomationSchedule,
|
|
38
44
|
} from './repository.ts';
|
|
@@ -72,6 +78,17 @@ function cadence(value: string): string {
|
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
|
|
81
|
+
function cadenceSlot(compute: () => number): number {
|
|
82
|
+
try {
|
|
83
|
+
return compute();
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (error instanceof InvalidCadenceError) {
|
|
86
|
+
throw new AutomationsServiceError('INVALID_CADENCE', error.message);
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
75
92
|
function trustedUser(input: string | UserActor): UserActor {
|
|
76
93
|
if (typeof input === 'string') {
|
|
77
94
|
const id = bounded(input, 'actorId', 1, 128);
|
|
@@ -203,17 +220,42 @@ export class AutomationScheduleService {
|
|
|
203
220
|
private readonly signal: AbortSignal = new AbortController().signal,
|
|
204
221
|
variables?: PlatformVariableRegistry,
|
|
205
222
|
targets?: AutomationTargetRegistry,
|
|
223
|
+
/* The workspace zone a cron slot is computed in, read live so a change
|
|
224
|
+
applies to the next slot rather than to the next deployment. */
|
|
225
|
+
private readonly timeZoneOf: (tenantId: string) => string = () =>
|
|
226
|
+
DEFAULT_TIME_ZONE,
|
|
227
|
+
/* Loads the workspace settings the zone is read from; the scheduler
|
|
228
|
+
fires outside any request, so nothing else has primed them. */
|
|
229
|
+
private readonly primeTenant: (tenantId: string) => Promise<void> = () =>
|
|
230
|
+
Promise.resolve(),
|
|
206
231
|
) {
|
|
207
232
|
this.variables = variables ?? createScheduleVariableRegistry(this.runs);
|
|
208
233
|
this.targets = targets ?? createAutomationTargetRegistry();
|
|
209
234
|
}
|
|
210
235
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
236
|
+
/** The zone this workspace's wall clock slots and screens use. */
|
|
237
|
+
timeZone(tenantId: string): string {
|
|
238
|
+
return this.timeZoneOf(bounded(tenantId, 'tenantId', 1, 128));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* An interval cadence carries no zone, so it never pays for the read. */
|
|
242
|
+
private zoneFor(cadence: Cadence, tenantId: string): string {
|
|
243
|
+
return cadence.kind === 'cron'
|
|
244
|
+
? this.timeZoneOf(tenantId)
|
|
245
|
+
: DEFAULT_TIME_ZONE;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async list(
|
|
249
|
+
tenantId: string,
|
|
250
|
+
query: AutomationListQuery,
|
|
251
|
+
): Promise<AutomationListPage<AutomationSchedule>> {
|
|
252
|
+
const page = await this.repository.listSchedulesPage(tenantId, query);
|
|
253
|
+
return {
|
|
254
|
+
items: await Promise.all(
|
|
255
|
+
page.items.map((record) => this.present(record)),
|
|
215
256
|
),
|
|
216
|
-
|
|
257
|
+
next: page.next,
|
|
258
|
+
};
|
|
217
259
|
}
|
|
218
260
|
|
|
219
261
|
async agents(tenantId: string) {
|
|
@@ -307,7 +349,7 @@ export class AutomationScheduleService {
|
|
|
307
349
|
cadence: normalized,
|
|
308
350
|
enabled: input.enabled === true,
|
|
309
351
|
disabledReason: null,
|
|
310
|
-
nextRunAt:
|
|
352
|
+
nextRunAt: this.firstSlot(normalized, trustedTenantId, now),
|
|
311
353
|
lastRunAt: null,
|
|
312
354
|
lastRunId: null,
|
|
313
355
|
lastError: null,
|
|
@@ -361,7 +403,7 @@ export class AutomationScheduleService {
|
|
|
361
403
|
const nextRunAt =
|
|
362
404
|
nextCadence === existing.cadence && existing.enabled === input.enabled
|
|
363
405
|
? existing.nextRunAt
|
|
364
|
-
:
|
|
406
|
+
: this.firstSlot(nextCadence, trustedTenantId, now);
|
|
365
407
|
const inputTemplate = bounded(input.inputTemplate, 'input', 1, 10_000);
|
|
366
408
|
validateScheduleTemplate(inputTemplate, scopes);
|
|
367
409
|
if (
|
|
@@ -541,22 +583,19 @@ export class AutomationScheduleService {
|
|
|
541
583
|
return { id, created, targetKind: stored.targetKind };
|
|
542
584
|
}
|
|
543
585
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (await this.fire(schedule, now)) fired += 1;
|
|
558
|
-
}
|
|
559
|
-
return fired;
|
|
586
|
+
/**
|
|
587
|
+
* One due schedule the cross-tenant poll routed here. The poll returns
|
|
588
|
+
* routing data only, so the schedule itself is read under the tenant that row
|
|
589
|
+
* named, and a slot that moved in between is skipped rather than fired twice.
|
|
590
|
+
* Answers whether the slot dispatched a run.
|
|
591
|
+
*/
|
|
592
|
+
async fireDue(routing: AutomationScheduleRouting): Promise<boolean> {
|
|
593
|
+
const schedule = await this.repository.getSchedule(
|
|
594
|
+
routing.tenantId,
|
|
595
|
+
routing.id,
|
|
596
|
+
);
|
|
597
|
+
if (!schedule || schedule.nextRunAt !== routing.nextRunAt) return false;
|
|
598
|
+
return await this.fire(schedule, this.now());
|
|
560
599
|
}
|
|
561
600
|
|
|
562
601
|
private async fire(
|
|
@@ -564,6 +603,43 @@ export class AutomationScheduleService {
|
|
|
564
603
|
now: number,
|
|
565
604
|
): Promise<boolean> {
|
|
566
605
|
const slot = schedule.nextRunAt;
|
|
606
|
+
await this.primeTenant(schedule.tenantId);
|
|
607
|
+
/* Resolved before anything is dispatched: a cadence whose next slot cannot
|
|
608
|
+
be computed disables the schedule instead of firing a slot it could
|
|
609
|
+
never advance past. */
|
|
610
|
+
let nextRunAt: number;
|
|
611
|
+
try {
|
|
612
|
+
const cadence = parseCadence(schedule.cadence);
|
|
613
|
+
nextRunAt = nextCadenceSlot(
|
|
614
|
+
cadence,
|
|
615
|
+
slot,
|
|
616
|
+
now,
|
|
617
|
+
this.zoneFor(cadence, schedule.tenantId),
|
|
618
|
+
);
|
|
619
|
+
} catch (error) {
|
|
620
|
+
if (!(error instanceof InvalidCadenceError)) throw error;
|
|
621
|
+
const reason = `INVALID_CADENCE: ${error.message}`.slice(
|
|
622
|
+
0,
|
|
623
|
+
MAX_ERROR_LENGTH,
|
|
624
|
+
);
|
|
625
|
+
if (
|
|
626
|
+
await this.repository.disableSchedule(
|
|
627
|
+
schedule.tenantId,
|
|
628
|
+
schedule.id,
|
|
629
|
+
reason,
|
|
630
|
+
now,
|
|
631
|
+
)
|
|
632
|
+
) {
|
|
633
|
+
await this.audit(
|
|
634
|
+
schedule,
|
|
635
|
+
'system',
|
|
636
|
+
'automation-schedule.disabled',
|
|
637
|
+
now,
|
|
638
|
+
{ reason: 'INVALID_CADENCE', targetKind: schedule.targetKind },
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
567
643
|
let runId: string | null = null;
|
|
568
644
|
let failure: string | null = null;
|
|
569
645
|
try {
|
|
@@ -647,7 +723,7 @@ export class AutomationScheduleService {
|
|
|
647
723
|
tenantId: schedule.tenantId,
|
|
648
724
|
scheduleId: schedule.id,
|
|
649
725
|
firedSlot: slot,
|
|
650
|
-
nextRunAt
|
|
726
|
+
nextRunAt,
|
|
651
727
|
lastRunAt: now,
|
|
652
728
|
lastRunId: runId ?? schedule.lastRunId,
|
|
653
729
|
lastError: failure,
|
|
@@ -669,6 +745,56 @@ export class AutomationScheduleService {
|
|
|
669
745
|
return runId !== null;
|
|
670
746
|
}
|
|
671
747
|
|
|
748
|
+
private firstSlot(normalized: string, tenantId: string, now: number): number {
|
|
749
|
+
const cadence = parseCadence(normalized);
|
|
750
|
+
return cadenceSlot(() =>
|
|
751
|
+
firstCadenceSlot(cadence, now, this.zoneFor(cadence, tenantId)),
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Moves every pending cron slot of one workspace into the zone it now uses.
|
|
757
|
+
* A slot already due is left alone so the fire it owes is not lost, and each
|
|
758
|
+
* write is conditional on the slot this read saw, so a concurrent fire wins.
|
|
759
|
+
*/
|
|
760
|
+
async retime(tenantId: string): Promise<number> {
|
|
761
|
+
const trustedTenantId = bounded(tenantId, 'tenantId', 1, 128);
|
|
762
|
+
const now = this.now();
|
|
763
|
+
const timeZone = this.timeZoneOf(trustedTenantId);
|
|
764
|
+
let moved = 0;
|
|
765
|
+
for (const schedule of await this.repository.listSchedules(
|
|
766
|
+
trustedTenantId,
|
|
767
|
+
)) {
|
|
768
|
+
if (!schedule.enabled || schedule.nextRunAt <= now) continue;
|
|
769
|
+
let nextRunAt: number;
|
|
770
|
+
try {
|
|
771
|
+
const cadence = parseCadence(schedule.cadence);
|
|
772
|
+
if (cadence.kind !== 'cron') continue;
|
|
773
|
+
nextRunAt = firstCadenceSlot(cadence, now, timeZone);
|
|
774
|
+
} catch (error) {
|
|
775
|
+
/* A cadence that no longer parses is left for the fire path, which
|
|
776
|
+
disables it with the reason on the schedule. */
|
|
777
|
+
if (error instanceof InvalidCadenceError) continue;
|
|
778
|
+
throw error;
|
|
779
|
+
}
|
|
780
|
+
if (nextRunAt === schedule.nextRunAt) continue;
|
|
781
|
+
const applied = await this.repository.retimeSchedule({
|
|
782
|
+
tenantId: trustedTenantId,
|
|
783
|
+
scheduleId: schedule.id,
|
|
784
|
+
expectedNextRunAt: schedule.nextRunAt,
|
|
785
|
+
nextRunAt,
|
|
786
|
+
updatedAt: now,
|
|
787
|
+
});
|
|
788
|
+
if (!applied) continue;
|
|
789
|
+
moved += 1;
|
|
790
|
+
await this.audit(schedule, 'system', 'automation-schedule.retimed', now, {
|
|
791
|
+
timeZone,
|
|
792
|
+
nextRunAt,
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
return moved;
|
|
796
|
+
}
|
|
797
|
+
|
|
672
798
|
private async validateTarget(
|
|
673
799
|
tenantId: string,
|
|
674
800
|
target: { readonly kind: string; readonly key: string },
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type { DatabaseHandle } from '@flowdular/sdk/database';
|
|
2
|
+
import { secretContext, type SecretVault } from './secret-vault.ts';
|
|
3
|
+
|
|
4
|
+
/** Rows re-sealed inside one tenant-scoped transaction. */
|
|
5
|
+
export const SECRET_ROTATION_BATCH = 200;
|
|
6
|
+
|
|
7
|
+
export const SECRET_ROTATION_TABLE = 'automations_triggers';
|
|
8
|
+
|
|
9
|
+
export interface SecretKeyCount {
|
|
10
|
+
readonly keyId: string;
|
|
11
|
+
readonly rows: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface SecretRotationReport {
|
|
15
|
+
readonly table: string;
|
|
16
|
+
/** Key id every row should end on: the current key of the vault. */
|
|
17
|
+
readonly currentKeyId: string;
|
|
18
|
+
readonly counts: readonly SecretKeyCount[];
|
|
19
|
+
/** Rows on a retired key when the run started. */
|
|
20
|
+
readonly stale: number;
|
|
21
|
+
readonly tenants: number;
|
|
22
|
+
readonly rotated: number;
|
|
23
|
+
/** Rows a concurrent write changed between the read and the update. */
|
|
24
|
+
readonly skipped: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SecretRotationOptions {
|
|
28
|
+
/** Tenant-scoped handle. Every read and write of a row runs on it. */
|
|
29
|
+
readonly runtime: DatabaseHandle;
|
|
30
|
+
/** Cross-tenant handle. It is granted the key ids and nothing else. */
|
|
31
|
+
readonly background: DatabaseHandle;
|
|
32
|
+
readonly vault: SecretVault;
|
|
33
|
+
readonly apply?: boolean;
|
|
34
|
+
readonly batchSize?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface StaleRow {
|
|
38
|
+
id: string;
|
|
39
|
+
secret_key_id: string;
|
|
40
|
+
secret_iv: string;
|
|
41
|
+
secret_tag: string;
|
|
42
|
+
secret_ciphertext: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const SQL = {
|
|
46
|
+
counts: `SELECT secret_key_id AS key_id, count(*) AS row_count
|
|
47
|
+
FROM automations_triggers
|
|
48
|
+
GROUP BY secret_key_id
|
|
49
|
+
ORDER BY secret_key_id`,
|
|
50
|
+
staleTenants: `SELECT tenant_id, count(*) AS row_count
|
|
51
|
+
FROM automations_triggers
|
|
52
|
+
WHERE secret_key_id <> $1
|
|
53
|
+
GROUP BY tenant_id
|
|
54
|
+
ORDER BY tenant_id`,
|
|
55
|
+
/* Paged by primary key: a row the optimistic update skipped stays stale, so
|
|
56
|
+
a query that only asked for stale rows would return it forever. */
|
|
57
|
+
staleBatch: `SELECT id, secret_key_id, secret_iv, secret_tag, secret_ciphertext
|
|
58
|
+
FROM automations_triggers
|
|
59
|
+
WHERE tenant_id = $1 AND secret_key_id <> $2 AND id > $3
|
|
60
|
+
ORDER BY id
|
|
61
|
+
LIMIT $4`,
|
|
62
|
+
/* The envelope the row still holds is the optimistic check: a secret rotated
|
|
63
|
+
by the application in between keeps its own value. secret_revision counts
|
|
64
|
+
secret changes a caller can see, and a re-seal is not one. */
|
|
65
|
+
reseal: `UPDATE automations_triggers
|
|
66
|
+
SET secret_key_id = $1, secret_iv = $2, secret_tag = $3,
|
|
67
|
+
secret_ciphertext = $4
|
|
68
|
+
WHERE tenant_id = $5 AND id = $6 AND secret_ciphertext = $7`,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function count(value: number | bigint | string): number {
|
|
72
|
+
const normalized = Number(value);
|
|
73
|
+
if (!Number.isSafeInteger(normalized)) {
|
|
74
|
+
throw new Error('The automations database returned an invalid count.');
|
|
75
|
+
}
|
|
76
|
+
return normalized;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Re-seals every stored trigger secret that is not on the current key. The
|
|
81
|
+
* inventory is read once across tenants, and each batch of rows is read,
|
|
82
|
+
* decrypted, re-sealed and written inside one transaction scoped to the tenant
|
|
83
|
+
* that owns them. It is idempotent: a second run finds nothing to do.
|
|
84
|
+
*/
|
|
85
|
+
export async function rotateTriggerSecrets(
|
|
86
|
+
options: SecretRotationOptions,
|
|
87
|
+
): Promise<SecretRotationReport> {
|
|
88
|
+
const currentKeyId = options.vault.keyId;
|
|
89
|
+
const batchSize = options.batchSize ?? SECRET_ROTATION_BATCH;
|
|
90
|
+
const inventory = await options.background.transaction(
|
|
91
|
+
async (transaction) => ({
|
|
92
|
+
counts: (
|
|
93
|
+
await transaction.query<{
|
|
94
|
+
key_id: string;
|
|
95
|
+
row_count: number | bigint | string;
|
|
96
|
+
}>({ text: SQL.counts })
|
|
97
|
+
).rows,
|
|
98
|
+
stale: (
|
|
99
|
+
await transaction.query<{
|
|
100
|
+
tenant_id: string;
|
|
101
|
+
row_count: number | bigint | string;
|
|
102
|
+
}>({ text: SQL.staleTenants, parameters: [currentKeyId] })
|
|
103
|
+
).rows,
|
|
104
|
+
}),
|
|
105
|
+
{ access: 'read' },
|
|
106
|
+
);
|
|
107
|
+
const report = {
|
|
108
|
+
table: SECRET_ROTATION_TABLE,
|
|
109
|
+
currentKeyId,
|
|
110
|
+
counts: inventory.counts.map((row) => ({
|
|
111
|
+
keyId: row.key_id,
|
|
112
|
+
rows: count(row.row_count),
|
|
113
|
+
})),
|
|
114
|
+
stale: inventory.stale.reduce(
|
|
115
|
+
(total, row) => total + count(row.row_count),
|
|
116
|
+
0,
|
|
117
|
+
),
|
|
118
|
+
tenants: inventory.stale.length,
|
|
119
|
+
};
|
|
120
|
+
if (options.apply !== true) {
|
|
121
|
+
return { ...report, rotated: 0, skipped: 0 };
|
|
122
|
+
}
|
|
123
|
+
let rotated = 0;
|
|
124
|
+
let skipped = 0;
|
|
125
|
+
for (const { tenant_id: tenantId } of inventory.stale) {
|
|
126
|
+
let cursor = '';
|
|
127
|
+
for (;;) {
|
|
128
|
+
const batch = await options.runtime.transaction(
|
|
129
|
+
async (transaction) => {
|
|
130
|
+
const rows = (
|
|
131
|
+
await transaction.query<StaleRow>({
|
|
132
|
+
text: SQL.staleBatch,
|
|
133
|
+
parameters: [tenantId, currentKeyId, cursor, batchSize],
|
|
134
|
+
})
|
|
135
|
+
).rows;
|
|
136
|
+
let written = 0;
|
|
137
|
+
for (const row of rows) {
|
|
138
|
+
const context = secretContext(tenantId, row.id);
|
|
139
|
+
const sealed = options.vault.encrypt(
|
|
140
|
+
options.vault.decrypt(
|
|
141
|
+
{
|
|
142
|
+
keyId: row.secret_key_id,
|
|
143
|
+
iv: row.secret_iv,
|
|
144
|
+
tag: row.secret_tag,
|
|
145
|
+
ciphertext: row.secret_ciphertext,
|
|
146
|
+
},
|
|
147
|
+
context,
|
|
148
|
+
),
|
|
149
|
+
context,
|
|
150
|
+
);
|
|
151
|
+
const result = await transaction.execute({
|
|
152
|
+
text: SQL.reseal,
|
|
153
|
+
parameters: [
|
|
154
|
+
sealed.keyId,
|
|
155
|
+
sealed.iv,
|
|
156
|
+
sealed.tag,
|
|
157
|
+
sealed.ciphertext,
|
|
158
|
+
tenantId,
|
|
159
|
+
row.id,
|
|
160
|
+
row.secret_ciphertext,
|
|
161
|
+
],
|
|
162
|
+
});
|
|
163
|
+
written += result.affectedRows;
|
|
164
|
+
}
|
|
165
|
+
return { read: rows.length, written, last: rows.at(-1)?.id };
|
|
166
|
+
},
|
|
167
|
+
{ access: 'write', tenantId },
|
|
168
|
+
);
|
|
169
|
+
rotated += batch.written;
|
|
170
|
+
skipped += batch.read - batch.written;
|
|
171
|
+
if (batch.read < batchSize || batch.last === undefined) break;
|
|
172
|
+
cursor = batch.last;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return { ...report, rotated, skipped };
|
|
176
|
+
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createCipheriv,
|
|
3
|
-
createDecipheriv,
|
|
4
|
-
createHash,
|
|
5
|
-
randomBytes,
|
|
6
|
-
} from 'node:crypto';
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
7
2
|
import {
|
|
8
3
|
closeSync,
|
|
9
4
|
mkdirSync,
|
|
@@ -12,6 +7,12 @@ import {
|
|
|
12
7
|
writeFileSync,
|
|
13
8
|
} from 'node:fs';
|
|
14
9
|
import { dirname } from 'node:path';
|
|
10
|
+
import {
|
|
11
|
+
createKeyring,
|
|
12
|
+
KeyringError,
|
|
13
|
+
parsePreviousKeys,
|
|
14
|
+
type Keyring,
|
|
15
|
+
} from '@flowdular/sdk/kernel';
|
|
15
16
|
import { flowdularLocalDataPath } from '@flowdular/sdk/kernel/legacy-local-state';
|
|
16
17
|
|
|
17
18
|
export interface EncryptedSecret {
|
|
@@ -21,32 +22,48 @@ export interface EncryptedSecret {
|
|
|
21
22
|
readonly ciphertext: string;
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* The additional data every trigger secret envelope is bound to. It is part of
|
|
27
|
+
* the stored envelope: re-sealing a row under a new key must rebuild exactly
|
|
28
|
+
* this string, so it lives with the envelope format and not with a service.
|
|
29
|
+
*/
|
|
30
|
+
export function secretContext(tenantId: string, triggerId: string): string {
|
|
31
|
+
return `${tenantId}:${triggerId}:automation-trigger`;
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
export interface SecretVault {
|
|
35
|
+
/** Key id every new envelope is written with; stored rows may carry older ones. */
|
|
36
|
+
readonly keyId: string;
|
|
25
37
|
encrypt(secret: string, context: string): EncryptedSecret;
|
|
26
38
|
decrypt(envelope: EncryptedSecret, context: string): string;
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
function encryptionKey(
|
|
41
|
+
function encryptionKey(
|
|
42
|
+
value: string,
|
|
43
|
+
variable = 'FD_AUTOMATIONS_CREDENTIAL_KEY',
|
|
44
|
+
): Buffer {
|
|
30
45
|
const key = Buffer.from(value.trim(), 'base64');
|
|
31
46
|
if (key.byteLength !== 32) {
|
|
32
47
|
key.fill(0);
|
|
33
|
-
throw new Error(
|
|
34
|
-
'FD_AUTOMATIONS_CREDENTIAL_KEY must be a base64-encoded 32-byte key.',
|
|
35
|
-
);
|
|
48
|
+
throw new Error(`${variable} must be a base64-encoded 32-byte key.`);
|
|
36
49
|
}
|
|
37
50
|
return key;
|
|
38
51
|
}
|
|
39
52
|
|
|
40
53
|
export class AesGcmSecretVault implements SecretVault {
|
|
41
|
-
readonly #
|
|
42
|
-
readonly #keyId: string;
|
|
54
|
+
readonly #keyring: Keyring;
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
/* `previous` holds the keys a rotation has not finished retiring: they open
|
|
57
|
+
stored rows, and nothing is ever written with them. */
|
|
58
|
+
constructor(key: Buffer, previous: readonly Buffer[] = []) {
|
|
45
59
|
if (key.byteLength !== 32) {
|
|
46
60
|
throw new Error('Automation secret encryption requires a 32-byte key.');
|
|
47
61
|
}
|
|
48
|
-
this.#
|
|
49
|
-
|
|
62
|
+
this.#keyring = createKeyring({ current: key, previous });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get keyId(): string {
|
|
66
|
+
return this.#keyring.keyId;
|
|
50
67
|
}
|
|
51
68
|
|
|
52
69
|
encrypt(secret: string, context: string): EncryptedSecret {
|
|
@@ -54,36 +71,39 @@ export class AesGcmSecretVault implements SecretVault {
|
|
|
54
71
|
if (normalized.length < 8 || normalized.length > 16_384) {
|
|
55
72
|
throw new Error('Automation secrets must contain 8 to 16384 characters.');
|
|
56
73
|
}
|
|
57
|
-
const
|
|
58
|
-
const cipher = createCipheriv('aes-256-gcm', this.#key, iv);
|
|
59
|
-
cipher.setAAD(Buffer.from(context, 'utf8'));
|
|
60
|
-
const ciphertext = Buffer.concat([
|
|
61
|
-
cipher.update(normalized, 'utf8'),
|
|
62
|
-
cipher.final(),
|
|
63
|
-
]);
|
|
74
|
+
const sealed = this.#keyring.seal(normalized, context);
|
|
64
75
|
return {
|
|
65
|
-
keyId:
|
|
66
|
-
iv: iv.toString('base64'),
|
|
67
|
-
tag:
|
|
68
|
-
ciphertext: ciphertext.toString('base64'),
|
|
76
|
+
keyId: sealed.keyId,
|
|
77
|
+
iv: sealed.iv.toString('base64'),
|
|
78
|
+
tag: sealed.tag.toString('base64'),
|
|
79
|
+
ciphertext: sealed.ciphertext.toString('base64'),
|
|
69
80
|
};
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
decrypt(envelope: EncryptedSecret, context: string): string {
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
try {
|
|
85
|
+
return this.#keyring
|
|
86
|
+
.open(
|
|
87
|
+
{
|
|
88
|
+
keyId: envelope.keyId,
|
|
89
|
+
iv: Buffer.from(envelope.iv, 'base64'),
|
|
90
|
+
tag: Buffer.from(envelope.tag, 'base64'),
|
|
91
|
+
ciphertext: Buffer.from(envelope.ciphertext, 'base64'),
|
|
92
|
+
},
|
|
93
|
+
context,
|
|
94
|
+
)
|
|
95
|
+
.toString('utf8');
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error instanceof KeyringError && error.code === 'KEY_UNKNOWN') {
|
|
98
|
+
throw new Error(
|
|
99
|
+
'The automation secret encryption key is unavailable.',
|
|
100
|
+
{
|
|
101
|
+
cause: error,
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
75
106
|
}
|
|
76
|
-
const decipher = createDecipheriv(
|
|
77
|
-
'aes-256-gcm',
|
|
78
|
-
this.#key,
|
|
79
|
-
Buffer.from(envelope.iv, 'base64'),
|
|
80
|
-
);
|
|
81
|
-
decipher.setAAD(Buffer.from(context, 'utf8'));
|
|
82
|
-
decipher.setAuthTag(Buffer.from(envelope.tag, 'base64'));
|
|
83
|
-
return Buffer.concat([
|
|
84
|
-
decipher.update(Buffer.from(envelope.ciphertext, 'base64')),
|
|
85
|
-
decipher.final(),
|
|
86
|
-
]).toString('utf8');
|
|
87
107
|
}
|
|
88
108
|
}
|
|
89
109
|
|
|
@@ -108,17 +128,24 @@ export function secretVaultFromEnvironment(
|
|
|
108
128
|
environment: NodeJS.ProcessEnv = process.env,
|
|
109
129
|
workspaceRoot = process.cwd(),
|
|
110
130
|
): SecretVault {
|
|
131
|
+
const previous = parsePreviousKeys(
|
|
132
|
+
environment.FD_AUTOMATIONS_CREDENTIAL_KEY_PREVIOUS,
|
|
133
|
+
(entry) => encryptionKey(entry, 'FD_AUTOMATIONS_CREDENTIAL_KEY_PREVIOUS'),
|
|
134
|
+
);
|
|
111
135
|
const configured = environment.FD_AUTOMATIONS_CREDENTIAL_KEY;
|
|
112
|
-
if (configured)
|
|
136
|
+
if (configured) {
|
|
137
|
+
return new AesGcmSecretVault(encryptionKey(configured), previous);
|
|
138
|
+
}
|
|
113
139
|
if (environment.NODE_ENV === 'production') {
|
|
114
140
|
throw new Error('FD_AUTOMATIONS_CREDENTIAL_KEY is required in production.');
|
|
115
141
|
}
|
|
116
142
|
if (environment.NODE_ENV === 'test') {
|
|
117
|
-
return new AesGcmSecretVault(Buffer.alloc(32, 0x41));
|
|
143
|
+
return new AesGcmSecretVault(Buffer.alloc(32, 0x41), previous);
|
|
118
144
|
}
|
|
119
145
|
return new AesGcmSecretVault(
|
|
120
146
|
developmentKey(
|
|
121
147
|
flowdularLocalDataPath(workspaceRoot, 'automations-credential.key'),
|
|
122
148
|
),
|
|
149
|
+
previous,
|
|
123
150
|
);
|
|
124
151
|
}
|