@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,342 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DeliveryAttempt,
|
|
3
|
+
DeliveryRouting,
|
|
4
|
+
DeliveryStatus,
|
|
5
|
+
MemberNotificationSettings,
|
|
6
|
+
NotificationKind,
|
|
7
|
+
NotificationPreference,
|
|
8
|
+
NotificationsInbox,
|
|
9
|
+
NotificationsInboxStatus,
|
|
10
|
+
WebhookSubscription,
|
|
11
|
+
WebhookSubscriptionStatus,
|
|
12
|
+
} from '../domain/types.ts';
|
|
13
|
+
import type { EncryptedSecret } from './secret-vault.ts';
|
|
14
|
+
|
|
15
|
+
/** A subscription with its sealed secret. Never leaves the service layer. */
|
|
16
|
+
export interface StoredWebhookSubscription extends WebhookSubscription {
|
|
17
|
+
readonly secret: EncryptedSecret;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface InboxFilters {
|
|
21
|
+
/** Absent means the open inbox: every item the member has not archived. */
|
|
22
|
+
readonly status?: NotificationsInboxStatus | undefined;
|
|
23
|
+
readonly kind?: NotificationKind | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SubscriptionFilters {
|
|
27
|
+
readonly status?: WebhookSubscriptionStatus | undefined;
|
|
28
|
+
/** A substring of the name or the URL. */
|
|
29
|
+
readonly search?: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface DeliveryFilters {
|
|
33
|
+
readonly status?: DeliveryStatus | undefined;
|
|
34
|
+
readonly subscriptionId?: string | undefined;
|
|
35
|
+
/** A substring of the source reference or the source module. */
|
|
36
|
+
readonly search?: string | undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type PageDirection = 'asc' | 'desc';
|
|
40
|
+
|
|
41
|
+
/** The sort value and the id of the row a page ends on. */
|
|
42
|
+
export interface PageKey<Key extends string | number> {
|
|
43
|
+
readonly key: Key;
|
|
44
|
+
readonly id: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* One keyset page of a list. Every list sorts on one column and the id, both
|
|
49
|
+
* in `direction`; `after` is the last row of the previous page, so the read is
|
|
50
|
+
* a range on the list's page index rather than an offset into it.
|
|
51
|
+
*/
|
|
52
|
+
export interface ListPage<Key extends string | number> {
|
|
53
|
+
readonly limit: number;
|
|
54
|
+
readonly direction: PageDirection;
|
|
55
|
+
readonly after: PageKey<Key> | null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface PagedRows<Row, Key extends string | number> {
|
|
59
|
+
readonly rows: readonly Row[];
|
|
60
|
+
/** The key of the last row when the page is full, so a caller can go on; null on a short page. */
|
|
61
|
+
readonly next: PageKey<Key> | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CompleteDeliveryInput {
|
|
65
|
+
readonly tenantId: string;
|
|
66
|
+
readonly id: string;
|
|
67
|
+
readonly status: Exclude<DeliveryStatus, 'pending'>;
|
|
68
|
+
readonly completedAt: number;
|
|
69
|
+
readonly responseStatus: number | null;
|
|
70
|
+
readonly errorClass: string | null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ClaimDeliveryInput {
|
|
74
|
+
readonly tenantId: string;
|
|
75
|
+
readonly id: string;
|
|
76
|
+
/** Claim stamp, and the due bound: an attempt scheduled later is not taken. */
|
|
77
|
+
readonly now: number;
|
|
78
|
+
/** A claim stamped at or before this was abandoned and may be taken over. */
|
|
79
|
+
readonly strandedBefore: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* One published event, written in a single tenant-scoped write transaction.
|
|
84
|
+
* The two builders are pure: the service decides what a row looks like, the
|
|
85
|
+
* adapter decides when it is written and under which transaction.
|
|
86
|
+
*/
|
|
87
|
+
export interface PublishEventInput {
|
|
88
|
+
readonly tenantId: string;
|
|
89
|
+
readonly kind: NotificationKind;
|
|
90
|
+
readonly sourceRef: string;
|
|
91
|
+
readonly recipients: readonly string[];
|
|
92
|
+
readonly inboxItem: (recipientAccountId: string) => NotificationsInbox;
|
|
93
|
+
readonly delivery: (subscription: WebhookSubscription) => DeliveryAttempt;
|
|
94
|
+
/** Queued for every addressed member who turned e-mail delivery on. */
|
|
95
|
+
readonly emailDelivery: (item: NotificationsInbox) => DeliveryAttempt;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface PublishEventResult {
|
|
99
|
+
readonly inboxItemIds: readonly string[];
|
|
100
|
+
readonly deliveryIds: readonly string[];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Where a keyset page ended. Both columns are written once and never updated,
|
|
105
|
+
* so a walk resumed from one cannot revisit or skip a row while the table is
|
|
106
|
+
* still being written to.
|
|
107
|
+
*/
|
|
108
|
+
export interface ExportCursor {
|
|
109
|
+
readonly createdAt: number;
|
|
110
|
+
readonly id: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The persistence port. Async and database agnostic: the PostgreSQL statements,
|
|
115
|
+
* the tenant transactions and the background lease live in the adapter.
|
|
116
|
+
*/
|
|
117
|
+
export interface NotificationsRepository {
|
|
118
|
+
/**
|
|
119
|
+
* Idempotent on (tenantId, kind, sourceRef). A repeat writes nothing and
|
|
120
|
+
* answers with the identifiers the first publication created.
|
|
121
|
+
*/
|
|
122
|
+
publish(input: PublishEventInput): Promise<PublishEventResult>;
|
|
123
|
+
|
|
124
|
+
/** One page of the member's own inbox, by creation time and id. */
|
|
125
|
+
listInbox(
|
|
126
|
+
tenantId: string,
|
|
127
|
+
recipientAccountId: string,
|
|
128
|
+
filters: InboxFilters,
|
|
129
|
+
page: ListPage<number>,
|
|
130
|
+
): Promise<PagedRows<NotificationsInbox, number>>;
|
|
131
|
+
countUnreadInbox(
|
|
132
|
+
tenantId: string,
|
|
133
|
+
recipientAccountId: string,
|
|
134
|
+
): Promise<number>;
|
|
135
|
+
getInboxItem(
|
|
136
|
+
tenantId: string,
|
|
137
|
+
recipientAccountId: string,
|
|
138
|
+
id: string,
|
|
139
|
+
): Promise<NotificationsInbox | null>;
|
|
140
|
+
/**
|
|
141
|
+
* The item one published event wrote for one member, by the natural key the
|
|
142
|
+
* publication is idempotent on. The e-mail channel reads the body from it at
|
|
143
|
+
* send time instead of copying it onto the attempt row.
|
|
144
|
+
*/
|
|
145
|
+
findInboxItem(
|
|
146
|
+
tenantId: string,
|
|
147
|
+
recipientAccountId: string,
|
|
148
|
+
kind: NotificationKind,
|
|
149
|
+
sourceRef: string,
|
|
150
|
+
): Promise<NotificationsInbox | null>;
|
|
151
|
+
setInboxStatus(
|
|
152
|
+
tenantId: string,
|
|
153
|
+
recipientAccountId: string,
|
|
154
|
+
id: string,
|
|
155
|
+
status: NotificationsInboxStatus,
|
|
156
|
+
readAt: string | null,
|
|
157
|
+
): Promise<NotificationsInbox | null>;
|
|
158
|
+
/**
|
|
159
|
+
* Writes the items an event produced outside a publication, skipping repeats
|
|
160
|
+
* and, exactly like `publish`, every recipient who disabled that kind.
|
|
161
|
+
*/
|
|
162
|
+
appendInboxItems(
|
|
163
|
+
tenantId: string,
|
|
164
|
+
records: readonly NotificationsInbox[],
|
|
165
|
+
emailDelivery: (item: NotificationsInbox) => DeliveryAttempt,
|
|
166
|
+
): Promise<readonly string[]>;
|
|
167
|
+
/**
|
|
168
|
+
* Every inbox item of one workspace, oldest first, one keyset page at a
|
|
169
|
+
* time. This is the workspace export of `notifications.core.inbox`, so it
|
|
170
|
+
* crosses recipients; the member-facing reads never do.
|
|
171
|
+
*/
|
|
172
|
+
exportInboxPage(
|
|
173
|
+
tenantId: string,
|
|
174
|
+
after: ExportCursor | null,
|
|
175
|
+
limit: number,
|
|
176
|
+
): Promise<readonly NotificationsInbox[]>;
|
|
177
|
+
/**
|
|
178
|
+
* Removes at most `limit` inbox items created strictly before `before`.
|
|
179
|
+
* Nothing else deletes an item by age, so this is the whole retention path
|
|
180
|
+
* of the class.
|
|
181
|
+
*/
|
|
182
|
+
deleteInboxItemsBefore(
|
|
183
|
+
tenantId: string,
|
|
184
|
+
before: number,
|
|
185
|
+
limit: number,
|
|
186
|
+
): Promise<number>;
|
|
187
|
+
|
|
188
|
+
listPreferences(
|
|
189
|
+
tenantId: string,
|
|
190
|
+
recipientAccountId: string,
|
|
191
|
+
): Promise<readonly NotificationPreference[]>;
|
|
192
|
+
savePreference(
|
|
193
|
+
record: NotificationPreference,
|
|
194
|
+
): Promise<NotificationPreference>;
|
|
195
|
+
/** Null when the member never saved one; the caller applies the defaults. */
|
|
196
|
+
getMemberSettings(
|
|
197
|
+
tenantId: string,
|
|
198
|
+
recipientAccountId: string,
|
|
199
|
+
): Promise<MemberNotificationSettings | null>;
|
|
200
|
+
saveMemberSettings(
|
|
201
|
+
record: MemberNotificationSettings,
|
|
202
|
+
): Promise<MemberNotificationSettings>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* One page of the workspace's subscriptions by normalized name and id. The
|
|
206
|
+
* key of a row is `lower(name)` as the database computes it, so a cursor
|
|
207
|
+
* compares exactly the way the page index orders.
|
|
208
|
+
*/
|
|
209
|
+
listSubscriptions(
|
|
210
|
+
tenantId: string,
|
|
211
|
+
filters: SubscriptionFilters,
|
|
212
|
+
page: ListPage<string>,
|
|
213
|
+
): Promise<PagedRows<StoredWebhookSubscription, string>>;
|
|
214
|
+
getSubscription(
|
|
215
|
+
tenantId: string,
|
|
216
|
+
id: string,
|
|
217
|
+
): Promise<StoredWebhookSubscription | null>;
|
|
218
|
+
/** Null when the normalized name is already taken in the tenant. */
|
|
219
|
+
createSubscription(
|
|
220
|
+
record: StoredWebhookSubscription,
|
|
221
|
+
): Promise<StoredWebhookSubscription | null>;
|
|
222
|
+
/** Null when the row is gone, `'conflict'` when the new name is taken. */
|
|
223
|
+
updateSubscription(
|
|
224
|
+
record: Pick<
|
|
225
|
+
WebhookSubscription,
|
|
226
|
+
| 'tenantId'
|
|
227
|
+
| 'id'
|
|
228
|
+
| 'name'
|
|
229
|
+
| 'url'
|
|
230
|
+
| 'events'
|
|
231
|
+
| 'description'
|
|
232
|
+
| 'updatedAt'
|
|
233
|
+
>,
|
|
234
|
+
): Promise<StoredWebhookSubscription | null | 'conflict'>;
|
|
235
|
+
setSubscriptionStatus(
|
|
236
|
+
tenantId: string,
|
|
237
|
+
id: string,
|
|
238
|
+
status: WebhookSubscriptionStatus,
|
|
239
|
+
updatedAt: number,
|
|
240
|
+
): Promise<StoredWebhookSubscription | null>;
|
|
241
|
+
/**
|
|
242
|
+
* Moves the subscription to disabled and drops its pending attempts in the
|
|
243
|
+
* same write, so no queued delivery can leave after the subscription stopped
|
|
244
|
+
* accepting events. The ledger of completed attempts is untouched.
|
|
245
|
+
*/
|
|
246
|
+
disableSubscription(
|
|
247
|
+
tenantId: string,
|
|
248
|
+
id: string,
|
|
249
|
+
updatedAt: number,
|
|
250
|
+
): Promise<StoredWebhookSubscription | null>;
|
|
251
|
+
rotateSubscriptionSecret(
|
|
252
|
+
tenantId: string,
|
|
253
|
+
id: string,
|
|
254
|
+
secret: EncryptedSecret,
|
|
255
|
+
fingerprint: string,
|
|
256
|
+
updatedAt: number,
|
|
257
|
+
): Promise<StoredWebhookSubscription | null>;
|
|
258
|
+
/** Deletes the subscription and its pending attempts; the ledger stays. */
|
|
259
|
+
deleteSubscription(tenantId: string, id: string): Promise<boolean>;
|
|
260
|
+
stampSubscriptionDelivery(
|
|
261
|
+
tenantId: string,
|
|
262
|
+
id: string,
|
|
263
|
+
at: number,
|
|
264
|
+
): Promise<void>;
|
|
265
|
+
|
|
266
|
+
/** One page of the ledger by schedule time and id. */
|
|
267
|
+
listDeliveries(
|
|
268
|
+
tenantId: string,
|
|
269
|
+
filters: DeliveryFilters,
|
|
270
|
+
page: ListPage<number>,
|
|
271
|
+
): Promise<PagedRows<DeliveryAttempt, number>>;
|
|
272
|
+
getDelivery(tenantId: string, id: string): Promise<DeliveryAttempt | null>;
|
|
273
|
+
/** Null when an attempt with the same sequence and number already exists. */
|
|
274
|
+
appendDelivery(record: DeliveryAttempt): Promise<DeliveryAttempt | null>;
|
|
275
|
+
/**
|
|
276
|
+
* Takes one due attempt for this process, under the tenant the routing row
|
|
277
|
+
* named, and returns the row it claimed. Null when the attempt moved on, is
|
|
278
|
+
* not due yet, or is held by a claim that has not gone stale: that is what
|
|
279
|
+
* keeps a second process draining the same queue from repeating the request.
|
|
280
|
+
*/
|
|
281
|
+
claimDelivery(input: ClaimDeliveryInput): Promise<DeliveryAttempt | null>;
|
|
282
|
+
/**
|
|
283
|
+
* Returns a claimed attempt to the queue at `scheduledFor`. The attempt
|
|
284
|
+
* number, the outcome and every other ledger field stay untouched, so a
|
|
285
|
+
* subscription that is holding its queue still counts no attempt.
|
|
286
|
+
*/
|
|
287
|
+
releaseDelivery(
|
|
288
|
+
tenantId: string,
|
|
289
|
+
id: string,
|
|
290
|
+
scheduledFor: number,
|
|
291
|
+
): Promise<boolean>;
|
|
292
|
+
/** Moves one open attempt, pending or claimed, to a terminal state. */
|
|
293
|
+
completeDelivery(input: CompleteDeliveryInput): Promise<boolean>;
|
|
294
|
+
/** Highest attempt run recorded for one event on one delivery target. */
|
|
295
|
+
latestDeliverySequence(
|
|
296
|
+
attempt: Pick<
|
|
297
|
+
DeliveryAttempt,
|
|
298
|
+
| 'tenantId'
|
|
299
|
+
| 'channel'
|
|
300
|
+
| 'subscriptionId'
|
|
301
|
+
| 'recipientAccountId'
|
|
302
|
+
| 'kind'
|
|
303
|
+
| 'sourceRef'
|
|
304
|
+
>,
|
|
305
|
+
): Promise<number>;
|
|
306
|
+
|
|
307
|
+
/** Cross-tenant, routing columns only, on the read-only background lease. */
|
|
308
|
+
listDueDeliveries(
|
|
309
|
+
now: number,
|
|
310
|
+
limit: number,
|
|
311
|
+
): Promise<readonly DeliveryRouting[]>;
|
|
312
|
+
/**
|
|
313
|
+
* Cross-tenant claims stamped at or before `before`, whose claimant never
|
|
314
|
+
* came back. A claim is invisible to the due query, so a process that died
|
|
315
|
+
* mid-send would strand its rows without this second, equally bounded read.
|
|
316
|
+
*/
|
|
317
|
+
listStrandedDeliveries(
|
|
318
|
+
before: number,
|
|
319
|
+
limit: number,
|
|
320
|
+
): Promise<readonly DeliveryRouting[]>;
|
|
321
|
+
/**
|
|
322
|
+
* Cross-tenant tenant list for retention, routing columns only. `after` is
|
|
323
|
+
* the last tenant id the previous page ended on, so a deployment with more
|
|
324
|
+
* tenants than one page still gets every one of them swept in turn.
|
|
325
|
+
*/
|
|
326
|
+
listDeliveryTenants(limit: number, after: string): Promise<readonly string[]>;
|
|
327
|
+
deleteCompletedDeliveriesBefore(
|
|
328
|
+
tenantId: string,
|
|
329
|
+
before: number,
|
|
330
|
+
limit: number,
|
|
331
|
+
): Promise<number>;
|
|
332
|
+
/**
|
|
333
|
+
* Every delivery attempt of one workspace, oldest first, one keyset page at
|
|
334
|
+
* a time. The key is the row's own creation, not the mutable schedule or
|
|
335
|
+
* completion the queue works from.
|
|
336
|
+
*/
|
|
337
|
+
exportDeliveriesPage(
|
|
338
|
+
tenantId: string,
|
|
339
|
+
after: ExportCursor | null,
|
|
340
|
+
limit: number,
|
|
341
|
+
): Promise<readonly DeliveryAttempt[]>;
|
|
342
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
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 = 'notifications_webhook_subscriptions';
|
|
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 notifications_webhook_subscriptions
|
|
48
|
+
GROUP BY secret_key_id
|
|
49
|
+
ORDER BY secret_key_id`,
|
|
50
|
+
staleTenants: `SELECT tenant_id, count(*) AS row_count
|
|
51
|
+
FROM notifications_webhook_subscriptions
|
|
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 notifications_webhook_subscriptions
|
|
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, so neither it
|
|
65
|
+
nor the fingerprint moves here. */
|
|
66
|
+
reseal: `UPDATE notifications_webhook_subscriptions
|
|
67
|
+
SET secret_key_id = $1, secret_iv = $2, secret_tag = $3,
|
|
68
|
+
secret_ciphertext = $4
|
|
69
|
+
WHERE tenant_id = $5 AND id = $6 AND secret_ciphertext = $7`,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function count(value: number | bigint | string): number {
|
|
73
|
+
const normalized = Number(value);
|
|
74
|
+
if (!Number.isSafeInteger(normalized)) {
|
|
75
|
+
throw new Error('The notifications database returned an invalid count.');
|
|
76
|
+
}
|
|
77
|
+
return normalized;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Re-seals every stored webhook signing secret that is not on the current key.
|
|
82
|
+
* The inventory is read once across tenants, and each batch of rows is read,
|
|
83
|
+
* decrypted, re-sealed and written inside one transaction scoped to the tenant
|
|
84
|
+
* that owns them. It is idempotent: a second run finds nothing to do.
|
|
85
|
+
*/
|
|
86
|
+
export async function rotateWebhookSecrets(
|
|
87
|
+
options: SecretRotationOptions,
|
|
88
|
+
): Promise<SecretRotationReport> {
|
|
89
|
+
const currentKeyId = options.vault.keyId;
|
|
90
|
+
const batchSize = options.batchSize ?? SECRET_ROTATION_BATCH;
|
|
91
|
+
const inventory = await options.background.transaction(
|
|
92
|
+
async (transaction) => ({
|
|
93
|
+
counts: (
|
|
94
|
+
await transaction.query<{
|
|
95
|
+
key_id: string;
|
|
96
|
+
row_count: number | bigint | string;
|
|
97
|
+
}>({ text: SQL.counts })
|
|
98
|
+
).rows,
|
|
99
|
+
stale: (
|
|
100
|
+
await transaction.query<{
|
|
101
|
+
tenant_id: string;
|
|
102
|
+
row_count: number | bigint | string;
|
|
103
|
+
}>({ text: SQL.staleTenants, parameters: [currentKeyId] })
|
|
104
|
+
).rows,
|
|
105
|
+
}),
|
|
106
|
+
{ access: 'read' },
|
|
107
|
+
);
|
|
108
|
+
const report = {
|
|
109
|
+
table: SECRET_ROTATION_TABLE,
|
|
110
|
+
currentKeyId,
|
|
111
|
+
counts: inventory.counts.map((row) => ({
|
|
112
|
+
keyId: row.key_id,
|
|
113
|
+
rows: count(row.row_count),
|
|
114
|
+
})),
|
|
115
|
+
stale: inventory.stale.reduce(
|
|
116
|
+
(total, row) => total + count(row.row_count),
|
|
117
|
+
0,
|
|
118
|
+
),
|
|
119
|
+
tenants: inventory.stale.length,
|
|
120
|
+
};
|
|
121
|
+
if (options.apply !== true) {
|
|
122
|
+
return { ...report, rotated: 0, skipped: 0 };
|
|
123
|
+
}
|
|
124
|
+
let rotated = 0;
|
|
125
|
+
let skipped = 0;
|
|
126
|
+
for (const { tenant_id: tenantId } of inventory.stale) {
|
|
127
|
+
let cursor = '';
|
|
128
|
+
for (;;) {
|
|
129
|
+
const batch = await options.runtime.transaction(
|
|
130
|
+
async (transaction) => {
|
|
131
|
+
const rows = (
|
|
132
|
+
await transaction.query<StaleRow>({
|
|
133
|
+
text: SQL.staleBatch,
|
|
134
|
+
parameters: [tenantId, currentKeyId, cursor, batchSize],
|
|
135
|
+
})
|
|
136
|
+
).rows;
|
|
137
|
+
let written = 0;
|
|
138
|
+
for (const row of rows) {
|
|
139
|
+
const context = secretContext(tenantId, row.id);
|
|
140
|
+
const sealed = options.vault.encrypt(
|
|
141
|
+
options.vault.decrypt(
|
|
142
|
+
{
|
|
143
|
+
keyId: row.secret_key_id,
|
|
144
|
+
iv: row.secret_iv,
|
|
145
|
+
tag: row.secret_tag,
|
|
146
|
+
ciphertext: row.secret_ciphertext,
|
|
147
|
+
},
|
|
148
|
+
context,
|
|
149
|
+
),
|
|
150
|
+
context,
|
|
151
|
+
);
|
|
152
|
+
const result = await transaction.execute({
|
|
153
|
+
text: SQL.reseal,
|
|
154
|
+
parameters: [
|
|
155
|
+
sealed.keyId,
|
|
156
|
+
sealed.iv,
|
|
157
|
+
sealed.tag,
|
|
158
|
+
sealed.ciphertext,
|
|
159
|
+
tenantId,
|
|
160
|
+
row.id,
|
|
161
|
+
row.secret_ciphertext,
|
|
162
|
+
],
|
|
163
|
+
});
|
|
164
|
+
written += result.affectedRows;
|
|
165
|
+
}
|
|
166
|
+
return { read: rows.length, written, last: rows.at(-1)?.id };
|
|
167
|
+
},
|
|
168
|
+
{ access: 'write', tenantId },
|
|
169
|
+
);
|
|
170
|
+
rotated += batch.written;
|
|
171
|
+
skipped += batch.read - batch.written;
|
|
172
|
+
if (batch.read < batchSize || batch.last === undefined) break;
|
|
173
|
+
cursor = batch.last;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { ...report, rotated, skipped };
|
|
177
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import {
|
|
3
|
+
closeSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
openSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
writeFileSync,
|
|
8
|
+
} from 'node:fs';
|
|
9
|
+
import { dirname } from 'node:path';
|
|
10
|
+
import {
|
|
11
|
+
createKeyring,
|
|
12
|
+
KeyringError,
|
|
13
|
+
parsePreviousKeys,
|
|
14
|
+
type Keyring,
|
|
15
|
+
} from '@flowdular/sdk/kernel';
|
|
16
|
+
import { flowdularLocalDataPath } from '@flowdular/sdk/kernel/legacy-local-state';
|
|
17
|
+
|
|
18
|
+
export interface EncryptedSecret {
|
|
19
|
+
readonly keyId: string;
|
|
20
|
+
readonly iv: string;
|
|
21
|
+
readonly tag: string;
|
|
22
|
+
readonly ciphertext: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Bytes of a generated signing secret before base64url encoding. */
|
|
26
|
+
export const WEBHOOK_SECRET_BYTES = 32;
|
|
27
|
+
/** Characters of the SHA-256 an administrator compares after a rotation. */
|
|
28
|
+
export const SECRET_FINGERPRINT_LENGTH = 32;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The additional data every webhook secret envelope is bound to. It is part of
|
|
32
|
+
* the stored envelope: a rotation engine re-sealing a row under a new key must
|
|
33
|
+
* rebuild exactly this string, so it lives with the envelope format.
|
|
34
|
+
*/
|
|
35
|
+
export function secretContext(
|
|
36
|
+
tenantId: string,
|
|
37
|
+
subscriptionId: string,
|
|
38
|
+
): string {
|
|
39
|
+
return `${tenantId}:${subscriptionId}:notifications-webhook`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function generateWebhookSecret(): string {
|
|
43
|
+
return randomBytes(WEBHOOK_SECRET_BYTES).toString('base64url');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Shown to administrators so a rotation is verifiable without the secret. */
|
|
47
|
+
export function secretFingerprint(secret: string): string {
|
|
48
|
+
return createHash('sha256')
|
|
49
|
+
.update(secret, 'utf8')
|
|
50
|
+
.digest('hex')
|
|
51
|
+
.slice(0, SECRET_FINGERPRINT_LENGTH);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface SecretVault {
|
|
55
|
+
/** Key id every new envelope is written with; stored rows may carry older ones. */
|
|
56
|
+
readonly keyId: string;
|
|
57
|
+
encrypt(secret: string, context: string): EncryptedSecret;
|
|
58
|
+
decrypt(envelope: EncryptedSecret, context: string): string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function encryptionKey(
|
|
62
|
+
value: string,
|
|
63
|
+
variable = 'FD_NOTIFICATIONS_SECRET_KEY',
|
|
64
|
+
): Buffer {
|
|
65
|
+
const key = Buffer.from(value.trim(), 'base64');
|
|
66
|
+
if (key.byteLength !== 32) {
|
|
67
|
+
key.fill(0);
|
|
68
|
+
throw new Error(`${variable} must be a base64-encoded 32-byte key.`);
|
|
69
|
+
}
|
|
70
|
+
return key;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export class AesGcmSecretVault implements SecretVault {
|
|
74
|
+
readonly #keyring: Keyring;
|
|
75
|
+
|
|
76
|
+
/* `previous` holds the keys a rotation has not finished retiring: they open
|
|
77
|
+
stored rows, and nothing is ever written with them. */
|
|
78
|
+
constructor(key: Buffer, previous: readonly Buffer[] = []) {
|
|
79
|
+
if (key.byteLength !== 32) {
|
|
80
|
+
throw new Error('Webhook secret encryption requires a 32-byte key.');
|
|
81
|
+
}
|
|
82
|
+
this.#keyring = createKeyring({ current: key, previous });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get keyId(): string {
|
|
86
|
+
return this.#keyring.keyId;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
encrypt(secret: string, context: string): EncryptedSecret {
|
|
90
|
+
const normalized = secret.trim();
|
|
91
|
+
if (normalized.length < 8 || normalized.length > 16_384) {
|
|
92
|
+
throw new Error('Webhook secrets must contain 8 to 16384 characters.');
|
|
93
|
+
}
|
|
94
|
+
const sealed = this.#keyring.seal(normalized, context);
|
|
95
|
+
return {
|
|
96
|
+
keyId: sealed.keyId,
|
|
97
|
+
iv: sealed.iv.toString('base64'),
|
|
98
|
+
tag: sealed.tag.toString('base64'),
|
|
99
|
+
ciphertext: sealed.ciphertext.toString('base64'),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
decrypt(envelope: EncryptedSecret, context: string): string {
|
|
104
|
+
try {
|
|
105
|
+
return this.#keyring
|
|
106
|
+
.open(
|
|
107
|
+
{
|
|
108
|
+
keyId: envelope.keyId,
|
|
109
|
+
iv: Buffer.from(envelope.iv, 'base64'),
|
|
110
|
+
tag: Buffer.from(envelope.tag, 'base64'),
|
|
111
|
+
ciphertext: Buffer.from(envelope.ciphertext, 'base64'),
|
|
112
|
+
},
|
|
113
|
+
context,
|
|
114
|
+
)
|
|
115
|
+
.toString('utf8');
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error instanceof KeyringError && error.code === 'KEY_UNKNOWN') {
|
|
118
|
+
throw new Error('The webhook secret encryption key is unavailable.', {
|
|
119
|
+
cause: error,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function developmentKey(path: string): Buffer {
|
|
128
|
+
try {
|
|
129
|
+
return encryptionKey(readFileSync(path, 'utf8'));
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
|
|
132
|
+
}
|
|
133
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
134
|
+
const descriptor = openSync(path, 'wx', 0o600);
|
|
135
|
+
try {
|
|
136
|
+
const encoded = randomBytes(32).toString('base64');
|
|
137
|
+
writeFileSync(descriptor, encoded, { encoding: 'utf8' });
|
|
138
|
+
return encryptionKey(encoded);
|
|
139
|
+
} finally {
|
|
140
|
+
closeSync(descriptor);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function secretVaultFromEnvironment(
|
|
145
|
+
environment: NodeJS.ProcessEnv = process.env,
|
|
146
|
+
workspaceRoot = process.cwd(),
|
|
147
|
+
): SecretVault {
|
|
148
|
+
const previous = parsePreviousKeys(
|
|
149
|
+
environment.FD_NOTIFICATIONS_SECRET_KEY_PREVIOUS,
|
|
150
|
+
(entry) => encryptionKey(entry, 'FD_NOTIFICATIONS_SECRET_KEY_PREVIOUS'),
|
|
151
|
+
);
|
|
152
|
+
const configured = environment.FD_NOTIFICATIONS_SECRET_KEY;
|
|
153
|
+
if (configured) {
|
|
154
|
+
return new AesGcmSecretVault(encryptionKey(configured), previous);
|
|
155
|
+
}
|
|
156
|
+
if (environment.NODE_ENV === 'production') {
|
|
157
|
+
throw new Error('FD_NOTIFICATIONS_SECRET_KEY is required in production.');
|
|
158
|
+
}
|
|
159
|
+
if (environment.NODE_ENV === 'test') {
|
|
160
|
+
return new AesGcmSecretVault(Buffer.alloc(32, 0x4e), previous);
|
|
161
|
+
}
|
|
162
|
+
return new AesGcmSecretVault(
|
|
163
|
+
developmentKey(
|
|
164
|
+
flowdularLocalDataPath(workspaceRoot, 'notifications-secret.key'),
|
|
165
|
+
),
|
|
166
|
+
previous,
|
|
167
|
+
);
|
|
168
|
+
}
|