@flowdular/sdk 0.2.4 → 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 +2 -1
- package/modules/agents/spec/module.yaml +63 -5
- package/modules/agents/src/api/endpoints.ts +291 -33
- package/modules/agents/src/cli/commands.json +11 -0
- package/modules/agents/src/cli/index.ts +45 -0
- package/modules/agents/src/client/AgentDashboardWidget.tsrx +19 -11
- package/modules/agents/src/client/AgentDefinitionList.tsrx +53 -10
- package/modules/agents/src/client/AgentPlaygroundView.tsrx +4 -4
- package/modules/agents/src/client/AgentProceduresView.tsrx +2 -2
- package/modules/agents/src/client/AgentRunsView.tsrx +143 -40
- package/modules/agents/src/client/AgentsView.tsrx +109 -33
- package/modules/agents/src/client/api.ts +99 -21
- package/modules/agents/src/client/state.ts +97 -0
- package/modules/agents/src/domain/types.ts +44 -4
- package/modules/agents/src/platform.ts +42 -0
- package/modules/agents/src/server/action-execution.ts +201 -106
- package/modules/agents/src/server/runtime.ts +32 -0
- package/modules/agents/src/services/agent-service.ts +158 -30
- package/modules/agents/src/services/credential-rotation.ts +185 -0
- package/modules/agents/src/services/credential-vault.ts +71 -46
- package/modules/agents/src/services/data-classes.ts +176 -0
- package/modules/agents/src/services/database-repository.ts +393 -101
- package/modules/agents/src/services/metering.ts +111 -0
- package/modules/agents/src/services/migration.ts +109 -0
- package/modules/agents/src/services/module-agent-preflight.ts +17 -9
- package/modules/agents/src/services/notifications.ts +98 -0
- package/modules/agents/src/services/provider-repository.ts +9 -18
- package/modules/agents/src/services/provider-service.ts +1 -9
- package/modules/agents/src/services/reports.ts +107 -0
- package/modules/agents/src/services/repository.ts +86 -6
- package/modules/agents/src/services/usage-service.ts +2 -0
- package/modules/agents/src/services/worker.ts +114 -4
- package/modules/agents/src/settings.ts +14 -3
- package/modules/agents/translations/en.json +14 -4
- package/modules/agents/translations/pl.json +14 -4
- package/modules/approvals/migrations/0001_approvals_core.down.sql +3 -0
- package/modules/approvals/migrations/0001_approvals_core.up.sql +78 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.down.sql +2 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.up.sql +19 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.down.sql +6 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.up.sql +14 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.down.sql +5 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.up.sql +12 -0
- package/modules/approvals/migrations/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 +2 -1
- package/modules/auth/spec/module.yaml +372 -3
- package/modules/auth/src/acl/scopes.ts +50 -6
- package/modules/auth/src/cli/commands.json +11 -0
- package/modules/auth/src/cli/greenfield.ts +2 -2
- package/modules/auth/src/cli/index.ts +14 -0
- package/modules/auth/src/cli/secrets.ts +114 -0
- package/modules/auth/src/client/AuthenticationCore.tsrx +61 -8
- package/modules/auth/src/client/api.ts +72 -6
- package/modules/auth/src/client/contribution.tsrx +23 -0
- package/modules/auth/src/client/index.ts +6 -0
- package/modules/auth/src/client/providers/IdentityProviderForm.tsrx +191 -0
- package/modules/auth/src/client/providers/IdentityProvidersView.tsrx +358 -0
- package/modules/auth/src/client/providers/api.ts +128 -0
- package/modules/auth/src/client/providers/provider-columns.tsrx +60 -0
- package/modules/auth/src/client/providers/state.ts +35 -0
- package/modules/auth/src/client/security/SecurityView.tsrx +9 -1
- package/modules/auth/src/client/state.ts +15 -1
- package/modules/auth/src/domain/types.ts +55 -0
- package/modules/auth/src/index.ts +11 -1
- package/modules/auth/src/middleware/authentication.ts +4 -0
- package/modules/auth/src/server/endpoints.ts +467 -171
- package/modules/auth/src/server/http.ts +3 -2
- package/modules/auth/src/server/index.ts +22 -1
- package/modules/auth/src/server/membership-endpoints.ts +62 -0
- package/modules/auth/src/server/mfa-enforcement.ts +156 -0
- package/modules/auth/src/server/oidc.ts +389 -0
- package/modules/auth/src/server/provider-endpoints.ts +246 -0
- package/modules/auth/src/server/provider-host.ts +77 -0
- package/modules/auth/src/server/runtime.ts +231 -55
- package/modules/auth/src/services/auth-service-error.ts +7 -2
- package/modules/auth/src/services/auth-service.ts +948 -51
- package/modules/auth/src/services/data-classes.ts +236 -0
- package/modules/auth/src/services/database-repository.ts +853 -71
- package/modules/auth/src/services/identity-provider-service.ts +571 -0
- package/modules/auth/src/services/mail-delivery.ts +16 -16
- package/modules/auth/src/services/mail-message.ts +54 -0
- package/modules/auth/src/services/mail-port.ts +24 -0
- package/modules/auth/src/services/mail-smtp.ts +85 -0
- package/modules/auth/src/services/mfa-rotation.ts +144 -0
- package/modules/auth/src/services/migration.ts +810 -0
- package/modules/auth/src/services/password.ts +14 -0
- package/modules/auth/src/services/provider-secret-rotation.ts +169 -0
- package/modules/auth/src/services/provider-secrets.ts +136 -0
- package/modules/auth/src/services/repository.ts +321 -5
- package/modules/auth/src/services/session-sweep-runner.ts +73 -0
- package/modules/auth/src/services/settings-store.ts +10 -83
- package/modules/auth/src/services/totp.ts +88 -62
- package/modules/auth/src/services/validation.ts +194 -7
- package/modules/auth/src/settings.ts +18 -0
- package/modules/auth/translations/en.json +84 -1
- package/modules/auth/translations/pl.json +84 -1
- package/modules/automations/migrations/0005_secret_rotation_inventory.down.sql +1 -0
- package/modules/automations/migrations/0005_secret_rotation_inventory.up.sql +6 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.down.sql +4 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.up.sql +11 -0
- package/modules/automations/module.json +24 -6
- package/modules/automations/package.json +4 -1
- package/modules/automations/spec/module.yaml +81 -7
- package/modules/automations/src/api/endpoints.ts +202 -28
- package/modules/automations/src/cli/commands.json +17 -0
- package/modules/automations/src/cli/index.ts +114 -0
- package/modules/automations/src/client/AutomationScheduleForm.tsrx +77 -19
- package/modules/automations/src/client/AutomationSchedulesView.tsrx +144 -40
- package/modules/automations/src/client/AutomationTriggersView.tsrx +131 -32
- package/modules/automations/src/client/api.ts +62 -19
- package/modules/automations/src/client/presentation.ts +20 -2
- package/modules/automations/src/client/state.ts +84 -0
- package/modules/automations/src/domain/cadence.ts +99 -3
- package/modules/automations/src/domain/cron.ts +366 -0
- package/modules/automations/src/domain/time-zone.ts +61 -0
- package/modules/automations/src/platform.ts +38 -4
- package/modules/automations/src/server/index.ts +11 -0
- package/modules/automations/src/server/runtime.ts +46 -22
- package/modules/{automations-workflows-integration/src/server/adapter.ts → automations/src/server/workflow-target.ts} +13 -14
- package/modules/{automations-workflows-integration/src/server/tools.ts → automations/src/server/workflow-tools.ts} +0 -0
- package/modules/automations/src/services/data-classes.ts +62 -0
- package/modules/automations/src/services/database-repository.ts +152 -38
- package/modules/automations/src/services/migration.ts +119 -9
- package/modules/automations/src/services/repository.ts +52 -1
- package/modules/automations/src/services/schedule-runner.ts +84 -0
- package/modules/automations/src/services/schedule-service.ts +152 -26
- package/modules/automations/src/services/secret-rotation.ts +176 -0
- package/modules/automations/src/services/secret-vault.ts +68 -41
- package/modules/automations/src/services/trigger-service.ts +13 -10
- package/modules/automations/translations/en.json +15 -2
- package/modules/automations/translations/pl.json +15 -2
- package/modules/connectors/migrations/0001_connectors_core.down.sql +3 -0
- package/modules/connectors/migrations/0001_connectors_core.up.sql +72 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.down.sql +3 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.up.sql +18 -0
- package/modules/connectors/migrations/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 +1 -1
- package/modules/profile/spec/module.yaml +3 -3
- package/modules/profile/src/services/database-repository.ts +3 -13
- package/modules/reports/module.json +28 -0
- package/modules/reports/package.json +42 -0
- package/modules/reports/spec/module.yaml +231 -0
- package/modules/reports/src/acl/permissions.ts +5 -0
- package/modules/reports/src/api/endpoints.ts +72 -0
- package/modules/reports/src/client/ReportsSummaryWidget.tsrx +52 -0
- package/modules/reports/src/client/ReportsView.tsrx +246 -0
- package/modules/reports/src/client/api.ts +65 -0
- package/modules/reports/src/client/contribution.tsrx +36 -0
- package/modules/reports/src/client/index.ts +18 -0
- package/modules/reports/src/client/navigation.ts +39 -0
- package/modules/reports/src/client/presentation.ts +123 -0
- package/modules/reports/src/client/state.ts +28 -0
- package/modules/reports/src/domain/providers.ts +115 -0
- package/modules/reports/src/domain/types.ts +44 -0
- package/modules/reports/src/index.ts +47 -0
- package/modules/reports/src/platform.ts +37 -0
- package/modules/reports/src/server/index.ts +21 -0
- package/modules/reports/src/server/runtime.ts +40 -0
- package/modules/reports/src/services/index.ts +17 -0
- package/modules/reports/src/services/provider-registry.ts +144 -0
- package/modules/reports/src/services/range.ts +65 -0
- package/modules/reports/src/services/reports-service.ts +316 -0
- package/modules/reports/src/services/service-error.ts +26 -0
- package/modules/reports/src/settings.ts +49 -0
- package/modules/reports/translations/en.json +35 -0
- package/modules/reports/translations/pl.json +35 -0
- package/modules/sandbox/module.json +4 -4
- package/modules/sandbox/package.json +1 -1
- package/modules/sandbox/spec/module.yaml +3 -3
- package/modules/sandbox/src/services/database-repository.ts +14 -23
- package/modules/sandbox/src/services/directory.ts +16 -0
- package/modules/sandbox/src/services/sandbox-service.ts +13 -11
- package/modules/search/migrations/0001_search_core.down.sql +1 -0
- package/modules/search/migrations/0001_search_core.up.sql +22 -0
- package/modules/search/migrations/0002_search_recent_export.down.sql +3 -0
- package/modules/search/migrations/0002_search_recent_export.up.sql +5 -0
- package/modules/search/migrations/README.md +3 -0
- package/modules/search/module.json +28 -0
- package/modules/search/package.json +43 -0
- package/modules/search/spec/module.yaml +177 -0
- package/modules/search/src/acl/permissions.ts +5 -0
- package/modules/search/src/api/endpoints.ts +221 -0
- package/modules/search/src/client/SearchView.tsrx +346 -0
- package/modules/search/src/client/api.ts +157 -0
- package/modules/search/src/client/contribution.tsrx +31 -0
- package/modules/search/src/client/index.ts +17 -0
- package/modules/search/src/client/navigation.ts +97 -0
- package/modules/search/src/client/search.css +56 -0
- package/modules/search/src/client/state.ts +113 -0
- package/modules/search/src/domain/data-classes.ts +73 -0
- package/modules/search/src/domain/providers.ts +88 -0
- package/modules/search/src/domain/types.ts +56 -0
- package/modules/search/src/index.ts +46 -0
- package/modules/search/src/platform.ts +42 -0
- package/modules/search/src/server/index.ts +25 -0
- package/modules/search/src/server/runtime.ts +123 -0
- package/modules/search/src/services/database-repository.ts +163 -0
- package/modules/search/src/services/index.ts +21 -0
- package/modules/search/src/services/migration.ts +65 -0
- package/modules/search/src/services/provider-registry.ts +137 -0
- package/modules/search/src/services/repository.ts +43 -0
- package/modules/search/src/services/search-service.ts +442 -0
- package/modules/search/src/services/service-error.ts +35 -0
- package/modules/search/src/settings.ts +68 -0
- package/modules/search/translations/en.json +45 -0
- package/modules/search/translations/pl.json +45 -0
- package/modules/system/module.json +2 -2
- package/modules/system/package.json +1 -1
- package/modules/system/spec/module.yaml +30 -3
- package/modules/system/src/client/FlagsPanel.tsrx +127 -0
- package/modules/system/src/client/ModuleSettingRow.tsrx +17 -7
- package/modules/system/src/client/ModuleSettingsSection.tsrx +10 -71
- package/modules/system/src/client/ModulesView.tsrx +91 -65
- package/modules/system/src/client/flags.ts +35 -0
- package/modules/system/src/client/index.ts +8 -0
- package/modules/system/src/client/navigation.ts +8 -0
- package/modules/system/src/client/settings-state.ts +159 -0
- package/modules/system/src/client/state.ts +2 -0
- package/modules/system/src/domain/time-zone.ts +105 -0
- package/modules/system/src/index.ts +12 -0
- package/modules/system/src/platform.ts +5 -1
- package/modules/system/src/server/endpoints.ts +72 -21
- package/modules/system/src/settings.ts +28 -0
- package/modules/system/translations/en.json +17 -0
- package/modules/system/translations/pl.json +17 -0
- package/modules/users/module.json +30 -4
- package/modules/users/package.json +4 -1
- package/modules/users/spec/module.yaml +290 -7
- package/modules/users/src/api/endpoints.ts +228 -15
- package/modules/users/src/client/InviteMemberForm.tsrx +2 -2
- package/modules/users/src/client/MemberDrawer.tsrx +142 -26
- package/modules/users/src/client/UserAccountForm.tsrx +2 -2
- package/modules/users/src/client/UsersView.tsrx +432 -71
- package/modules/users/src/client/api.ts +106 -12
- package/modules/users/src/client/contribution.tsrx +5 -0
- package/modules/users/src/client/member-columns.tsrx +22 -9
- package/modules/users/src/client/state.ts +172 -7
- package/modules/users/src/domain/lists.ts +9 -0
- package/modules/users/src/index.ts +11 -0
- package/modules/users/src/platform.ts +50 -1
- package/modules/users/src/services/member-export.ts +51 -0
- package/modules/users/src/services/member-import.ts +249 -0
- package/modules/users/src/services/member-search.ts +145 -0
- package/modules/users/src/services/users-service.ts +117 -4
- package/modules/users/translations/en.json +57 -8
- package/modules/users/translations/pl.json +57 -8
- package/modules/workflows/migrations/0004_payload_rotation_inventory.up.sql +17 -0
- package/modules/workflows/migrations/0005_workflows_human_approval.up.sql +28 -0
- package/modules/workflows/migrations/0006_workflows_retention_indexes.up.sql +11 -0
- package/modules/workflows/migrations/0007_workflows_erasure_subject_indexes.up.sql +17 -0
- package/modules/workflows/migrations/0008_workflows_subject_account.up.sql +24 -0
- package/modules/workflows/migrations/0009_workflows_definition_list_indexes.up.sql +9 -0
- package/modules/workflows/module.json +34 -6
- package/modules/workflows/package.json +2 -1
- package/modules/workflows/spec/module.yaml +26 -9
- package/modules/workflows/src/api/endpoints.ts +131 -25
- package/modules/workflows/src/cli/commands.json +17 -0
- package/modules/workflows/src/cli/index.ts +114 -0
- package/modules/workflows/src/client/WorkflowExecutionHistory.tsrx +36 -27
- package/modules/workflows/src/client/WorkflowInspector.tsrx +116 -0
- package/modules/workflows/src/client/WorkflowNodePalette.tsrx +1 -0
- package/modules/workflows/src/client/WorkflowsView.tsrx +236 -99
- package/modules/workflows/src/client/api.ts +54 -34
- package/modules/workflows/src/client/canvas-model.ts +12 -0
- package/modules/workflows/src/client/state.ts +95 -0
- package/modules/workflows/src/domain/events.ts +25 -11
- package/modules/workflows/src/domain/graph.ts +135 -1
- package/modules/workflows/src/domain/types.ts +91 -4
- package/modules/workflows/src/platform.ts +12 -0
- package/modules/workflows/src/server/runtime.ts +78 -5
- package/modules/workflows/src/services/approvals.ts +62 -0
- package/modules/workflows/src/services/cursors.ts +37 -0
- package/modules/workflows/src/services/data-classes.ts +232 -0
- package/modules/workflows/src/services/database-repository.ts +660 -171
- package/modules/workflows/src/services/migration.ts +240 -0
- package/modules/workflows/src/services/notifications.ts +98 -0
- package/modules/workflows/src/services/payload-codec.ts +51 -28
- package/modules/workflows/src/services/payload-rotation.ts +171 -0
- package/modules/workflows/src/services/repository.ts +123 -8
- package/modules/workflows/src/services/simulation.ts +7 -0
- package/modules/workflows/src/services/worker.ts +446 -25
- package/modules/workflows/src/services/workflows-service.ts +264 -103
- package/modules/workflows/translations/en.json +12 -4
- package/modules/workflows/translations/pl.json +12 -4
- package/modules.json +48 -4
- package/package.json +64 -6
- package/packages/client/package.json +1 -0
- package/packages/client/src/ApplicationShell.tsrx +43 -0
- package/packages/client/src/contributions.ts +55 -0
- package/packages/client/src/i18n/locales/en.json +5 -0
- package/packages/client/src/i18n/locales/pl.json +5 -0
- package/packages/client/src/index.ts +13 -1
- package/packages/client/src/routing.ts +22 -0
- package/packages/client/src/shell/CommandPalette.tsrx +223 -11
- package/packages/client/src/shell/command-search.ts +126 -0
- package/packages/client/src/shell/command.ts +30 -0
- package/packages/client/src/shell/navigation.ts +12 -0
- package/packages/client/src/shell/palette-keys.ts +27 -0
- package/packages/client/src/shell/shell.css +7 -0
- package/packages/contracts/schemas/module-spec.schema.json +287 -1
- package/packages/contracts/schemas/module.schema.json +25 -0
- package/packages/contracts/src/index.ts +144 -1
- package/packages/database/src/backup.ts +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/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,356 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import type { AuthPrincipal } from '@flowdular/sdk/modules/auth';
|
|
3
|
+
import {
|
|
4
|
+
runListExport,
|
|
5
|
+
ListExportError,
|
|
6
|
+
type ListExportPrincipal,
|
|
7
|
+
} from '@flowdular/sdk/server';
|
|
8
|
+
import { StorageError, type StoragePort } from '@flowdular/sdk/storage';
|
|
9
|
+
import {
|
|
10
|
+
EXPORT_LIMITS,
|
|
11
|
+
EXPORT_UNEXPECTED_FAILURE,
|
|
12
|
+
type ClaimedExportJob,
|
|
13
|
+
type ExportJob,
|
|
14
|
+
type ExportListView,
|
|
15
|
+
type ExportRequester,
|
|
16
|
+
} from '../domain/types.ts';
|
|
17
|
+
import type { ExportListRegistry } from './list-registry.ts';
|
|
18
|
+
import type {
|
|
19
|
+
ExportJobPage,
|
|
20
|
+
ExportJobQuery,
|
|
21
|
+
ExportRepository,
|
|
22
|
+
} from './repository.ts';
|
|
23
|
+
|
|
24
|
+
export class ExportServiceError extends Error {
|
|
25
|
+
constructor(
|
|
26
|
+
readonly code: string,
|
|
27
|
+
message: string,
|
|
28
|
+
readonly status = 400,
|
|
29
|
+
) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = 'ExportServiceError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The module id every object of this module lives under in the storage port. */
|
|
36
|
+
export const EXPORT_OWNER_MODULE = 'exports.core';
|
|
37
|
+
|
|
38
|
+
export const EXPORT_CSV_CONTENT_TYPE = 'text/csv';
|
|
39
|
+
|
|
40
|
+
/** How long a minted read URL lives. Long enough to click, short enough to lose. */
|
|
41
|
+
export const EXPORT_READ_URL_SECONDS = 300;
|
|
42
|
+
|
|
43
|
+
export interface ExportServiceOptions {
|
|
44
|
+
readonly repository: ExportRepository;
|
|
45
|
+
readonly lists: ExportListRegistry;
|
|
46
|
+
readonly storage: StoragePort;
|
|
47
|
+
readonly maxRows: () => number;
|
|
48
|
+
readonly maxBytes: () => number;
|
|
49
|
+
/** The storage port's own object ceiling, which bounds the same bytes. */
|
|
50
|
+
readonly maxObjectBytes: () => number;
|
|
51
|
+
readonly now?: () => number;
|
|
52
|
+
readonly newId?: () => string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function requesterOf(principal: AuthPrincipal): ExportRequester {
|
|
56
|
+
const requester: ExportRequester = {
|
|
57
|
+
accountId: principal.accountId,
|
|
58
|
+
email: principal.email,
|
|
59
|
+
displayName: principal.displayName,
|
|
60
|
+
role: principal.role,
|
|
61
|
+
scopes: [...principal.scopes],
|
|
62
|
+
};
|
|
63
|
+
/* The job row bounds the snapshot at 8 KB. A principal carrying more than
|
|
64
|
+
that is refused here with a code the screen can read, rather than by the
|
|
65
|
+
column check once the job is half written. */
|
|
66
|
+
if (JSON.stringify(requester).length > EXPORT_LIMITS.json) {
|
|
67
|
+
throw new ExportServiceError(
|
|
68
|
+
'REQUESTER_TOO_LARGE',
|
|
69
|
+
'Your account carries more grants than an export job can record.',
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return requester;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The requester the list sees in the background stage. It carries the identity
|
|
77
|
+
* and the grants held when the job was started; the workspace is the job's own,
|
|
78
|
+
* and other workspace memberships are never part of an export.
|
|
79
|
+
*/
|
|
80
|
+
function principalOf(job: ExportJob): ListExportPrincipal {
|
|
81
|
+
return {
|
|
82
|
+
accountId: job.requester.accountId,
|
|
83
|
+
tenantId: job.tenantId,
|
|
84
|
+
scopes: job.requester.scopes,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* One stable code per way a stage can end badly. A storage refusal on size is
|
|
89
|
+
the byte bound the operator already knows about, reported as that bound
|
|
90
|
+
rather than as a second one underneath it. */
|
|
91
|
+
function failureCodeOf(error: unknown): string {
|
|
92
|
+
if (error instanceof ListExportError) return error.code;
|
|
93
|
+
if (error instanceof StorageError) {
|
|
94
|
+
return error.code === 'OBJECT_TOO_LARGE'
|
|
95
|
+
? 'EXPORT_BYTES_EXCEEDED'
|
|
96
|
+
: 'EXPORT_STORAGE_FAILED';
|
|
97
|
+
}
|
|
98
|
+
if (error instanceof ExportServiceError) return error.code;
|
|
99
|
+
return EXPORT_UNEXPECTED_FAILURE;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The catalogue a reader sees. It needs the sealed registry and the caller's
|
|
104
|
+
* scopes only, so the endpoint answers it without a repository or a lease.
|
|
105
|
+
*/
|
|
106
|
+
export function exportCatalogue(
|
|
107
|
+
lists: Pick<ExportListRegistry, 'list'>,
|
|
108
|
+
principal: AuthPrincipal,
|
|
109
|
+
): readonly ExportListView[] {
|
|
110
|
+
const held = new Set(principal.scopes);
|
|
111
|
+
return lists.list().map((entry) => ({
|
|
112
|
+
id: entry.id,
|
|
113
|
+
label: entry.definition.label,
|
|
114
|
+
moduleId: entry.moduleId,
|
|
115
|
+
permitted: held.has(entry.definition.permission),
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export class ExportService {
|
|
120
|
+
readonly #repository: ExportRepository;
|
|
121
|
+
readonly #lists: ExportListRegistry;
|
|
122
|
+
readonly #storage: StoragePort;
|
|
123
|
+
readonly #maxRows: () => number;
|
|
124
|
+
readonly #maxBytes: () => number;
|
|
125
|
+
readonly #maxObjectBytes: () => number;
|
|
126
|
+
readonly #now: () => number;
|
|
127
|
+
readonly #newId: () => string;
|
|
128
|
+
|
|
129
|
+
constructor(options: ExportServiceOptions) {
|
|
130
|
+
this.#repository = options.repository;
|
|
131
|
+
this.#lists = options.lists;
|
|
132
|
+
this.#storage = options.storage;
|
|
133
|
+
this.#maxRows = options.maxRows;
|
|
134
|
+
this.#maxBytes = options.maxBytes;
|
|
135
|
+
this.#maxObjectBytes = options.maxObjectBytes;
|
|
136
|
+
this.#now = options.now ?? (() => Date.now());
|
|
137
|
+
this.#newId = options.newId ?? (() => randomUUID());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* The storage port refuses an object above its own ceiling, and it counts the
|
|
141
|
+
same plaintext bytes the walk does. A walk bounded above the ceiling would
|
|
142
|
+
read the list to its end and build the whole file only to have the write
|
|
143
|
+
refused, so the lower of the two is applied before the first page. Both
|
|
144
|
+
refusals are reported under EXPORT_BYTES_EXCEEDED either way. */
|
|
145
|
+
#bytesBound(): number {
|
|
146
|
+
return Math.min(this.#maxBytes(), this.#maxObjectBytes());
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async start(principal: AuthPrincipal, listId: string): Promise<ExportJob> {
|
|
150
|
+
const registered = this.#lists.find(listId);
|
|
151
|
+
if (!registered) {
|
|
152
|
+
throw new ExportServiceError(
|
|
153
|
+
'EXPORT_LIST_UNKNOWN',
|
|
154
|
+
'No module registered a list export under that id.',
|
|
155
|
+
404,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
/* The list's own permission, checked on the acting principal before
|
|
159
|
+
anything is recorded, so an export never widens what a member may
|
|
160
|
+
read. */
|
|
161
|
+
if (!principal.scopes.includes(registered.definition.permission)) {
|
|
162
|
+
throw new ExportServiceError(
|
|
163
|
+
'EXPORT_LIST_FORBIDDEN',
|
|
164
|
+
'You do not hold the permission this list requires.',
|
|
165
|
+
403,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const startedAt = this.#now();
|
|
169
|
+
return this.#repository.createJob({
|
|
170
|
+
id: this.#newId(),
|
|
171
|
+
tenantId: principal.tenantId,
|
|
172
|
+
listId: registered.id,
|
|
173
|
+
status: 'requested',
|
|
174
|
+
rowCount: 0,
|
|
175
|
+
byteCount: 0,
|
|
176
|
+
objectId: null,
|
|
177
|
+
requesterAccountId: principal.accountId,
|
|
178
|
+
requester: requesterOf(principal),
|
|
179
|
+
failureCode: null,
|
|
180
|
+
claimedAt: null,
|
|
181
|
+
startedAt,
|
|
182
|
+
completedAt: null,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The catalogue as one principal sees it: every registered list, each marked
|
|
188
|
+
* with whether that principal holds the permission the list declares. The
|
|
189
|
+
* permission is decided again on the live principal when a job is started, so
|
|
190
|
+
* this is what a screen offers and never what authorizes an export.
|
|
191
|
+
*/
|
|
192
|
+
jobs(tenantId: string, query: ExportJobQuery): Promise<ExportJobPage> {
|
|
193
|
+
return this.#repository.listJobs(tenantId, query);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async job(tenantId: string, id: string): Promise<ExportJob> {
|
|
197
|
+
const job = await this.#repository.findJob(tenantId, id);
|
|
198
|
+
if (!job) {
|
|
199
|
+
throw new ExportServiceError(
|
|
200
|
+
'EXPORT_JOB_NOT_FOUND',
|
|
201
|
+
'That export job does not exist in this workspace.',
|
|
202
|
+
404,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
return job;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* A signed platform route for the file of a completed job. It is minted per
|
|
210
|
+
* request and never stored, so a signed credential does not reach a log line
|
|
211
|
+
* or a page of results.
|
|
212
|
+
*/
|
|
213
|
+
async readUrl(principal: AuthPrincipal, id: string): Promise<string> {
|
|
214
|
+
const tenantId = principal.tenantId;
|
|
215
|
+
const job = await this.job(tenantId, id);
|
|
216
|
+
/* The file holds the rows of the exported list, so opening it needs that
|
|
217
|
+
list's own permission on the live principal and not only the permission
|
|
218
|
+
to read jobs. Otherwise a member who may see the job list could download
|
|
219
|
+
rows the list itself would never have shown them, and a grant revoked
|
|
220
|
+
after the export would still hand the file over. */
|
|
221
|
+
const registered = this.#lists.find(job.listId);
|
|
222
|
+
if (!registered) {
|
|
223
|
+
throw new ExportServiceError(
|
|
224
|
+
'EXPORT_LIST_UNKNOWN',
|
|
225
|
+
'No module registered the list this file was exported from.',
|
|
226
|
+
404,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (!principal.scopes.includes(registered.definition.permission)) {
|
|
230
|
+
throw new ExportServiceError(
|
|
231
|
+
'EXPORT_LIST_FORBIDDEN',
|
|
232
|
+
'You do not hold the permission this list requires.',
|
|
233
|
+
403,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
const objectId = job.objectId;
|
|
237
|
+
if (job.status !== 'completed' || objectId === null) {
|
|
238
|
+
throw new ExportServiceError(
|
|
239
|
+
'EXPORT_NOT_READY',
|
|
240
|
+
'That export has no file to open.',
|
|
241
|
+
409,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
const reference = {
|
|
245
|
+
tenantId,
|
|
246
|
+
moduleId: EXPORT_OWNER_MODULE,
|
|
247
|
+
objectId,
|
|
248
|
+
};
|
|
249
|
+
/* Retention deletes the object before its row, so a job can name a file
|
|
250
|
+
that is already gone; the reader is told that rather than handed a URL
|
|
251
|
+
that answers nothing. */
|
|
252
|
+
if ((await this.#storage.stat(reference)) === null) {
|
|
253
|
+
throw new ExportServiceError(
|
|
254
|
+
'EXPORT_OBJECT_GONE',
|
|
255
|
+
'That export file is no longer stored.',
|
|
256
|
+
404,
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
return this.#storage.readUrl({
|
|
260
|
+
...reference,
|
|
261
|
+
expiresInSeconds: EXPORT_READ_URL_SECONDS,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* One claimed job: walk the list under the requester's snapshot, write the
|
|
267
|
+
* file and settle. It never throws for work it performed; a claim taken over
|
|
268
|
+
* mid-stage settles nothing and leaves the job to whoever holds it now.
|
|
269
|
+
*/
|
|
270
|
+
async perform(job: ClaimedExportJob, signal: AbortSignal): Promise<void> {
|
|
271
|
+
const registered = this.#lists.find(job.listId);
|
|
272
|
+
if (!registered) {
|
|
273
|
+
/* A list that was registered when the job started and is not any more
|
|
274
|
+
means the module was disabled between the two. */
|
|
275
|
+
await this.#fail(job, 'EXPORT_LIST_UNKNOWN');
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
let objectId: string | null = null;
|
|
279
|
+
let recorded = false;
|
|
280
|
+
try {
|
|
281
|
+
const result = await runListExport({
|
|
282
|
+
definition: registered.definition,
|
|
283
|
+
principal: principalOf(job),
|
|
284
|
+
bounds: { maxRows: this.#maxRows(), maxBytes: this.#bytesBound() },
|
|
285
|
+
signal,
|
|
286
|
+
});
|
|
287
|
+
/* Nothing is written for a claim this stage no longer holds. */
|
|
288
|
+
signal.throwIfAborted();
|
|
289
|
+
objectId = this.#newId();
|
|
290
|
+
const stored = await this.#storage.put({
|
|
291
|
+
tenantId: job.tenantId,
|
|
292
|
+
moduleId: EXPORT_OWNER_MODULE,
|
|
293
|
+
objectId,
|
|
294
|
+
contentType: EXPORT_CSV_CONTENT_TYPE,
|
|
295
|
+
body: result.body,
|
|
296
|
+
declaredBytes: result.bytes,
|
|
297
|
+
});
|
|
298
|
+
const settled = await this.#repository.settleJob(job.tenantId, job.id, {
|
|
299
|
+
status: 'completed',
|
|
300
|
+
rowCount: result.rows,
|
|
301
|
+
byteCount: stored.bytes,
|
|
302
|
+
objectId,
|
|
303
|
+
failureCode: null,
|
|
304
|
+
completedAt: this.#now(),
|
|
305
|
+
});
|
|
306
|
+
recorded = settled !== null;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (!signal.aborted) await this.#fail(job, failureCodeOf(error));
|
|
309
|
+
} finally {
|
|
310
|
+
/* Every way this stage can end without the job row naming the object:
|
|
311
|
+
the claim changed hands, the settle raised, the abort landed between
|
|
312
|
+
the write and the settle, or the stage failed after the file existed.
|
|
313
|
+
In each of them nothing would ever reference the object and no sweep
|
|
314
|
+
would ever find it, so it goes now. */
|
|
315
|
+
if (objectId !== null && !recorded) {
|
|
316
|
+
await this.#discard(job.tenantId, objectId);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async #fail(job: ClaimedExportJob, failureCode: string): Promise<void> {
|
|
322
|
+
await this.#repository.settleJob(job.tenantId, job.id, {
|
|
323
|
+
status: 'failed',
|
|
324
|
+
rowCount: 0,
|
|
325
|
+
byteCount: 0,
|
|
326
|
+
objectId: null,
|
|
327
|
+
failureCode,
|
|
328
|
+
completedAt: this.#now(),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* Best effort: a file that could not be deleted is one the retention sweep
|
|
333
|
+
never sees, but failing the stage over it would settle a job whose work is
|
|
334
|
+
already decided. */
|
|
335
|
+
async #discard(tenantId: string, objectId: string): Promise<void> {
|
|
336
|
+
try {
|
|
337
|
+
await this.#storage.delete({
|
|
338
|
+
tenantId,
|
|
339
|
+
moduleId: EXPORT_OWNER_MODULE,
|
|
340
|
+
objectId,
|
|
341
|
+
});
|
|
342
|
+
} catch {
|
|
343
|
+
/* The object outlives its job; nothing else depends on the delete. */
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** Deletes the files of a swept batch before its rows go. */
|
|
348
|
+
async discardObjects(
|
|
349
|
+
tenantId: string,
|
|
350
|
+
objectIds: readonly string[],
|
|
351
|
+
): Promise<void> {
|
|
352
|
+
for (const objectId of objectIds) {
|
|
353
|
+
await this.#discard(tenantId, objectId);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { DefinedListExport } from '@flowdular/sdk/server';
|
|
2
|
+
import { EXPORT_LIST_LIMITS, type ExportLists } from '../domain/lists.ts';
|
|
3
|
+
|
|
4
|
+
export class ExportListError extends Error {
|
|
5
|
+
constructor(
|
|
6
|
+
readonly code: string,
|
|
7
|
+
message: string,
|
|
8
|
+
readonly status = 400,
|
|
9
|
+
) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'ExportListError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** A registered list and the module that declared it. */
|
|
16
|
+
export interface RegisteredExportList {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly moduleId: string;
|
|
19
|
+
readonly definition: DefinedListExport;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ExportListRegistry extends ExportLists {
|
|
23
|
+
/** Closes registration. Every later `register` throws. */
|
|
24
|
+
seal(): void;
|
|
25
|
+
find(id: string): RegisteredExportList | null;
|
|
26
|
+
list(): readonly RegisteredExportList[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The lists a workspace can export. Registration is open while the platform
|
|
31
|
+
* composes and sealed before the first request, so the catalogue a job was
|
|
32
|
+
* started against cannot change under it. Lookup is a map read, O(1).
|
|
33
|
+
*/
|
|
34
|
+
export function createExportListRegistry(): ExportListRegistry {
|
|
35
|
+
const lists = new Map<string, RegisteredExportList>();
|
|
36
|
+
let sealed = false;
|
|
37
|
+
return {
|
|
38
|
+
register(moduleId, registered) {
|
|
39
|
+
if (sealed) {
|
|
40
|
+
throw new ExportListError(
|
|
41
|
+
'EXPORT_LISTS_SEALED',
|
|
42
|
+
'List exports are registered while the platform composes.',
|
|
43
|
+
500,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (
|
|
47
|
+
typeof moduleId !== 'string' ||
|
|
48
|
+
moduleId.length === 0 ||
|
|
49
|
+
moduleId.length > EXPORT_LIST_LIMITS.moduleId
|
|
50
|
+
) {
|
|
51
|
+
throw new ExportListError(
|
|
52
|
+
'EXPORT_LIST_INVALID',
|
|
53
|
+
`A module id is 1 to ${EXPORT_LIST_LIMITS.moduleId} characters.`,
|
|
54
|
+
500,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (registered.length > EXPORT_LIST_LIMITS.listsPerModule) {
|
|
58
|
+
throw new ExportListError(
|
|
59
|
+
'EXPORT_LIST_INVALID',
|
|
60
|
+
`A module registers at most ${EXPORT_LIST_LIMITS.listsPerModule} lists.`,
|
|
61
|
+
500,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
for (const definition of registered) {
|
|
65
|
+
/* The id is the registrar's own namespace. Without this a module
|
|
66
|
+
could declare an export under another module's id and answer for a
|
|
67
|
+
list it does not own. */
|
|
68
|
+
if (!definition.id.startsWith(`${moduleId}.`)) {
|
|
69
|
+
throw new ExportListError(
|
|
70
|
+
'EXPORT_LIST_INVALID',
|
|
71
|
+
`The list ${definition.id} is not inside the namespace of ${moduleId}.`,
|
|
72
|
+
500,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (lists.has(definition.id)) {
|
|
76
|
+
throw new ExportListError(
|
|
77
|
+
'EXPORT_LIST_DUPLICATE',
|
|
78
|
+
`The list export ${definition.id} is already registered.`,
|
|
79
|
+
500,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (lists.size >= EXPORT_LIST_LIMITS.lists) {
|
|
83
|
+
throw new ExportListError(
|
|
84
|
+
'EXPORT_LIST_INVALID',
|
|
85
|
+
`The catalogue holds at most ${EXPORT_LIST_LIMITS.lists} lists.`,
|
|
86
|
+
500,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
lists.set(definition.id, {
|
|
90
|
+
id: definition.id,
|
|
91
|
+
moduleId,
|
|
92
|
+
definition,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
seal() {
|
|
97
|
+
sealed = true;
|
|
98
|
+
},
|
|
99
|
+
find: (id) => lists.get(id) ?? null,
|
|
100
|
+
list: () =>
|
|
101
|
+
[...lists.values()].sort((left, right) =>
|
|
102
|
+
left.id.localeCompare(right.id),
|
|
103
|
+
),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { DatabaseMigration } from '@flowdular/sdk/database';
|
|
2
|
+
import { postgresTenantTableState } from '@flowdular/sdk/database';
|
|
3
|
+
|
|
4
|
+
/* Every constant mirrors its migrations/<id>.up.sql file byte for byte;
|
|
5
|
+
tests/migrations.test.ts fails on drift. */
|
|
6
|
+
|
|
7
|
+
export const EXPORTS_MIGRATION_001 = `CREATE TABLE IF NOT EXISTS exports_jobs (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
tenant_id TEXT NOT NULL,
|
|
10
|
+
list_id TEXT NOT NULL CHECK (length(list_id) BETWEEN 3 AND 96),
|
|
11
|
+
status TEXT NOT NULL CHECK (status IN ('requested', 'running', 'completed', 'failed')),
|
|
12
|
+
row_count BIGINT NOT NULL CHECK (row_count >= 0),
|
|
13
|
+
byte_count BIGINT NOT NULL CHECK (byte_count >= 0),
|
|
14
|
+
object_id TEXT CHECK (object_id IS NULL OR length(object_id) BETWEEN 1 AND 128),
|
|
15
|
+
requester_account_id TEXT NOT NULL CHECK (length(requester_account_id) BETWEEN 1 AND 128),
|
|
16
|
+
requester_json TEXT NOT NULL CHECK (length(requester_json) <= 8192 AND requester_json::jsonb IS NOT NULL),
|
|
17
|
+
failure_code TEXT CHECK (failure_code IS NULL OR length(failure_code) BETWEEN 1 AND 64),
|
|
18
|
+
claimed_at BIGINT,
|
|
19
|
+
started_at BIGINT NOT NULL,
|
|
20
|
+
completed_at BIGINT,
|
|
21
|
+
UNIQUE (tenant_id, object_id),
|
|
22
|
+
CHECK ((status IN ('completed', 'failed')) = (completed_at IS NOT NULL)),
|
|
23
|
+
CHECK ((failure_code IS NOT NULL) = (status = 'failed')),
|
|
24
|
+
CHECK (object_id IS NULL OR status = 'completed')
|
|
25
|
+
);
|
|
26
|
+
CREATE INDEX IF NOT EXISTS exports_jobs_tenant_started_idx
|
|
27
|
+
ON exports_jobs (tenant_id, started_at DESC, id);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS exports_jobs_tenant_export_idx
|
|
29
|
+
ON exports_jobs (tenant_id, started_at, id);
|
|
30
|
+
ALTER TABLE exports_jobs ENABLE ROW LEVEL SECURITY;
|
|
31
|
+
ALTER TABLE exports_jobs FORCE ROW LEVEL SECURITY;
|
|
32
|
+
CREATE POLICY exports_jobs_tenant_policy ON exports_jobs
|
|
33
|
+
USING (tenant_id = current_setting('coreloom.tenant_id', true))
|
|
34
|
+
WITH CHECK (tenant_id = current_setting('coreloom.tenant_id', true));
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
export const EXPORTS_MIGRATION_002_JOB_ROUTING_ROLE = `-- The poll loop must find waiting jobs across workspaces before it knows whose
|
|
38
|
+
-- they are, so it reads the routing columns alone on the background role: the
|
|
39
|
+
-- list, the requester snapshot, the object and every count stay invisible to
|
|
40
|
+
-- it, and each job it picks is claimed and run again under the workspace the
|
|
41
|
+
-- routing row named. PostgreSQL checks column privileges in WHERE too, so
|
|
42
|
+
-- \`status\` is part of the grant. A job already running is routed as well, so a
|
|
43
|
+
-- claim whose process is gone is found again once its lease lapses.
|
|
44
|
+
CREATE INDEX IF NOT EXISTS exports_jobs_routing_idx
|
|
45
|
+
ON exports_jobs (status, started_at, tenant_id, id);
|
|
46
|
+
DO $$
|
|
47
|
+
BEGIN
|
|
48
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'coreloom_background') THEN
|
|
49
|
+
RAISE EXCEPTION 'The coreloom_background role must exist before this migration.';
|
|
50
|
+
END IF;
|
|
51
|
+
END
|
|
52
|
+
$$;
|
|
53
|
+
CREATE POLICY exports_jobs_background_policy ON exports_jobs
|
|
54
|
+
FOR SELECT TO coreloom_background
|
|
55
|
+
USING (status IN ('requested', 'running'));
|
|
56
|
+
REVOKE SELECT ON exports_jobs FROM coreloom_background;
|
|
57
|
+
GRANT SELECT (tenant_id, id, status, started_at) ON exports_jobs TO coreloom_background;
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
export const databaseMigrations: readonly DatabaseMigration[] = [
|
|
61
|
+
{
|
|
62
|
+
id: '0001_exports_core',
|
|
63
|
+
sql: { postgresql: EXPORTS_MIGRATION_001 },
|
|
64
|
+
inspectExisting: (database) =>
|
|
65
|
+
postgresTenantTableState(
|
|
66
|
+
database,
|
|
67
|
+
'exports_jobs',
|
|
68
|
+
'exports_jobs_tenant_policy',
|
|
69
|
+
[
|
|
70
|
+
() => database.schema.hasIndex('exports_jobs_tenant_started_idx'),
|
|
71
|
+
() => database.schema.hasIndex('exports_jobs_tenant_export_idx'),
|
|
72
|
+
],
|
|
73
|
+
),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: '0002_exports_job_routing_role',
|
|
77
|
+
sql: { postgresql: EXPORTS_MIGRATION_002_JOB_ROUTING_ROLE },
|
|
78
|
+
/* A policy and a column grant leave no schema object behind, so the
|
|
79
|
+
privilege itself is what proves this migration ran. */
|
|
80
|
+
inspectExisting: async (database) => {
|
|
81
|
+
const result = await database.query<{ granted: boolean }>({
|
|
82
|
+
text: `SELECT CASE WHEN to_regclass('exports_jobs') IS NOT NULL THEN
|
|
83
|
+
has_column_privilege('coreloom_background', 'exports_jobs', 'status', 'SELECT')
|
|
84
|
+
ELSE false END AS granted`,
|
|
85
|
+
});
|
|
86
|
+
return result.rows[0]?.granted ? 'complete' : 'absent';
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DataClassExportSink,
|
|
3
|
+
DataClassExportSummary,
|
|
4
|
+
} from '@flowdular/sdk/kernel';
|
|
5
|
+
import type {
|
|
6
|
+
ClaimedExportJob,
|
|
7
|
+
ExportJob,
|
|
8
|
+
ExportJobRouting,
|
|
9
|
+
ExportJobStatus,
|
|
10
|
+
} from '../domain/types.ts';
|
|
11
|
+
|
|
12
|
+
/** The keyset of the last job on a page: newest first, id breaking ties. */
|
|
13
|
+
export interface ExportJobCursor {
|
|
14
|
+
readonly startedAt: number;
|
|
15
|
+
readonly id: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ExportJobQuery {
|
|
19
|
+
readonly status?: ExportJobStatus | undefined;
|
|
20
|
+
readonly limit: number;
|
|
21
|
+
readonly cursor?: ExportJobCursor | undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ExportJobPage {
|
|
25
|
+
readonly items: readonly ExportJob[];
|
|
26
|
+
readonly nextCursor: ExportJobCursor | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ClaimExportJobInput {
|
|
30
|
+
readonly tenantId: string;
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly claimedAt: number;
|
|
33
|
+
/** A claim at or before this belonged to a process that is gone. */
|
|
34
|
+
readonly staleBefore: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SettleExportJobInput {
|
|
38
|
+
readonly status: Extract<ExportJobStatus, 'completed' | 'failed'>;
|
|
39
|
+
readonly rowCount: number;
|
|
40
|
+
readonly byteCount: number;
|
|
41
|
+
readonly objectId: string | null;
|
|
42
|
+
readonly failureCode: string | null;
|
|
43
|
+
readonly completedAt: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ExportSweepInput {
|
|
47
|
+
/** Settled jobs started strictly before this go. */
|
|
48
|
+
readonly settledBefore: number;
|
|
49
|
+
/** Upper bound on the jobs one pass removes. */
|
|
50
|
+
readonly limit: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ExportSweepBatch {
|
|
54
|
+
readonly ids: readonly string[];
|
|
55
|
+
/** The objects those jobs hold, for the caller to delete before the rows. */
|
|
56
|
+
readonly objectIds: readonly string[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The business port: async, database-agnostic, and unaware of SQL. Every method
|
|
61
|
+
* is tenant-scoped except `listPendingJobs`, which crosses workspaces on the
|
|
62
|
+
* background role and answers routing columns alone.
|
|
63
|
+
*/
|
|
64
|
+
export interface ExportRepository {
|
|
65
|
+
createJob(job: ExportJob): Promise<ExportJob>;
|
|
66
|
+
findJob(tenantId: string, id: string): Promise<ExportJob | null>;
|
|
67
|
+
listJobs(tenantId: string, query: ExportJobQuery): Promise<ExportJobPage>;
|
|
68
|
+
/** Routing columns of the jobs waiting or in flight, across workspaces. */
|
|
69
|
+
listPendingJobs(limit: number): Promise<readonly ExportJobRouting[]>;
|
|
70
|
+
/** Takes one job for this process; null when another already holds it. */
|
|
71
|
+
claimJob(input: ClaimExportJobInput): Promise<ClaimedExportJob | null>;
|
|
72
|
+
/** Renews a claim, answering false once the job changed hands. */
|
|
73
|
+
heartbeatJob(
|
|
74
|
+
tenantId: string,
|
|
75
|
+
id: string,
|
|
76
|
+
at: number,
|
|
77
|
+
claimedAt: number,
|
|
78
|
+
): Promise<boolean>;
|
|
79
|
+
/** Settles a running job; null when it is no longer this process's work. */
|
|
80
|
+
settleJob(
|
|
81
|
+
tenantId: string,
|
|
82
|
+
id: string,
|
|
83
|
+
input: SettleExportJobInput,
|
|
84
|
+
): Promise<ExportJob | null>;
|
|
85
|
+
/** The batch one retention pass removes, chosen once, oldest first. */
|
|
86
|
+
claimSweepBatch(
|
|
87
|
+
tenantId: string,
|
|
88
|
+
input: ExportSweepInput,
|
|
89
|
+
): Promise<ExportSweepBatch>;
|
|
90
|
+
/** Removes the jobs of a chosen batch; answers how many rows went. */
|
|
91
|
+
deleteJobs(tenantId: string, ids: readonly string[]): Promise<number>;
|
|
92
|
+
/** The whole workspace, oldest first, for the data class export. */
|
|
93
|
+
exportJobs(
|
|
94
|
+
tenantId: string,
|
|
95
|
+
sink: DataClassExportSink,
|
|
96
|
+
): Promise<DataClassExportSummary>;
|
|
97
|
+
}
|