@flowdular/sdk 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai/agents/sandbox/business-manager.md +5 -1
- package/.ai/blueprints/author-spec/README.md +1 -1
- package/.ai/blueprints/author-spec/spec-requirements.yaml +44 -0
- package/.ai/blueprints/author-spec/steps.yaml +5 -5
- package/.ai/blueprints/author-spec/templates/module.yaml +99 -3
- package/.ai/blueprints/edit-module/gates.yaml +4 -0
- package/.ai/blueprints/edit-module/required-files.yaml +9 -0
- package/.ai/blueprints/new-module/gates.yaml +4 -0
- package/.ai/blueprints/new-module/spec-requirements.yaml +2 -2
- package/.ai/blueprints/release/gates.yaml +4 -0
- package/.ai/platform-capabilities.md +128 -0
- package/.ai/policies/capabilities.yaml +130 -3
- package/.ai/policies/path-ownership.yaml +5 -2
- package/.ai/policies/task-budgets.yaml +5 -3
- package/.ai/references/catalog/module.json +4 -4
- package/.ai/references/catalog/package.json +2 -2
- package/.ai/references/catalog/spec/module.yaml +5 -3
- package/.ai/references/catalog/src/platform.ts +2 -0
- package/.ai/references/catalog/src/services/catalog-service.ts +89 -1
- package/.ai/references/catalog/src/services/data-classes.ts +47 -0
- package/.ai/references/catalog/src/services/database-repository.ts +98 -1
- package/.ai/references/catalog/src/services/repository.ts +22 -1
- package/.ai/references/catalog/tests/data-classes.test.ts +157 -0
- package/.ai/references/catalog.provenance.json +12 -10
- package/.ai/skills/README.md +10 -0
- package/.ai/skills/agent-tool-design/SKILL.md +1 -2
- package/.ai/skills/auth-security-review/SKILL.md +1 -1
- package/.ai/skills/business-agent-design/SKILL.md +0 -1
- package/.ai/skills/cli-extension/SKILL.md +1 -1
- package/.ai/skills/deploy-operate/SKILL.md +119 -0
- package/.ai/skills/module-new/SKILL.md +29 -3
- package/.ai/skills/module-update/SKILL.md +9 -3
- package/.ai/skills/perf-audit/SKILL.md +0 -1
- package/.ai/skills/release-eject-pr/SKILL.md +0 -1
- package/.ai/skills/spec-interview/SKILL.md +120 -0
- package/.ai/skills/test-hardening/SKILL.md +1 -0
- package/.ai/skills/ux-design/SKILL.md +34 -3
- package/.ai/skills/variables/SKILL.md +0 -2
- package/.ai/skills/workflow-development/SKILL.md +0 -1
- package/AGENTS.md +4 -0
- package/docs/agent-contract.md +2 -2
- package/docs/design-system.md +185 -31
- package/modules/access/migrations/0001_access_core.down.sql +1 -0
- package/modules/access/migrations/0001_access_core.up.sql +28 -0
- package/modules/access/migrations/README.md +3 -0
- package/modules/access/module.json +33 -0
- package/modules/access/package.json +43 -0
- package/modules/access/spec/module.yaml +225 -0
- package/modules/access/src/acl/permissions.ts +6 -0
- package/modules/access/src/api/endpoints.ts +244 -0
- package/modules/access/src/client/ActivityView.tsrx +245 -0
- package/modules/access/src/client/AttestationsView.tsrx +176 -0
- package/modules/access/src/client/ReviewView.tsrx +586 -0
- package/modules/access/src/client/api.ts +132 -0
- package/modules/access/src/client/contribution.tsrx +41 -0
- package/modules/access/src/client/index.ts +41 -0
- package/modules/access/src/client/navigation.ts +57 -0
- package/modules/access/src/client/presentation.ts +69 -0
- package/modules/access/src/client/state.ts +72 -0
- package/modules/access/src/domain/types.ts +189 -0
- package/modules/access/src/index.ts +38 -0
- package/modules/access/src/platform.ts +60 -0
- package/modules/access/src/server/index.ts +42 -0
- package/modules/access/src/server/runtime.ts +105 -0
- package/modules/access/src/services/access-service.ts +298 -0
- package/modules/access/src/services/audit-window.ts +78 -0
- package/modules/access/src/services/auth-directory.ts +72 -0
- package/modules/access/src/services/changes.ts +91 -0
- package/modules/access/src/services/data-classes.ts +28 -0
- package/modules/access/src/services/database-repository.ts +185 -0
- package/modules/access/src/services/directory.ts +102 -0
- package/modules/access/src/services/index.ts +33 -0
- package/modules/access/src/services/list-exports.ts +150 -0
- package/modules/access/src/services/migration.ts +54 -0
- package/modules/access/src/services/repository.ts +30 -0
- package/modules/access/src/services/review.ts +178 -0
- package/modules/access/translations/en.json +155 -0
- package/modules/access/translations/pl.json +155 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.down.sql +2 -0
- package/modules/agents/migrations/0022_credential_rotation_inventory.up.sql +7 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.down.sql +2 -0
- package/modules/agents/migrations/0023_agents_retention_indexes.up.sql +9 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.down.sql +3 -0
- package/modules/agents/migrations/0024_agent_meter_refusals.up.sql +22 -0
- package/modules/agents/migrations/0025_agent_list_indexes.down.sql +3 -0
- package/modules/agents/migrations/0025_agent_list_indexes.up.sql +11 -0
- package/modules/agents/module.json +30 -4
- package/modules/agents/package.json +2 -1
- package/modules/agents/spec/module.yaml +63 -5
- package/modules/agents/src/api/endpoints.ts +291 -33
- package/modules/agents/src/cli/commands.json +11 -0
- package/modules/agents/src/cli/index.ts +45 -0
- package/modules/agents/src/client/AgentDashboardWidget.tsrx +19 -11
- package/modules/agents/src/client/AgentDefinitionList.tsrx +53 -10
- package/modules/agents/src/client/AgentPlaygroundView.tsrx +4 -4
- package/modules/agents/src/client/AgentProceduresView.tsrx +2 -2
- package/modules/agents/src/client/AgentRunsView.tsrx +143 -40
- package/modules/agents/src/client/AgentsView.tsrx +109 -33
- package/modules/agents/src/client/api.ts +99 -21
- package/modules/agents/src/client/state.ts +97 -0
- package/modules/agents/src/domain/types.ts +44 -4
- package/modules/agents/src/platform.ts +42 -0
- package/modules/agents/src/server/action-execution.ts +201 -106
- package/modules/agents/src/server/runtime.ts +32 -0
- package/modules/agents/src/services/agent-service.ts +158 -30
- package/modules/agents/src/services/credential-rotation.ts +185 -0
- package/modules/agents/src/services/credential-vault.ts +71 -46
- package/modules/agents/src/services/data-classes.ts +176 -0
- package/modules/agents/src/services/database-repository.ts +393 -101
- package/modules/agents/src/services/metering.ts +111 -0
- package/modules/agents/src/services/migration.ts +109 -0
- package/modules/agents/src/services/module-agent-preflight.ts +17 -9
- package/modules/agents/src/services/notifications.ts +98 -0
- package/modules/agents/src/services/provider-repository.ts +9 -18
- package/modules/agents/src/services/provider-service.ts +1 -9
- package/modules/agents/src/services/reports.ts +107 -0
- package/modules/agents/src/services/repository.ts +86 -6
- package/modules/agents/src/services/usage-service.ts +2 -0
- package/modules/agents/src/services/worker.ts +114 -4
- package/modules/agents/src/settings.ts +14 -3
- package/modules/agents/translations/en.json +14 -4
- package/modules/agents/translations/pl.json +14 -4
- package/modules/approvals/migrations/0001_approvals_core.down.sql +3 -0
- package/modules/approvals/migrations/0001_approvals_core.up.sql +78 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.down.sql +2 -0
- package/modules/approvals/migrations/0002_approvals_expiry_routing_role.up.sql +19 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.down.sql +6 -0
- package/modules/approvals/migrations/0003_approvals_retention_indexes.up.sql +14 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.down.sql +5 -0
- package/modules/approvals/migrations/0004_approvals_inbox_keyset_indexes.up.sql +12 -0
- package/modules/approvals/migrations/0005_approvals_grant_audit.down.sql +4 -0
- package/modules/approvals/migrations/0005_approvals_grant_audit.up.sql +20 -0
- package/modules/approvals/migrations/README.md +3 -0
- package/modules/approvals/module.json +34 -0
- package/modules/approvals/package.json +43 -0
- package/modules/approvals/spec/module.yaml +327 -0
- package/modules/approvals/src/acl/permissions.ts +7 -0
- package/modules/approvals/src/api/endpoints.ts +457 -0
- package/modules/approvals/src/client/ApprovalRequestDrawer.tsrx +138 -0
- package/modules/approvals/src/client/ApprovalsView.tsrx +562 -0
- package/modules/approvals/src/client/PendingCountWidget.tsrx +52 -0
- package/modules/approvals/src/client/api.ts +203 -0
- package/modules/approvals/src/client/approvals.css +51 -0
- package/modules/approvals/src/client/contribution.tsrx +44 -0
- package/modules/approvals/src/client/index.ts +26 -0
- package/modules/approvals/src/client/navigation.ts +39 -0
- package/modules/approvals/src/client/pending-count.ts +26 -0
- package/modules/approvals/src/client/presentation.ts +52 -0
- package/modules/approvals/src/client/state.ts +141 -0
- package/modules/approvals/src/domain/capability.ts +107 -0
- package/modules/approvals/src/domain/grant.ts +69 -0
- package/modules/approvals/src/domain/types.ts +168 -0
- package/modules/approvals/src/index.ts +61 -0
- package/modules/approvals/src/platform.ts +136 -0
- package/modules/approvals/src/server/index.ts +42 -0
- package/modules/approvals/src/server/runtime.ts +185 -0
- package/modules/approvals/src/services/approvals-service.ts +637 -0
- package/modules/approvals/src/services/callbacks.ts +75 -0
- package/modules/approvals/src/services/data-classes.ts +167 -0
- package/modules/approvals/src/services/database-repository.ts +783 -0
- package/modules/approvals/src/services/eligibility.ts +121 -0
- package/modules/approvals/src/services/expiry-runner.ts +81 -0
- package/modules/approvals/src/services/index.ts +31 -0
- package/modules/approvals/src/services/migration.ts +256 -0
- package/modules/approvals/src/services/notifications.ts +95 -0
- package/modules/approvals/src/services/repository.ts +169 -0
- package/modules/approvals/src/services/service-error.ts +70 -0
- package/modules/approvals/src/settings.ts +102 -0
- package/modules/approvals/translations/en.json +104 -0
- package/modules/approvals/translations/pl.json +104 -0
- package/modules/audit/migrations/0001_audit_core.down.sql +8 -0
- package/modules/audit/migrations/0001_audit_core.up.sql +107 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.down.sql +2 -0
- package/modules/audit/migrations/0002_audit_sweep_routing_role.up.sql +21 -0
- package/modules/audit/migrations/0003_audit_export_request.down.sql +12 -0
- package/modules/audit/migrations/0003_audit_export_request.up.sql +40 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.down.sql +17 -0
- package/modules/audit/migrations/0004_audit_hold_seal_erasure.up.sql +192 -0
- package/modules/audit/migrations/0005_audit_event_format.down.sql +17 -0
- package/modules/audit/migrations/0005_audit_event_format.up.sql +60 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.down.sql +3 -0
- package/modules/audit/migrations/0006_audit_own_class_walks.up.sql +14 -0
- package/modules/audit/migrations/README.md +3 -0
- package/modules/audit/module.json +32 -0
- package/modules/audit/package.json +49 -0
- package/modules/audit/spec/module.yaml +809 -0
- package/modules/audit/src/acl/permissions.ts +7 -0
- package/modules/audit/src/api/endpoints.ts +315 -0
- package/modules/audit/src/cli/commands.json +95 -0
- package/modules/audit/src/cli/index.ts +658 -0
- package/modules/audit/src/client/DataClassesView.tsrx +420 -0
- package/modules/audit/src/client/ExportsView.tsrx +256 -0
- package/modules/audit/src/client/HoldsView.tsrx +604 -0
- package/modules/audit/src/client/SweepsView.tsrx +251 -0
- package/modules/audit/src/client/api.ts +185 -0
- package/modules/audit/src/client/contribution.tsrx +52 -0
- package/modules/audit/src/client/index.ts +23 -0
- package/modules/audit/src/client/navigation.ts +74 -0
- package/modules/audit/src/client/presentation.ts +105 -0
- package/modules/audit/src/client/state.ts +86 -0
- package/modules/audit/src/domain/data-classes.ts +16 -0
- package/modules/audit/src/domain/types.ts +339 -0
- package/modules/audit/src/index.ts +76 -0
- package/modules/audit/src/platform.ts +44 -0
- package/modules/audit/src/server/index.ts +177 -0
- package/modules/audit/src/server/runtime.ts +303 -0
- package/modules/audit/src/services/anchor-key.ts +143 -0
- package/modules/audit/src/services/anchor-rotation.ts +147 -0
- package/modules/audit/src/services/audit-runners.ts +278 -0
- package/modules/audit/src/services/backup-guard.ts +95 -0
- package/modules/audit/src/services/database-repository.ts +1946 -0
- package/modules/audit/src/services/declared-classes.ts +64 -0
- package/modules/audit/src/services/erasure-port.ts +126 -0
- package/modules/audit/src/services/erasure-service.ts +770 -0
- package/modules/audit/src/services/export-directory.ts +106 -0
- package/modules/audit/src/services/export-service.ts +714 -0
- package/modules/audit/src/services/hold-service.ts +295 -0
- package/modules/audit/src/services/index.ts +17 -0
- package/modules/audit/src/services/migration.ts +658 -0
- package/modules/audit/src/services/own-classes.ts +318 -0
- package/modules/audit/src/services/platform-version.ts +23 -0
- package/modules/audit/src/services/repository.ts +495 -0
- package/modules/audit/src/services/retention-service.ts +191 -0
- package/modules/audit/src/services/seal-service.ts +769 -0
- package/modules/audit/src/services/service-error.ts +61 -0
- package/modules/audit/src/services/subject-keys.ts +90 -0
- package/modules/audit/src/services/sweep-service.ts +298 -0
- package/modules/audit/src/services/zip.ts +217 -0
- package/modules/audit/src/settings.ts +69 -0
- package/modules/audit/translations/en.json +210 -0
- package/modules/audit/translations/pl.json +210 -0
- package/modules/auth/README.md +77 -29
- package/modules/auth/migrations/0016_external_identities.up.sql +16 -0
- package/modules/auth/migrations/0017_mfa_key_id.up.sql +8 -0
- package/modules/auth/migrations/0018_retire_bundled_module_scopes.up.sql +29 -0
- package/modules/auth/migrations/0019_notifications_member_scopes.up.sql +44 -0
- package/modules/auth/migrations/0020_identity_providers.up.sql +61 -0
- package/modules/auth/migrations/0021_membership_status.up.sql +19 -0
- package/modules/auth/migrations/0022_auth_provider_scopes.up.sql +45 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.down.sql +19 -0
- package/modules/auth/migrations/0023_enterprise_module_scopes.up.sql +71 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.down.sql +22 -0
- package/modules/auth/migrations/0024_approvals_member_scopes.up.sql +48 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.down.sql +21 -0
- package/modules/auth/migrations/0025_audit_holds_owner_scope.up.sql +47 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.down.sql +6 -0
- package/modules/auth/migrations/0026_auth_export_keyset_indexes.up.sql +15 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.down.sql +34 -0
- package/modules/auth/migrations/0027_workflow_automation_profile_scopes.up.sql +72 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.down.sql +6 -0
- package/modules/auth/migrations/0028_auth_member_search_prefix_indexes.up.sql +21 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.down.sql +22 -0
- package/modules/auth/migrations/0029_reports_exports_access_scopes.up.sql +56 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.down.sql +4 -0
- package/modules/auth/migrations/0030_auth_membership_keyset_index.up.sql +10 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.down.sql +4 -0
- package/modules/auth/migrations/0031_membership_scope_backfills_under_rls.up.sql +31 -0
- package/modules/auth/migrations/0032_audit_actor_service.down.sql +9 -0
- package/modules/auth/migrations/0032_audit_actor_service.up.sql +10 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.down.sql +5 -0
- package/modules/auth/migrations/0033_auth_account_keyset_indexes.up.sql +23 -0
- package/modules/auth/module.json +3 -3
- package/modules/auth/package.json +2 -1
- package/modules/auth/spec/module.yaml +372 -3
- package/modules/auth/src/acl/scopes.ts +50 -6
- package/modules/auth/src/cli/commands.json +11 -0
- package/modules/auth/src/cli/greenfield.ts +2 -2
- package/modules/auth/src/cli/index.ts +14 -0
- package/modules/auth/src/cli/secrets.ts +114 -0
- package/modules/auth/src/client/AuthenticationCore.tsrx +61 -8
- package/modules/auth/src/client/api.ts +72 -6
- package/modules/auth/src/client/contribution.tsrx +23 -0
- package/modules/auth/src/client/index.ts +6 -0
- package/modules/auth/src/client/providers/IdentityProviderForm.tsrx +191 -0
- package/modules/auth/src/client/providers/IdentityProvidersView.tsrx +358 -0
- package/modules/auth/src/client/providers/api.ts +128 -0
- package/modules/auth/src/client/providers/provider-columns.tsrx +60 -0
- package/modules/auth/src/client/providers/state.ts +35 -0
- package/modules/auth/src/client/security/SecurityView.tsrx +9 -1
- package/modules/auth/src/client/state.ts +15 -1
- package/modules/auth/src/domain/types.ts +55 -0
- package/modules/auth/src/index.ts +11 -1
- package/modules/auth/src/middleware/authentication.ts +4 -0
- package/modules/auth/src/server/endpoints.ts +467 -171
- package/modules/auth/src/server/http.ts +3 -2
- package/modules/auth/src/server/index.ts +22 -1
- package/modules/auth/src/server/membership-endpoints.ts +62 -0
- package/modules/auth/src/server/mfa-enforcement.ts +156 -0
- package/modules/auth/src/server/oidc.ts +389 -0
- package/modules/auth/src/server/provider-endpoints.ts +246 -0
- package/modules/auth/src/server/provider-host.ts +77 -0
- package/modules/auth/src/server/runtime.ts +231 -55
- package/modules/auth/src/services/auth-service-error.ts +7 -2
- package/modules/auth/src/services/auth-service.ts +948 -51
- package/modules/auth/src/services/data-classes.ts +236 -0
- package/modules/auth/src/services/database-repository.ts +853 -71
- package/modules/auth/src/services/identity-provider-service.ts +571 -0
- package/modules/auth/src/services/mail-delivery.ts +16 -16
- package/modules/auth/src/services/mail-message.ts +54 -0
- package/modules/auth/src/services/mail-port.ts +24 -0
- package/modules/auth/src/services/mail-smtp.ts +85 -0
- package/modules/auth/src/services/mfa-rotation.ts +144 -0
- package/modules/auth/src/services/migration.ts +810 -0
- package/modules/auth/src/services/password.ts +14 -0
- package/modules/auth/src/services/provider-secret-rotation.ts +169 -0
- package/modules/auth/src/services/provider-secrets.ts +136 -0
- package/modules/auth/src/services/repository.ts +321 -5
- package/modules/auth/src/services/session-sweep-runner.ts +73 -0
- package/modules/auth/src/services/settings-store.ts +10 -83
- package/modules/auth/src/services/totp.ts +88 -62
- package/modules/auth/src/services/validation.ts +194 -7
- package/modules/auth/src/settings.ts +18 -0
- package/modules/auth/translations/en.json +84 -1
- package/modules/auth/translations/pl.json +84 -1
- package/modules/automations/migrations/0005_secret_rotation_inventory.down.sql +1 -0
- package/modules/automations/migrations/0005_secret_rotation_inventory.up.sql +6 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.down.sql +4 -0
- package/modules/automations/migrations/0006_automations_list_sort_indexes.up.sql +11 -0
- package/modules/automations/module.json +24 -6
- package/modules/automations/package.json +4 -1
- package/modules/automations/spec/module.yaml +81 -7
- package/modules/automations/src/api/endpoints.ts +202 -28
- package/modules/automations/src/cli/commands.json +17 -0
- package/modules/automations/src/cli/index.ts +114 -0
- package/modules/automations/src/client/AutomationScheduleForm.tsrx +77 -19
- package/modules/automations/src/client/AutomationSchedulesView.tsrx +144 -40
- package/modules/automations/src/client/AutomationTriggersView.tsrx +131 -32
- package/modules/automations/src/client/api.ts +62 -19
- package/modules/automations/src/client/presentation.ts +20 -2
- package/modules/automations/src/client/state.ts +84 -0
- package/modules/automations/src/domain/cadence.ts +99 -3
- package/modules/automations/src/domain/cron.ts +366 -0
- package/modules/automations/src/domain/time-zone.ts +61 -0
- package/modules/automations/src/platform.ts +38 -4
- package/modules/automations/src/server/index.ts +11 -0
- package/modules/automations/src/server/runtime.ts +46 -22
- package/modules/{automations-workflows-integration/src/server/adapter.ts → automations/src/server/workflow-target.ts} +13 -14
- package/modules/{automations-workflows-integration/src/server/tools.ts → automations/src/server/workflow-tools.ts} +0 -0
- package/modules/automations/src/services/data-classes.ts +62 -0
- package/modules/automations/src/services/database-repository.ts +152 -38
- package/modules/automations/src/services/migration.ts +119 -9
- package/modules/automations/src/services/repository.ts +52 -1
- package/modules/automations/src/services/schedule-runner.ts +84 -0
- package/modules/automations/src/services/schedule-service.ts +152 -26
- package/modules/automations/src/services/secret-rotation.ts +176 -0
- package/modules/automations/src/services/secret-vault.ts +68 -41
- package/modules/automations/src/services/trigger-service.ts +13 -10
- package/modules/automations/translations/en.json +15 -2
- package/modules/automations/translations/pl.json +15 -2
- package/modules/connectors/migrations/0001_connectors_core.down.sql +3 -0
- package/modules/connectors/migrations/0001_connectors_core.up.sql +72 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.down.sql +3 -0
- package/modules/connectors/migrations/0002_connectors_call_keys.up.sql +18 -0
- package/modules/connectors/migrations/0003_connectors_rotation_inventory.down.sql +2 -0
- package/modules/connectors/migrations/0003_connectors_rotation_inventory.up.sql +19 -0
- package/modules/connectors/migrations/README.md +3 -0
- package/modules/connectors/module.json +32 -0
- package/modules/{automations-workflows-integration → connectors}/package.json +28 -26
- package/modules/connectors/spec/module.yaml +448 -0
- package/modules/connectors/src/acl/permissions.ts +6 -0
- package/modules/connectors/src/agent/tools.ts +180 -0
- package/modules/connectors/src/api/endpoints.ts +572 -0
- package/modules/connectors/src/cli/commands.json +17 -0
- package/modules/connectors/src/cli/index.ts +126 -0
- package/modules/connectors/src/client/ConnectorCallsView.tsrx +358 -0
- package/modules/connectors/src/client/ConnectorForm.tsrx +424 -0
- package/modules/connectors/src/client/ConnectorsView.tsrx +711 -0
- package/modules/connectors/src/client/api.ts +281 -0
- package/modules/connectors/src/client/consent.ts +48 -0
- package/modules/connectors/src/client/contribution.tsrx +37 -0
- package/modules/connectors/src/client/index.ts +22 -0
- package/modules/connectors/src/client/navigation.ts +42 -0
- package/modules/connectors/src/client/presentation.ts +38 -0
- package/modules/connectors/src/client/state.ts +175 -0
- package/modules/connectors/src/domain/calls.ts +70 -0
- package/modules/connectors/src/domain/definitions.ts +190 -0
- package/modules/connectors/src/domain/http-json.ts +68 -0
- package/modules/connectors/src/domain/types.ts +185 -0
- package/modules/connectors/src/index.ts +64 -0
- package/modules/connectors/src/platform.ts +56 -0
- package/modules/connectors/src/server/index.ts +66 -0
- package/modules/connectors/src/server/runtime.ts +163 -0
- package/modules/connectors/src/services/call-service.ts +903 -0
- package/modules/connectors/src/services/connectors-service.ts +653 -0
- package/modules/connectors/src/services/credential-rotation.ts +221 -0
- package/modules/connectors/src/services/credential-vault.ts +194 -0
- package/modules/connectors/src/services/data-classes.ts +158 -0
- package/modules/connectors/src/services/database-repository.ts +897 -0
- package/modules/connectors/src/services/egress.ts +261 -0
- package/modules/connectors/src/services/index.ts +19 -0
- package/modules/connectors/src/services/migration.ts +202 -0
- package/modules/connectors/src/services/repository.ts +175 -0
- package/modules/connectors/src/services/service-error.ts +46 -0
- package/modules/connectors/src/settings.ts +69 -0
- package/modules/connectors/translations/en.json +191 -0
- package/modules/connectors/translations/pl.json +191 -0
- package/modules/directory/migrations/0001_directory_core.down.sql +5 -0
- package/modules/directory/migrations/0001_directory_core.up.sql +111 -0
- package/modules/directory/migrations/README.md +3 -0
- package/modules/directory/module.json +27 -0
- package/modules/directory/package.json +46 -0
- package/modules/directory/spec/module.yaml +351 -0
- package/modules/directory/src/acl/permissions.ts +7 -0
- package/modules/directory/src/api/endpoints.ts +478 -0
- package/modules/directory/src/api/scim-endpoints.ts +516 -0
- package/modules/directory/src/client/GroupMappingsView.tsrx +430 -0
- package/modules/directory/src/client/ProvisioningLogView.tsrx +248 -0
- package/modules/directory/src/client/ScimTokensView.tsrx +587 -0
- package/modules/directory/src/client/api.ts +222 -0
- package/modules/directory/src/client/contribution.tsrx +46 -0
- package/modules/directory/src/client/index.ts +22 -0
- package/modules/directory/src/client/navigation.ts +57 -0
- package/modules/directory/src/client/presentation.ts +143 -0
- package/modules/directory/src/client/state.ts +173 -0
- package/modules/directory/src/domain/scim.ts +346 -0
- package/modules/directory/src/domain/types.ts +166 -0
- package/modules/directory/src/index.ts +44 -0
- package/modules/directory/src/platform.ts +43 -0
- package/modules/directory/src/server/index.ts +17 -0
- package/modules/directory/src/server/runtime.ts +124 -0
- package/modules/directory/src/services/auth-port.ts +127 -0
- package/modules/directory/src/services/data-classes.ts +41 -0
- package/modules/directory/src/services/database-repository.ts +1067 -0
- package/modules/directory/src/services/directory-service.ts +311 -0
- package/modules/directory/src/services/index.ts +43 -0
- package/modules/directory/src/services/migration.ts +146 -0
- package/modules/directory/src/services/provisioning-service.ts +1420 -0
- package/modules/directory/src/services/rate-limiter.ts +103 -0
- package/modules/directory/src/services/repository.ts +208 -0
- package/modules/directory/src/services/service-error.ts +42 -0
- package/modules/directory/src/services/token-service.ts +215 -0
- package/modules/directory/src/settings.ts +86 -0
- package/modules/directory/translations/en.json +185 -0
- package/modules/directory/translations/pl.json +185 -0
- package/modules/documents/migrations/0001_documents_core.down.sql +1 -0
- package/modules/documents/migrations/0001_documents_core.up.sql +35 -0
- package/modules/documents/migrations/0002_documents_files_page.down.sql +1 -0
- package/modules/documents/migrations/0002_documents_files_page.up.sql +6 -0
- package/modules/documents/migrations/0003_documents_rotation_inventory.down.sql +2 -0
- package/modules/documents/migrations/0003_documents_rotation_inventory.up.sql +18 -0
- package/modules/documents/migrations/README.md +3 -0
- package/modules/documents/module.json +32 -0
- package/modules/documents/package.json +50 -0
- package/modules/documents/spec/module.yaml +248 -0
- package/modules/documents/src/acl/permissions.ts +6 -0
- package/modules/documents/src/api/endpoints.ts +401 -0
- package/modules/documents/src/cli/commands.json +17 -0
- package/modules/documents/src/cli/index.ts +145 -0
- package/modules/documents/src/client/DocumentUploader.tsrx +148 -0
- package/modules/documents/src/client/DocumentsView.tsrx +540 -0
- package/modules/documents/src/client/api.ts +209 -0
- package/modules/documents/src/client/contribution.tsrx +29 -0
- package/modules/documents/src/client/download.ts +70 -0
- package/modules/documents/src/client/index.ts +22 -0
- package/modules/documents/src/client/navigation.ts +25 -0
- package/modules/documents/src/client/presentation.ts +110 -0
- package/modules/documents/src/client/state.ts +117 -0
- package/modules/documents/src/domain/attachments.ts +84 -0
- package/modules/documents/src/domain/types.ts +80 -0
- package/modules/documents/src/index.ts +46 -0
- package/modules/documents/src/platform.ts +61 -0
- package/modules/documents/src/server/index.ts +30 -0
- package/modules/documents/src/server/runtime.ts +107 -0
- package/modules/documents/src/services/attachments.ts +39 -0
- package/modules/documents/src/services/data-classes.ts +25 -0
- package/modules/documents/src/services/database-repository.ts +270 -0
- package/modules/documents/src/services/documents-service.ts +590 -0
- package/modules/documents/src/services/index.ts +18 -0
- package/modules/documents/src/services/migration.ts +117 -0
- package/modules/documents/src/services/repository.ts +58 -0
- package/modules/documents/src/services/storage-rotation.ts +157 -0
- package/modules/documents/src/settings.ts +107 -0
- package/modules/documents/translations/en.json +111 -0
- package/modules/documents/translations/pl.json +111 -0
- package/modules/exports/migrations/0001_exports_core.down.sql +2 -0
- package/modules/exports/migrations/0001_exports_core.up.sql +28 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.down.sql +4 -0
- package/modules/exports/migrations/0002_exports_job_routing_role.up.sql +21 -0
- package/modules/exports/migrations/0003_exports_rotation_inventory.down.sql +1 -0
- package/modules/exports/migrations/0003_exports_rotation_inventory.up.sql +9 -0
- package/modules/exports/migrations/README.md +3 -0
- package/modules/exports/module.json +32 -0
- package/modules/exports/package.json +45 -0
- package/modules/exports/spec/module.yaml +230 -0
- package/modules/exports/src/acl/permissions.ts +6 -0
- package/modules/exports/src/api/endpoints.ts +211 -0
- package/modules/exports/src/cli/commands.json +17 -0
- package/modules/exports/src/cli/index.ts +145 -0
- package/modules/exports/src/client/ExportsView.tsrx +327 -0
- package/modules/exports/src/client/api.ts +133 -0
- package/modules/exports/src/client/contribution.tsrx +31 -0
- package/modules/exports/src/client/index.ts +20 -0
- package/modules/exports/src/client/navigation.ts +25 -0
- package/modules/exports/src/client/presentation.ts +53 -0
- package/modules/exports/src/client/state.ts +56 -0
- package/modules/exports/src/domain/lists.ts +29 -0
- package/modules/exports/src/domain/types.ts +120 -0
- package/modules/exports/src/index.ts +41 -0
- package/modules/exports/src/platform.ts +80 -0
- package/modules/exports/src/server/index.ts +50 -0
- package/modules/exports/src/server/runtime.ts +160 -0
- package/modules/exports/src/services/data-classes.ts +59 -0
- package/modules/exports/src/services/database-repository.ts +403 -0
- package/modules/exports/src/services/export-runner.ts +123 -0
- package/modules/exports/src/services/export-service.ts +356 -0
- package/modules/exports/src/services/index.ts +6 -0
- package/modules/exports/src/services/list-registry.ts +105 -0
- package/modules/exports/src/services/migration.ts +116 -0
- package/modules/exports/src/services/repository.ts +96 -0
- package/modules/exports/src/services/storage-rotation.ts +138 -0
- package/modules/exports/src/settings.ts +70 -0
- package/modules/exports/translations/en.json +69 -0
- package/modules/exports/translations/pl.json +69 -0
- package/modules/import/migrations/0001_import_core.down.sql +6 -0
- package/modules/import/migrations/0001_import_core.up.sql +61 -0
- package/modules/import/migrations/0002_import_job_routing_role.down.sql +4 -0
- package/modules/import/migrations/0002_import_job_routing_role.up.sql +20 -0
- package/modules/import/migrations/0003_import_jobs_export_index.down.sql +1 -0
- package/modules/import/migrations/0003_import_jobs_export_index.up.sql +7 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.down.sql +1 -0
- package/modules/import/migrations/0004_import_jobs_traceparent.up.sql +7 -0
- package/modules/import/migrations/README.md +3 -0
- package/modules/import/module.json +37 -0
- package/modules/import/package.json +50 -0
- package/modules/import/spec/module.yaml +335 -0
- package/modules/import/src/acl/permissions.ts +6 -0
- package/modules/import/src/api/endpoints.ts +400 -0
- package/modules/import/src/client/ImportJobDrawer.tsrx +229 -0
- package/modules/import/src/client/ImportsView.tsrx +455 -0
- package/modules/import/src/client/NewImportForm.tsrx +274 -0
- package/modules/import/src/client/api.ts +243 -0
- package/modules/import/src/client/contribution.tsrx +29 -0
- package/modules/import/src/client/index.ts +23 -0
- package/modules/import/src/client/navigation.ts +25 -0
- package/modules/import/src/client/presentation.ts +59 -0
- package/modules/import/src/client/state.ts +43 -0
- package/modules/import/src/domain/csv.ts +258 -0
- package/modules/import/src/domain/ports.ts +157 -0
- package/modules/import/src/domain/types.ts +179 -0
- package/modules/import/src/index.ts +58 -0
- package/modules/import/src/platform.ts +60 -0
- package/modules/import/src/server/index.ts +49 -0
- package/modules/import/src/server/runtime.ts +158 -0
- package/modules/import/src/services/csv-source.ts +121 -0
- package/modules/import/src/services/data-classes.ts +63 -0
- package/modules/import/src/services/database-repository.ts +780 -0
- package/modules/import/src/services/import-runner.ts +127 -0
- package/modules/import/src/services/import-service.ts +872 -0
- package/modules/import/src/services/index.ts +6 -0
- package/modules/import/src/services/migration.ts +156 -0
- package/modules/import/src/services/port-registry.ts +158 -0
- package/modules/import/src/services/repository.ts +147 -0
- package/modules/import/src/settings.ts +70 -0
- package/modules/import/translations/en.json +175 -0
- package/modules/import/translations/pl.json +175 -0
- package/modules/metering/migrations/0001_metering_core.down.sql +6 -0
- package/modules/metering/migrations/0001_metering_core.up.sql +119 -0
- package/modules/metering/migrations/0002_metering_bucket_export.down.sql +3 -0
- package/modules/metering/migrations/0002_metering_bucket_export.up.sql +5 -0
- package/modules/metering/migrations/README.md +3 -0
- package/modules/metering/module.json +46 -0
- package/modules/metering/package.json +50 -0
- package/modules/metering/spec/module.yaml +269 -0
- package/modules/metering/src/acl/permissions.ts +5 -0
- package/modules/metering/src/api/endpoints.ts +104 -0
- package/modules/metering/src/cli/commands.json +28 -0
- package/modules/metering/src/cli/index.ts +246 -0
- package/modules/metering/src/client/LimitsView.tsrx +170 -0
- package/modules/metering/src/client/UsageSummaryWidget.tsrx +63 -0
- package/modules/metering/src/client/UsageView.tsrx +205 -0
- package/modules/metering/src/client/api.ts +91 -0
- package/modules/metering/src/client/contribution.tsrx +42 -0
- package/modules/metering/src/client/index.ts +26 -0
- package/modules/metering/src/client/navigation.ts +54 -0
- package/modules/metering/src/client/presentation.ts +63 -0
- package/modules/metering/src/client/state.ts +31 -0
- package/modules/metering/src/domain/meters.ts +100 -0
- package/modules/metering/src/domain/types.ts +71 -0
- package/modules/metering/src/index.ts +51 -0
- package/modules/metering/src/platform.ts +84 -0
- package/modules/metering/src/server/index.ts +40 -0
- package/modules/metering/src/server/runtime.ts +165 -0
- package/modules/metering/src/services/data-classes.ts +34 -0
- package/modules/metering/src/services/database-repository.ts +574 -0
- package/modules/metering/src/services/index.ts +9 -0
- package/modules/metering/src/services/meter-registry.ts +145 -0
- package/modules/metering/src/services/metering-service.ts +441 -0
- package/modules/metering/src/services/migration.ts +183 -0
- package/modules/metering/src/services/notifications.ts +75 -0
- package/modules/metering/src/services/reports.ts +105 -0
- package/modules/metering/src/services/repository.ts +132 -0
- package/modules/metering/src/services/service-error.ts +46 -0
- package/modules/metering/src/settings.ts +47 -0
- package/modules/metering/translations/en.json +68 -0
- package/modules/metering/translations/pl.json +68 -0
- package/modules/notifications/migrations/0001_notifications_core.down.sql +1 -0
- package/modules/notifications/migrations/0001_notifications_core.up.sql +26 -0
- package/modules/notifications/migrations/0002_notifications_preferences.down.sql +1 -0
- package/modules/notifications/migrations/0002_notifications_preferences.up.sql +17 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.down.sql +1 -0
- package/modules/notifications/migrations/0003_notifications_webhook_subscriptions.up.sql +30 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.down.sql +1 -0
- package/modules/notifications/migrations/0004_notifications_deliveries.up.sql +35 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.down.sql +2 -0
- package/modules/notifications/migrations/0005_notifications_delivery_routing_role.up.sql +17 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.down.sql +1 -0
- package/modules/notifications/migrations/0006_notifications_delivery_title.up.sql +11 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.down.sql +2 -0
- package/modules/notifications/migrations/0007_notifications_secret_rotation_inventory.up.sql +19 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.down.sql +8 -0
- package/modules/notifications/migrations/0008_notifications_delivery_claim.up.sql +19 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.down.sql +16 -0
- package/modules/notifications/migrations/0009_notifications_kind_approvals.up.sql +18 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.down.sql +16 -0
- package/modules/notifications/migrations/0010_notifications_kind_meter_threshold.up.sql +18 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.down.sql +5 -0
- package/modules/notifications/migrations/0011_notifications_retention_keyset.up.sql +15 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.down.sql +12 -0
- package/modules/notifications/migrations/0012_notifications_email_channel.up.sql +38 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.down.sql +5 -0
- package/modules/notifications/migrations/0013_notifications_list_pages.up.sql +13 -0
- package/modules/notifications/migrations/README.md +3 -0
- package/modules/notifications/module.json +32 -0
- package/modules/notifications/package.json +49 -0
- package/modules/notifications/spec/module.yaml +718 -0
- package/modules/notifications/src/acl/permissions.ts +11 -0
- package/modules/notifications/src/api/endpoints.ts +814 -0
- package/modules/notifications/src/cli/commands.json +17 -0
- package/modules/notifications/src/cli/index.ts +126 -0
- package/modules/notifications/src/client/DeliveriesView.tsrx +483 -0
- package/modules/notifications/src/client/FactList.tsrx +24 -0
- package/modules/notifications/src/client/NotificationPreferencesView.tsrx +240 -0
- package/modules/notifications/src/client/NotificationsInboxView.tsrx +592 -0
- package/modules/notifications/src/client/UnreadCountWidget.tsrx +62 -0
- package/modules/notifications/src/client/WebhookForm.tsrx +297 -0
- package/modules/notifications/src/client/WebhooksView.tsrx +637 -0
- package/modules/notifications/src/client/api.ts +382 -0
- package/modules/notifications/src/client/contribution.tsrx +83 -0
- package/modules/notifications/src/client/inbox.ts +41 -0
- package/modules/notifications/src/client/index.ts +29 -0
- package/modules/notifications/src/client/navigation.ts +92 -0
- package/modules/notifications/src/client/notifications.css +70 -0
- package/modules/notifications/src/client/presentation.ts +81 -0
- package/modules/notifications/src/client/state.ts +246 -0
- package/modules/notifications/src/client/unread-count.ts +26 -0
- package/modules/notifications/src/domain/locale.ts +47 -0
- package/modules/notifications/src/domain/publish.ts +46 -0
- package/modules/notifications/src/domain/types.ts +186 -0
- package/modules/notifications/src/index.ts +62 -0
- package/modules/notifications/src/platform.ts +85 -0
- package/modules/notifications/src/server/index.ts +82 -0
- package/modules/notifications/src/server/runtime.ts +251 -0
- package/modules/notifications/src/services/data-classes.ts +139 -0
- package/modules/notifications/src/services/database-repository.ts +1334 -0
- package/modules/notifications/src/services/delivery-payload.ts +93 -0
- package/modules/notifications/src/services/delivery-runner.ts +170 -0
- package/modules/notifications/src/services/delivery-service.ts +811 -0
- package/modules/notifications/src/services/egress.ts +239 -0
- package/modules/notifications/src/services/email-channel.ts +93 -0
- package/modules/notifications/src/services/index.ts +23 -0
- package/modules/notifications/src/services/migration.ts +572 -0
- package/modules/notifications/src/services/notifications-service.ts +297 -0
- package/modules/notifications/src/services/paging.ts +60 -0
- package/modules/notifications/src/services/publish-service.ts +133 -0
- package/modules/notifications/src/services/repository.ts +342 -0
- package/modules/notifications/src/services/secret-rotation.ts +177 -0
- package/modules/notifications/src/services/secret-vault.ts +168 -0
- package/modules/notifications/src/services/service-error.ts +67 -0
- package/modules/notifications/src/services/signature.ts +81 -0
- package/modules/notifications/src/services/webhook-service.ts +307 -0
- package/modules/notifications/src/settings.ts +130 -0
- package/modules/notifications/translations/en.json +255 -0
- package/modules/notifications/translations/pl.json +255 -0
- package/modules/profile/module.json +3 -3
- package/modules/profile/package.json +1 -1
- package/modules/profile/spec/module.yaml +3 -3
- package/modules/profile/src/services/database-repository.ts +3 -13
- package/modules/reports/module.json +28 -0
- package/modules/reports/package.json +42 -0
- package/modules/reports/spec/module.yaml +231 -0
- package/modules/reports/src/acl/permissions.ts +5 -0
- package/modules/reports/src/api/endpoints.ts +72 -0
- package/modules/reports/src/client/ReportsSummaryWidget.tsrx +52 -0
- package/modules/reports/src/client/ReportsView.tsrx +246 -0
- package/modules/reports/src/client/api.ts +65 -0
- package/modules/reports/src/client/contribution.tsrx +36 -0
- package/modules/reports/src/client/index.ts +18 -0
- package/modules/reports/src/client/navigation.ts +39 -0
- package/modules/reports/src/client/presentation.ts +123 -0
- package/modules/reports/src/client/state.ts +28 -0
- package/modules/reports/src/domain/providers.ts +115 -0
- package/modules/reports/src/domain/types.ts +44 -0
- package/modules/reports/src/index.ts +47 -0
- package/modules/reports/src/platform.ts +37 -0
- package/modules/reports/src/server/index.ts +21 -0
- package/modules/reports/src/server/runtime.ts +40 -0
- package/modules/reports/src/services/index.ts +17 -0
- package/modules/reports/src/services/provider-registry.ts +144 -0
- package/modules/reports/src/services/range.ts +65 -0
- package/modules/reports/src/services/reports-service.ts +316 -0
- package/modules/reports/src/services/service-error.ts +26 -0
- package/modules/reports/src/settings.ts +49 -0
- package/modules/reports/translations/en.json +35 -0
- package/modules/reports/translations/pl.json +35 -0
- package/modules/sandbox/module.json +4 -4
- package/modules/sandbox/package.json +1 -1
- package/modules/sandbox/spec/module.yaml +3 -3
- package/modules/sandbox/src/services/database-repository.ts +14 -23
- package/modules/sandbox/src/services/directory.ts +16 -0
- package/modules/sandbox/src/services/sandbox-service.ts +13 -11
- package/modules/search/migrations/0001_search_core.down.sql +1 -0
- package/modules/search/migrations/0001_search_core.up.sql +22 -0
- package/modules/search/migrations/0002_search_recent_export.down.sql +3 -0
- package/modules/search/migrations/0002_search_recent_export.up.sql +5 -0
- package/modules/search/migrations/README.md +3 -0
- package/modules/search/module.json +28 -0
- package/modules/search/package.json +43 -0
- package/modules/search/spec/module.yaml +177 -0
- package/modules/search/src/acl/permissions.ts +5 -0
- package/modules/search/src/api/endpoints.ts +221 -0
- package/modules/search/src/client/SearchView.tsrx +346 -0
- package/modules/search/src/client/api.ts +157 -0
- package/modules/search/src/client/contribution.tsrx +31 -0
- package/modules/search/src/client/index.ts +17 -0
- package/modules/search/src/client/navigation.ts +97 -0
- package/modules/search/src/client/search.css +56 -0
- package/modules/search/src/client/state.ts +113 -0
- package/modules/search/src/domain/data-classes.ts +73 -0
- package/modules/search/src/domain/providers.ts +88 -0
- package/modules/search/src/domain/types.ts +56 -0
- package/modules/search/src/index.ts +46 -0
- package/modules/search/src/platform.ts +42 -0
- package/modules/search/src/server/index.ts +25 -0
- package/modules/search/src/server/runtime.ts +123 -0
- package/modules/search/src/services/database-repository.ts +163 -0
- package/modules/search/src/services/index.ts +21 -0
- package/modules/search/src/services/migration.ts +65 -0
- package/modules/search/src/services/provider-registry.ts +137 -0
- package/modules/search/src/services/repository.ts +43 -0
- package/modules/search/src/services/search-service.ts +442 -0
- package/modules/search/src/services/service-error.ts +35 -0
- package/modules/search/src/settings.ts +68 -0
- package/modules/search/translations/en.json +45 -0
- package/modules/search/translations/pl.json +45 -0
- package/modules/system/module.json +2 -2
- package/modules/system/package.json +1 -1
- package/modules/system/spec/module.yaml +30 -3
- package/modules/system/src/client/FlagsPanel.tsrx +127 -0
- package/modules/system/src/client/ModuleSettingRow.tsrx +17 -7
- package/modules/system/src/client/ModuleSettingsSection.tsrx +10 -71
- package/modules/system/src/client/ModulesView.tsrx +91 -65
- package/modules/system/src/client/flags.ts +35 -0
- package/modules/system/src/client/index.ts +8 -0
- package/modules/system/src/client/navigation.ts +8 -0
- package/modules/system/src/client/settings-state.ts +159 -0
- package/modules/system/src/client/state.ts +2 -0
- package/modules/system/src/domain/time-zone.ts +105 -0
- package/modules/system/src/index.ts +12 -0
- package/modules/system/src/platform.ts +5 -1
- package/modules/system/src/server/endpoints.ts +72 -21
- package/modules/system/src/settings.ts +28 -0
- package/modules/system/translations/en.json +17 -0
- package/modules/system/translations/pl.json +17 -0
- package/modules/users/module.json +30 -4
- package/modules/users/package.json +4 -1
- package/modules/users/spec/module.yaml +290 -7
- package/modules/users/src/api/endpoints.ts +228 -15
- package/modules/users/src/client/InviteMemberForm.tsrx +2 -2
- package/modules/users/src/client/MemberDrawer.tsrx +142 -26
- package/modules/users/src/client/UserAccountForm.tsrx +2 -2
- package/modules/users/src/client/UsersView.tsrx +432 -71
- package/modules/users/src/client/api.ts +106 -12
- package/modules/users/src/client/contribution.tsrx +5 -0
- package/modules/users/src/client/member-columns.tsrx +22 -9
- package/modules/users/src/client/state.ts +172 -7
- package/modules/users/src/domain/lists.ts +9 -0
- package/modules/users/src/index.ts +11 -0
- package/modules/users/src/platform.ts +50 -1
- package/modules/users/src/services/member-export.ts +51 -0
- package/modules/users/src/services/member-import.ts +249 -0
- package/modules/users/src/services/member-search.ts +145 -0
- package/modules/users/src/services/users-service.ts +117 -4
- package/modules/users/translations/en.json +57 -8
- package/modules/users/translations/pl.json +57 -8
- package/modules/workflows/migrations/0004_payload_rotation_inventory.up.sql +17 -0
- package/modules/workflows/migrations/0005_workflows_human_approval.up.sql +28 -0
- package/modules/workflows/migrations/0006_workflows_retention_indexes.up.sql +11 -0
- package/modules/workflows/migrations/0007_workflows_erasure_subject_indexes.up.sql +17 -0
- package/modules/workflows/migrations/0008_workflows_subject_account.up.sql +24 -0
- package/modules/workflows/migrations/0009_workflows_definition_list_indexes.up.sql +9 -0
- package/modules/workflows/module.json +34 -6
- package/modules/workflows/package.json +2 -1
- package/modules/workflows/spec/module.yaml +26 -9
- package/modules/workflows/src/api/endpoints.ts +131 -25
- package/modules/workflows/src/cli/commands.json +17 -0
- package/modules/workflows/src/cli/index.ts +114 -0
- package/modules/workflows/src/client/WorkflowExecutionHistory.tsrx +36 -27
- package/modules/workflows/src/client/WorkflowInspector.tsrx +116 -0
- package/modules/workflows/src/client/WorkflowNodePalette.tsrx +1 -0
- package/modules/workflows/src/client/WorkflowsView.tsrx +236 -99
- package/modules/workflows/src/client/api.ts +54 -34
- package/modules/workflows/src/client/canvas-model.ts +12 -0
- package/modules/workflows/src/client/state.ts +95 -0
- package/modules/workflows/src/domain/events.ts +25 -11
- package/modules/workflows/src/domain/graph.ts +135 -1
- package/modules/workflows/src/domain/types.ts +91 -4
- package/modules/workflows/src/platform.ts +12 -0
- package/modules/workflows/src/server/runtime.ts +78 -5
- package/modules/workflows/src/services/approvals.ts +62 -0
- package/modules/workflows/src/services/cursors.ts +37 -0
- package/modules/workflows/src/services/data-classes.ts +232 -0
- package/modules/workflows/src/services/database-repository.ts +660 -171
- package/modules/workflows/src/services/migration.ts +240 -0
- package/modules/workflows/src/services/notifications.ts +98 -0
- package/modules/workflows/src/services/payload-codec.ts +51 -28
- package/modules/workflows/src/services/payload-rotation.ts +171 -0
- package/modules/workflows/src/services/repository.ts +123 -8
- package/modules/workflows/src/services/simulation.ts +7 -0
- package/modules/workflows/src/services/worker.ts +446 -25
- package/modules/workflows/src/services/workflows-service.ts +264 -103
- package/modules/workflows/translations/en.json +12 -4
- package/modules/workflows/translations/pl.json +12 -4
- package/modules.json +48 -4
- package/package.json +64 -6
- package/packages/client/package.json +1 -0
- package/packages/client/src/ApplicationShell.tsrx +43 -0
- package/packages/client/src/contributions.ts +55 -0
- package/packages/client/src/i18n/locales/en.json +5 -0
- package/packages/client/src/i18n/locales/pl.json +5 -0
- package/packages/client/src/index.ts +13 -1
- package/packages/client/src/routing.ts +22 -0
- package/packages/client/src/shell/CommandPalette.tsrx +223 -11
- package/packages/client/src/shell/command-search.ts +126 -0
- package/packages/client/src/shell/command.ts +30 -0
- package/packages/client/src/shell/navigation.ts +12 -0
- package/packages/client/src/shell/palette-keys.ts +27 -0
- package/packages/client/src/shell/shell.css +7 -0
- package/packages/contracts/schemas/module-spec.schema.json +287 -1
- package/packages/contracts/schemas/module.schema.json +25 -0
- package/packages/contracts/src/index.ts +144 -1
- package/packages/database/src/backup.ts +180 -0
- package/packages/database/src/decoders.ts +25 -0
- package/packages/database/src/index.ts +17 -0
- package/packages/database/src/migrations.ts +7 -0
- package/packages/database/src/record-history.ts +5 -14
- package/packages/harness/src/index.ts +2 -0
- package/packages/harness/src/runtime.ts +378 -2
- package/packages/harness/src/tool-adapters.ts +20 -9
- package/packages/kernel/src/acl.ts +179 -0
- package/packages/kernel/src/approval-grant.ts +310 -0
- package/packages/kernel/src/capability-registry.ts +69 -2
- package/packages/kernel/src/data-class-registry.ts +354 -0
- package/packages/kernel/src/index.ts +85 -4
- package/packages/kernel/src/keyring.ts +208 -0
- package/packages/kernel/src/module-compatibility.ts +35 -4
- package/packages/kernel/src/module-registry.ts +49 -2
- package/packages/kernel/src/module-settings.ts +189 -27
- package/packages/server/package.json +2 -1
- package/packages/server/src/composition.ts +38 -0
- package/packages/server/src/endpoint.ts +104 -47
- package/packages/server/src/export/csv.ts +34 -0
- package/packages/server/src/export/definition.ts +346 -0
- package/packages/server/src/export/index.ts +61 -0
- package/packages/server/src/export/run.ts +116 -0
- package/packages/server/src/index.ts +155 -0
- package/packages/server/src/jobs/index.ts +93 -0
- package/packages/server/src/jobs/runner.ts +486 -0
- package/packages/server/src/log.ts +291 -0
- package/packages/server/src/mail/config.ts +184 -0
- package/packages/server/src/mail/contracts.ts +251 -0
- package/packages/server/src/mail/index.ts +31 -0
- package/packages/server/src/mail/port.ts +101 -0
- package/packages/server/src/mail/smtp.ts +191 -0
- package/packages/server/src/mail/template.ts +105 -0
- package/packages/server/src/metrics.ts +447 -0
- package/packages/server/src/pagination.ts +246 -0
- package/packages/server/src/trace/context.ts +103 -0
- package/packages/server/src/trace/egress.ts +66 -0
- package/packages/server/src/trace/error-sink.ts +296 -0
- package/packages/server/src/trace/exporter.ts +295 -0
- package/packages/server/src/trace/index.ts +60 -0
- package/packages/server/src/trace/job-sink.ts +172 -0
- package/packages/server/src/trace/tracer.ts +338 -0
- package/packages/server/src/web.ts +5 -1
- package/packages/storage/package.json +40 -0
- package/packages/storage/src/config.ts +189 -0
- package/packages/storage/src/content-type.ts +124 -0
- package/packages/storage/src/contracts.ts +112 -0
- package/packages/storage/src/envelope.ts +238 -0
- package/packages/storage/src/index.ts +49 -0
- package/packages/storage/src/local.ts +75 -0
- package/packages/storage/src/port.ts +262 -0
- package/packages/storage/src/read-token.ts +130 -0
- package/packages/storage/src/reseal.ts +128 -0
- package/packages/storage/src/s3.ts +144 -0
- package/packages/storage/src/scanner.ts +22 -0
- package/packages/storage/src/sigv4.ts +104 -0
- package/packages/storage/src/store.ts +13 -0
- package/packages/ui/package.json +1 -0
- package/packages/ui/src/components/Button.tsrx +3 -0
- package/packages/ui/src/components/ConfirmDialog.tsrx +13 -2
- package/packages/ui/src/components/DateField.tsrx +92 -0
- package/packages/ui/src/components/DatePicker.tsrx +525 -0
- package/packages/ui/src/components/DateRangeField.tsrx +93 -0
- package/packages/ui/src/components/Drawer.tsrx +10 -1
- package/packages/ui/src/components/FileUpload.tsrx +158 -0
- package/packages/ui/src/components/Pagination.tsrx +130 -0
- package/packages/ui/src/components/Select.tsrx +78 -0
- package/packages/ui/src/components/Table.tsrx +498 -81
- package/packages/ui/src/components/Tabs.tsrx +53 -0
- package/packages/ui/src/components/ToastHost.tsrx +48 -0
- package/packages/ui/src/components/calendar.ts +243 -0
- package/packages/ui/src/components/date-field.ts +62 -0
- package/packages/ui/src/components/file-upload.ts +49 -0
- package/packages/ui/src/components/focus-trap.ts +62 -0
- package/packages/ui/src/components/pagination.ts +68 -0
- package/packages/ui/src/components/table-sorting.ts +49 -0
- package/packages/ui/src/components/tabs.ts +61 -0
- package/packages/ui/src/components/toast-store.ts +116 -0
- package/packages/ui/src/icons/Icon.tsrx +5 -0
- package/packages/ui/src/index.ts +45 -0
- package/packages/ui/src/styles/components.css +598 -0
- package/modules/automations-workflows-integration/module.json +0 -27
- package/modules/automations-workflows-integration/spec/module.yaml +0 -93
- package/modules/automations-workflows-integration/src/index.ts +0 -14
- package/modules/automations-workflows-integration/src/platform.ts +0 -24
- package/modules/automations-workflows-integration/src/server/index.ts +0 -11
- package/modules/automations-workflows-integration/translations/en.json +0 -21
- package/modules/automations-workflows-integration/translations/pl.json +0 -21
- package/modules/workflows/src/services/cursor-codec.ts +0 -62
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../packages/contracts/schemas/module.schema.json",
|
|
3
|
+
"schemaVersion": 1,
|
|
4
|
+
"id": "reports.core",
|
|
5
|
+
"package": "@flowdular/module-reports",
|
|
6
|
+
"version": "0.1.2",
|
|
7
|
+
"platformApi": "^0.1.2",
|
|
8
|
+
"profile": "full",
|
|
9
|
+
"capabilities": ["api", "client", "translations"],
|
|
10
|
+
"platform": {
|
|
11
|
+
"server": true,
|
|
12
|
+
"client": true
|
|
13
|
+
},
|
|
14
|
+
"dependencies": [
|
|
15
|
+
{
|
|
16
|
+
"id": "system.core",
|
|
17
|
+
"range": "^0.7.0"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "auth.core",
|
|
21
|
+
"range": "^0.13.0"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"provides": ["reports.v1"],
|
|
25
|
+
"tenancy": "required",
|
|
26
|
+
"locales": ["en", "pl"],
|
|
27
|
+
"stability": "experimental"
|
|
28
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flowdular/module-reports",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.ts",
|
|
8
|
+
"./client": "./src/client/index.ts",
|
|
9
|
+
"./server": "./src/server/index.ts",
|
|
10
|
+
"./platform": "./src/platform.ts",
|
|
11
|
+
"./module.json": "./module.json"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"module.json",
|
|
16
|
+
"translations",
|
|
17
|
+
"spec",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"typecheck": "tsrx-tsc --noEmit -p tsconfig.json",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@flowdular/client": "workspace:*",
|
|
26
|
+
"@flowdular/contracts": "workspace:*",
|
|
27
|
+
"@flowdular/kernel": "workspace:*",
|
|
28
|
+
"@flowdular/module-auth": "workspace:*",
|
|
29
|
+
"@flowdular/server": "workspace:*",
|
|
30
|
+
"@flowdular/ui": "workspace:*",
|
|
31
|
+
"octane": "0.1.51",
|
|
32
|
+
"segment-state": "0.2.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@flowdular/database": "workspace:*",
|
|
36
|
+
"@flowdular/database-testing": "workspace:*",
|
|
37
|
+
"@tsrx/typescript-plugin": "0.3.120",
|
|
38
|
+
"@types/node": "24.13.3",
|
|
39
|
+
"typescript": "5.9.3",
|
|
40
|
+
"vitest": "4.1.11"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
schemaVersion: 2
|
|
2
|
+
id: reports.core
|
|
3
|
+
specVersion: 0.1.2
|
|
4
|
+
status: approved
|
|
5
|
+
name: Reports Core
|
|
6
|
+
description: Composes one workspace report out of the rollups other modules already hold, by asking every module that registered a report provider for its own tiles and series over a date range under the reader's permissions, and rendering them on one screen and one dashboard widget; reports.core holds no rows, no index and no copy of another module's data.
|
|
7
|
+
profile: full
|
|
8
|
+
capabilities:
|
|
9
|
+
- api
|
|
10
|
+
- client
|
|
11
|
+
- translations
|
|
12
|
+
dependencies:
|
|
13
|
+
- id: system.core
|
|
14
|
+
range: ^0.7.0
|
|
15
|
+
- id: auth.core
|
|
16
|
+
range: ^0.13.0
|
|
17
|
+
provides:
|
|
18
|
+
- reports.v1
|
|
19
|
+
tenancy: required
|
|
20
|
+
locales:
|
|
21
|
+
- en
|
|
22
|
+
- pl
|
|
23
|
+
invariants:
|
|
24
|
+
- reports.core owns no table, no migration and no data class beyond an empty declaration; every number it shows was computed by the module that owns the rows, inside that module's own tenant-scoped transaction, and reaches reports.core only through the public capability reports.v1.
|
|
25
|
+
- A report provider is registered by its owning module at composition through reports.v1 with a stable key, a label, the permission a reader needs before the provider is asked at all, and a read({ tenantId, principal, range }) operation; registration is sealed when reports.core starts, so every request reads the same providers in the same order.
|
|
26
|
+
- A provider may name its label, each tile label and each series label with a key into its own module's translation bundle beside the English literal. reports.core renders the module's translation when the reader's locale carries the key and the literal when it does not, so copy stays owned by the module that computed the number and a missing key never shows a raw key.
|
|
27
|
+
- A provider whose rollup covers a period of its own answers that period with its tiles, and the screen captions that report with it; a provider that answers none is captioned with the range the request asked for. The metering usage provider answers its calendar month, because its numbers are the month's rollup whatever range the reader picked.
|
|
28
|
+
- The registry is bounded at composition to at most 64 providers in a deployment, and a provider answer to at most 16 tiles, 8 series and 400 points. A provider that exceeds a bound, fails, or answers something unreadable contributes nothing and is named as unavailable; it never turns the workspace report into an error.
|
|
29
|
+
- Permission filtering happens before any provider is called. A provider whose permission the principal does not hold is not asked, is not listed, and is not reported as unavailable, so the report never reveals that the provider exists.
|
|
30
|
+
- Every provider gets the same per-provider time budget, a platform setting defaulting to 3000 milliseconds, and the fan-out is parallel; a provider over its budget is abandoned with its abort signal raised and named as unavailable, and the report still answers within the budget. A shipped provider passes that signal into its own tenant transaction, so the statement it is waiting on is cancelled with the answer nobody is waiting for.
|
|
31
|
+
- The range is two UTC days, from and to inclusive, defaulting to the last 30 days and bounded to 400 days; a reversed or malformed range is refused with a stable code before any provider is called, and the screen refuses the same width before it spends a request on it, keeping the filter card on screen so the reader can correct the dates.
|
|
32
|
+
- The screen renders a report that answered only lines. A provider with series and no tile is something to show, and the empty state is kept for a report that carries neither.
|
|
33
|
+
- GET /api/reports is a read behind reports.workspace.read, resolved from the authenticated principal's tenant; it carries no CSRF requirement because it mutates nothing, and it accepts no tenant identifier from the request.
|
|
34
|
+
permissions:
|
|
35
|
+
- id: reports.workspace.read
|
|
36
|
+
description: Read the composed workspace report in the active workspace, within the reader's own permissions per provider.
|
|
37
|
+
dataOwnership:
|
|
38
|
+
- reports.core owns the registry of report providers as composed, and nothing else; it declares an empty data class list so a workspace can see it holds no rows.
|
|
39
|
+
- Each provider module owns its rollup, its arithmetic, its retention and the permission that gates its tiles.
|
|
40
|
+
entities:
|
|
41
|
+
- id: report
|
|
42
|
+
name: Report
|
|
43
|
+
description: One provider's answer for the requested range, as the screen shows it, carrying the period its provider rolled up when that is not the requested range.
|
|
44
|
+
fields:
|
|
45
|
+
- id: key
|
|
46
|
+
type: string
|
|
47
|
+
required: true
|
|
48
|
+
unique: tenant
|
|
49
|
+
maxLength: 96
|
|
50
|
+
- id: moduleId
|
|
51
|
+
type: string
|
|
52
|
+
required: true
|
|
53
|
+
maxLength: 64
|
|
54
|
+
- id: label
|
|
55
|
+
type: string
|
|
56
|
+
required: true
|
|
57
|
+
maxLength: 120
|
|
58
|
+
- id: labelKey
|
|
59
|
+
type: string
|
|
60
|
+
maxLength: 96
|
|
61
|
+
description: Key into the provider module's own translation bundle, rendered instead of label when the reader's locale carries it.
|
|
62
|
+
- id: permission
|
|
63
|
+
type: string
|
|
64
|
+
required: true
|
|
65
|
+
maxLength: 96
|
|
66
|
+
- id: tile
|
|
67
|
+
name: Report tile
|
|
68
|
+
description: One number of a report, with the unit it is counted in.
|
|
69
|
+
fields:
|
|
70
|
+
- id: key
|
|
71
|
+
type: string
|
|
72
|
+
required: true
|
|
73
|
+
maxLength: 96
|
|
74
|
+
- id: label
|
|
75
|
+
type: string
|
|
76
|
+
required: true
|
|
77
|
+
maxLength: 120
|
|
78
|
+
- id: value
|
|
79
|
+
type: decimal
|
|
80
|
+
required: true
|
|
81
|
+
- id: tileLabelKey
|
|
82
|
+
type: string
|
|
83
|
+
maxLength: 96
|
|
84
|
+
description: Key into the provider module's own translation bundle, rendered instead of label when the reader's locale carries it.
|
|
85
|
+
- id: unit
|
|
86
|
+
type: string
|
|
87
|
+
maxLength: 32
|
|
88
|
+
- id: delta
|
|
89
|
+
type: decimal
|
|
90
|
+
description: Change against the provider's own comparison period, when the provider states one.
|
|
91
|
+
- id: series
|
|
92
|
+
name: Report series
|
|
93
|
+
description: One line of a report over the range, at most 400 points.
|
|
94
|
+
fields:
|
|
95
|
+
- id: key
|
|
96
|
+
type: string
|
|
97
|
+
required: true
|
|
98
|
+
maxLength: 96
|
|
99
|
+
- id: label
|
|
100
|
+
type: string
|
|
101
|
+
required: true
|
|
102
|
+
maxLength: 120
|
|
103
|
+
- id: seriesLabelKey
|
|
104
|
+
type: string
|
|
105
|
+
maxLength: 96
|
|
106
|
+
description: Key into the provider module's own translation bundle, rendered instead of label when the reader's locale carries it.
|
|
107
|
+
- id: at
|
|
108
|
+
type: string
|
|
109
|
+
required: true
|
|
110
|
+
maxLength: 32
|
|
111
|
+
description: The point's position on the range axis, a UTC day in YYYY-MM-DD form for the shipped providers.
|
|
112
|
+
- id: value
|
|
113
|
+
type: decimal
|
|
114
|
+
required: true
|
|
115
|
+
screens:
|
|
116
|
+
- id: reports
|
|
117
|
+
kind: dashboard
|
|
118
|
+
entity: report
|
|
119
|
+
title: Reports
|
|
120
|
+
columns:
|
|
121
|
+
- label
|
|
122
|
+
- moduleId
|
|
123
|
+
navigationGroup: Administration
|
|
124
|
+
actions:
|
|
125
|
+
- id: read
|
|
126
|
+
entity: report
|
|
127
|
+
permission: reports.workspace.read
|
|
128
|
+
kind: custom
|
|
129
|
+
risk: read
|
|
130
|
+
idempotent: true
|
|
131
|
+
description: Read the composed workspace report for a date range by fanning out to every permitted provider under a per-provider time budget.
|
|
132
|
+
widgets:
|
|
133
|
+
- id: reports-summary
|
|
134
|
+
slot: dashboard.metrics
|
|
135
|
+
entity: tile
|
|
136
|
+
description: The three largest tiles of the workspace report, so the dashboard carries the numbers without opening the screen.
|
|
137
|
+
settings:
|
|
138
|
+
- key: providerTimeoutMs
|
|
139
|
+
type: integer
|
|
140
|
+
scope: platform
|
|
141
|
+
default: 3000
|
|
142
|
+
description: Time budget per report provider per request before it is reported unavailable; 200 to 30000.
|
|
143
|
+
agentTools: []
|
|
144
|
+
outOfScope:
|
|
145
|
+
- CSV and PDF export of a report are not platform capabilities; a reader reads the report on screen and the workspace export in audit.core stays the way out for whole data classes.
|
|
146
|
+
- Scheduled and mailed reports are not offered; a reader opens the screen or the dashboard widget.
|
|
147
|
+
- Cross-provider arithmetic, a shared measure catalogue and ranking across modules are refused by the data ownership rule; a report is exactly what one owning module computed, and provider order is registration order.
|
|
148
|
+
- A saved report, a custom report builder and a per-reader layout are deferred; the screen renders every permitted provider in registration order.
|
|
149
|
+
- Server-side paging of tiles does not exist and is not needed, because a provider answers at most 16 tiles and 8 series, so one request carries a whole report.
|
|
150
|
+
decisions:
|
|
151
|
+
- id: D-REPORTS-AUDIENCE
|
|
152
|
+
question: May a member read the workspace report, or owners only?
|
|
153
|
+
answer: Owners only. A workspace report composes spend, usage and volume across modules, which is an administrative view, so reports.workspace.read is granted to the owners of every workspace by auth sync-scopes and is not added to the member scopes. A member keeps the per-module screens their own permissions already open.
|
|
154
|
+
decidedBy: default
|
|
155
|
+
- id: D-REPORTS-SHAPE
|
|
156
|
+
question: What does a provider answer?
|
|
157
|
+
answer: Tiles and optional series. A tile is a key, a label, a number, an optional unit and an optional delta; a series is a key, a label and points of an axis position and a number. Nothing else, so reports.core never has to understand a module's domain to render it.
|
|
158
|
+
decidedBy: default
|
|
159
|
+
- id: D-REPORTS-BOUNDS
|
|
160
|
+
question: What bounds the fan-out?
|
|
161
|
+
answer: 64 providers in a deployment, 16 tiles, 8 series and 400 points per provider answer, and a per-provider time budget that is a platform setting defaulting to 3000 ms. A provider over any bound is named unavailable rather than failing the report.
|
|
162
|
+
decidedBy: default
|
|
163
|
+
- id: D-REPORTS-RANGE
|
|
164
|
+
question: What range does the screen ask for?
|
|
165
|
+
answer: Two UTC days, from and to inclusive, defaulting to the last 30 days and bounded to 400 days, which is also the point bound, so a daily series can never exceed it.
|
|
166
|
+
decidedBy: default
|
|
167
|
+
- id: D-REPORTS-NO-DATA
|
|
168
|
+
question: Does reports.core store anything?
|
|
169
|
+
answer: No. It has no database capability, no migration and no table; it declares an empty data class list so a workspace sees that it holds no rows, and every number it shows is read live from the owning module.
|
|
170
|
+
decidedBy: default
|
|
171
|
+
- id: D-REPORTS-WIDGET
|
|
172
|
+
question: What does the dashboard widget show?
|
|
173
|
+
answer: The three largest tiles of the report by value, across every permitted provider, each as a Kpi linking to the Reports screen.
|
|
174
|
+
decidedBy: default
|
|
175
|
+
- id: D-REPORTS-PROVIDERS
|
|
176
|
+
question: Which providers ship first?
|
|
177
|
+
answer: metering.core registers usage, this calendar month's rollup per meter with the operator's monthly limit carried as the unit context; agents.core registers runs, runs and tokens per day over the range read from the agent run cost rollup.
|
|
178
|
+
decidedBy: user
|
|
179
|
+
acceptanceScenarios:
|
|
180
|
+
- id: REPORTS-FANOUT
|
|
181
|
+
given: Three permitted providers, one of which never answers within the time budget.
|
|
182
|
+
when: An owner reads the workspace report.
|
|
183
|
+
then: The two responsive providers' tiles and series are returned within the budget, the slow provider contributes nothing, is named in the unavailable list and has its abort signal raised, and the read is not an error. A provider that throws before its first await, rather than rejecting, is named the same way and costs the reader only that provider.
|
|
184
|
+
- id: REPORTS-PERMISSION
|
|
185
|
+
given: A provider whose permission the reader does not hold.
|
|
186
|
+
when: The reader reads the workspace report.
|
|
187
|
+
then: The provider's read operation is never called, the provider is absent from the reports and from the unavailable list, and only permitted providers appear.
|
|
188
|
+
- id: REPORTS-BOUNDS
|
|
189
|
+
given: A provider answering 17 tiles, one answering 9 series, one answering 401 points, and a deployment registering a 65th provider.
|
|
190
|
+
when: The report is read and the registry is loaded.
|
|
191
|
+
then: Each over-bound answer makes only that provider unavailable, the rest of the report is unaffected, and the 65th registration is refused at composition with a stable code.
|
|
192
|
+
- id: REPORTS-SEALED
|
|
193
|
+
given: reports.core has started.
|
|
194
|
+
when: A module registers a provider.
|
|
195
|
+
then: The registration is refused with a stable code and the provider list a request reads is unchanged.
|
|
196
|
+
- id: REPORTS-RANGE
|
|
197
|
+
given: A request with a reversed range, a malformed day, or a range wider than 400 days.
|
|
198
|
+
when: The report is read.
|
|
199
|
+
then: The request is refused with a stable code and a 400 status before any provider is called, a request with no range reads the last 30 days, and the screen refuses a range wider than 400 days itself, keeping the filter card and the reader's dates on screen with the failure shown on the field.
|
|
200
|
+
- id: REPORTS-DENY
|
|
201
|
+
given: A principal that is unauthenticated, and a principal without reports.workspace.read.
|
|
202
|
+
when: The principal reads the workspace report.
|
|
203
|
+
then: The server answers 401 and 403 respectively, before any provider is called.
|
|
204
|
+
- id: REPORTS-READ-CSRF-FREE
|
|
205
|
+
given: An owner with reports.workspace.read and no CSRF token on the request.
|
|
206
|
+
when: The owner reads the workspace report.
|
|
207
|
+
then: The read succeeds, because it mutates nothing; the endpoint accepts no body and no tenant identifier from the request.
|
|
208
|
+
- id: REPORTS-TENANT-BOUNDARY
|
|
209
|
+
given: Two workspaces whose providers hold different rollups.
|
|
210
|
+
when: An owner of one workspace reads the report.
|
|
211
|
+
then: Every provider is called with the tenant of the authenticated principal only, and no number of the other workspace appears.
|
|
212
|
+
- id: REPORTS-WIDGET
|
|
213
|
+
given: A report whose providers answer more than three tiles.
|
|
214
|
+
when: The dashboard widget renders.
|
|
215
|
+
then: The three largest tiles by value are shown, in descending order, and a report with no tile shows nothing rather than an error.
|
|
216
|
+
- id: REPORTS-LABELS
|
|
217
|
+
given: A provider that named its label, its tile labels and its series labels with keys of its own module's bundle, and a reader whose locale carries some of those keys.
|
|
218
|
+
when: The report is read and rendered.
|
|
219
|
+
then: Each key survives the answer reader beside the literal, the screen shows the module's own translation for a key the locale carries, and the provider's English literal for a key it does not.
|
|
220
|
+
- id: REPORTS-PERIOD
|
|
221
|
+
given: One provider that answers a period of its own and one that answers none.
|
|
222
|
+
when: The report is read and rendered.
|
|
223
|
+
then: The first report carries that period and its card is captioned with it, and the second carries none and its card is captioned with the range the request asked for.
|
|
224
|
+
- id: REPORTS-METERING-USAGE
|
|
225
|
+
given: A workspace with recorded meter facts this month and an operator limit on one meter.
|
|
226
|
+
when: The metering usage provider is read.
|
|
227
|
+
then: It answers one tile per meter with this month's usage as the value, the meter's unit carrying the monthly limit as its context, at most 16 tiles ordered by usage, and no series, and it names its own calendar month as the period those tiles cover.
|
|
228
|
+
- id: REPORTS-AGENTS-RUNS
|
|
229
|
+
given: A workspace with agent runs settled on several days inside and outside the range.
|
|
230
|
+
when: The agents runs provider is read.
|
|
231
|
+
then: It answers the runs and token totals of the range as tiles and runs and tokens per day as two series read from the existing rollup, with only the days inside the range, and names itself, its tiles and its lines with keys of its own bundle.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEndpoint,
|
|
3
|
+
jsonResponse,
|
|
4
|
+
problemResponse,
|
|
5
|
+
} from '@flowdular/sdk/server';
|
|
6
|
+
import type { AuthPrincipal } from '@flowdular/sdk/modules/auth';
|
|
7
|
+
import type { AuthRuntime } from '@flowdular/sdk/modules/auth/server';
|
|
8
|
+
import {
|
|
9
|
+
endpointIdentityFromContext,
|
|
10
|
+
principalFromContext,
|
|
11
|
+
} from '@flowdular/sdk/modules/auth/server';
|
|
12
|
+
import { REPORTS_PERMISSIONS } from '../acl/permissions.ts';
|
|
13
|
+
import type { ReportsRuntime } from '../server/runtime.ts';
|
|
14
|
+
import { readReportRange } from '../services/range.ts';
|
|
15
|
+
import { ReportsServiceError } from '../services/service-error.ts';
|
|
16
|
+
|
|
17
|
+
function failure(error: unknown): Response {
|
|
18
|
+
if (error instanceof ReportsServiceError) {
|
|
19
|
+
return jsonResponse(
|
|
20
|
+
{ error: { code: error.code, message: error.message } },
|
|
21
|
+
error.status,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
return problemResponse(error, 'The reports operation failed.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function reportPrincipal(principal: AuthPrincipal) {
|
|
28
|
+
return {
|
|
29
|
+
accountId: principal.accountId,
|
|
30
|
+
tenantId: principal.tenantId,
|
|
31
|
+
scopes: principal.scopes,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createReportsRoutes(
|
|
36
|
+
_auth: AuthRuntime,
|
|
37
|
+
runtime: ReportsRuntime,
|
|
38
|
+
) {
|
|
39
|
+
/* A read: no body, no CSRF token and no tenant identifier from the request.
|
|
40
|
+
The principal the endpoint resolved is the only tenant authority. */
|
|
41
|
+
const read = defineEndpoint({
|
|
42
|
+
id: 'reports.workspace.read',
|
|
43
|
+
path: '/api/reports',
|
|
44
|
+
methods: ['GET'],
|
|
45
|
+
access: { kind: 'permission', permission: REPORTS_PERMISSIONS.read },
|
|
46
|
+
resolveIdentity: endpointIdentityFromContext,
|
|
47
|
+
handler: async ({ octane }) => {
|
|
48
|
+
try {
|
|
49
|
+
const principal = principalFromContext(octane)!;
|
|
50
|
+
const url = new URL(octane.request.url);
|
|
51
|
+
return jsonResponse(
|
|
52
|
+
await runtime.service().read({
|
|
53
|
+
principal: reportPrincipal(principal),
|
|
54
|
+
range: readReportRange(
|
|
55
|
+
{
|
|
56
|
+
from: url.searchParams.get('from'),
|
|
57
|
+
to: url.searchParams.get('to'),
|
|
58
|
+
},
|
|
59
|
+
Date.now(),
|
|
60
|
+
),
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return failure(error);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return [read.serverRoute] as const;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const endpoints = ['reports.workspace.read'] as const;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'octane';
|
|
2
|
+
import { Kpi } from '@flowdular/sdk/ui';
|
|
3
|
+
import { activeLocale, t, workspaceViewHref } from '@flowdular/sdk/client';
|
|
4
|
+
import { useValue } from 'segment-state';
|
|
5
|
+
import { loadReport } from './api.ts';
|
|
6
|
+
import { REPORTS_VIEWS } from './navigation.ts';
|
|
7
|
+
import { largestTiles, numberLabel, resolvedLabel } from './presentation.ts';
|
|
8
|
+
import { createReportsWidgetState } from './state.ts';
|
|
9
|
+
|
|
10
|
+
/** Tiles the dashboard shows; the largest of the whole report come first. */
|
|
11
|
+
const TILES = 3;
|
|
12
|
+
|
|
13
|
+
const REFRESH_INTERVAL_MS = 300_000;
|
|
14
|
+
|
|
15
|
+
export function ReportsSummaryWidget() @{
|
|
16
|
+
const client = useMemo(() => createReportsWidgetState(), []);
|
|
17
|
+
const [reports] = useValue(client.state.reports);
|
|
18
|
+
const locale = activeLocale();
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const refresh = async () => {
|
|
22
|
+
try {
|
|
23
|
+
const page = await loadReport();
|
|
24
|
+
client.store.act(
|
|
25
|
+
(transaction) => transaction.set(client.state.reports, page.reports),
|
|
26
|
+
'reports/widget-loaded',
|
|
27
|
+
);
|
|
28
|
+
} catch {
|
|
29
|
+
/* The dashboard shows the tiles it has. A workspace without the
|
|
30
|
+
scope, or a provider that is briefly unreachable, leaves the row
|
|
31
|
+
as it was rather than pushing an error into it. */
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
void refresh();
|
|
35
|
+
const timer = setInterval(() => void refresh(), REFRESH_INTERVAL_MS);
|
|
36
|
+
return () => clearInterval(timer);
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
const largest = largestTiles(reports, TILES);
|
|
40
|
+
const reportsHref = workspaceViewHref(REPORTS_VIEWS.reports);
|
|
41
|
+
|
|
42
|
+
@for (const entry of largest; key entry.report.key + '/' + entry.tile.key) {
|
|
43
|
+
<Kpi
|
|
44
|
+
label={resolvedLabel(t, entry.tile.label, entry.tile.tileLabelKey)}
|
|
45
|
+
value={numberLabel(locale, entry.tile.value)}
|
|
46
|
+
unit={entry.tile.unit ?? ''}
|
|
47
|
+
note={resolvedLabel(t, entry.report.label, entry.report.labelKey)}
|
|
48
|
+
href={reportsHref}
|
|
49
|
+
linkLabel={t('reports.widget.link')}
|
|
50
|
+
/>
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'octane';
|
|
2
|
+
import {
|
|
3
|
+
Alert,
|
|
4
|
+
Button,
|
|
5
|
+
Chart,
|
|
6
|
+
DateRangeField,
|
|
7
|
+
EmptyState,
|
|
8
|
+
Icon,
|
|
9
|
+
Kpi,
|
|
10
|
+
PageHeader,
|
|
11
|
+
} from '@flowdular/sdk/ui';
|
|
12
|
+
import { activeLocale, t } from '@flowdular/sdk/client';
|
|
13
|
+
import { useValue } from 'segment-state';
|
|
14
|
+
import { REPORT_LIMITS } from '../domain/types.ts';
|
|
15
|
+
import { loadReport, ReportsApiError, reportsErrorMessage } from './api.ts';
|
|
16
|
+
import {
|
|
17
|
+
dayLabel,
|
|
18
|
+
deltaLabel,
|
|
19
|
+
numberLabel,
|
|
20
|
+
rangeTooWide,
|
|
21
|
+
reportCaption,
|
|
22
|
+
resolvedLabel,
|
|
23
|
+
screenSurface,
|
|
24
|
+
} from './presentation.ts';
|
|
25
|
+
import { createReportsClientState } from './state.ts';
|
|
26
|
+
|
|
27
|
+
export interface ReportsViewProps {
|
|
28
|
+
readonly csrfToken: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const CHART_HEIGHT = 220;
|
|
32
|
+
|
|
33
|
+
export function ReportsView(_props: ReportsViewProps) @{
|
|
34
|
+
const client = useMemo(() => createReportsClientState(), []);
|
|
35
|
+
const [reports] = useValue(client.state.reports);
|
|
36
|
+
const [range] = useValue(client.state.range);
|
|
37
|
+
const [unavailable] = useValue(client.state.unavailable);
|
|
38
|
+
const [status, setStatus] = useValue(client.state.status);
|
|
39
|
+
const [error, setError] = useValue(client.state.error);
|
|
40
|
+
const [from, setFrom] = useValue(client.state.from);
|
|
41
|
+
const [to, setTo] = useValue(client.state.to);
|
|
42
|
+
const locale = activeLocale();
|
|
43
|
+
|
|
44
|
+
const refresh = async (asked: { from: string; to: string }) => {
|
|
45
|
+
setStatus('loading');
|
|
46
|
+
setError('');
|
|
47
|
+
try {
|
|
48
|
+
const page = await loadReport(asked);
|
|
49
|
+
client.store.act((transaction) => {
|
|
50
|
+
transaction.set(client.state.reports, page.reports);
|
|
51
|
+
transaction.set(client.state.range, page.range);
|
|
52
|
+
transaction.set(client.state.unavailable, page.unavailable);
|
|
53
|
+
transaction.set(client.state.from, page.range.from);
|
|
54
|
+
transaction.set(client.state.to, page.range.to);
|
|
55
|
+
transaction.set(client.state.status, 'idle');
|
|
56
|
+
}, 'reports/loaded');
|
|
57
|
+
} catch (loadError) {
|
|
58
|
+
setError(reportsErrorMessage(loadError, 'reports.error.load'));
|
|
59
|
+
setStatus(
|
|
60
|
+
loadError instanceof ReportsApiError && loadError.status === 403
|
|
61
|
+
? 'denied'
|
|
62
|
+
: 'error',
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/* The server refuses a range past the same bound, so the screen keeps the
|
|
68
|
+
reader's dates and says so instead of spending a request on the answer. */
|
|
69
|
+
const ask = (asked: { from: string; to: string }) => {
|
|
70
|
+
if (!rangeTooWide(asked.from, asked.to)) {
|
|
71
|
+
void refresh(asked);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
client.store.act((transaction) => {
|
|
75
|
+
transaction.set(
|
|
76
|
+
client.state.error,
|
|
77
|
+
t('reports.range.tooWide', { days: REPORT_LIMITS.rangeDays }),
|
|
78
|
+
);
|
|
79
|
+
transaction.set(client.state.status, 'error');
|
|
80
|
+
}, 'reports/range-too-wide');
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
void refresh({ from: '', to: '' });
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
87
|
+
const surface = screenSurface(status, reports);
|
|
88
|
+
|
|
89
|
+
<div class="ui-view">
|
|
90
|
+
<PageHeader
|
|
91
|
+
eyebrow={t('reports.page.eyebrow')}
|
|
92
|
+
title={t('reports.page.title')}
|
|
93
|
+
description={t('reports.page.description')}
|
|
94
|
+
>
|
|
95
|
+
<Button
|
|
96
|
+
size="sm"
|
|
97
|
+
disabled={status === 'denied'}
|
|
98
|
+
onClick={() => ask({ from, to })}
|
|
99
|
+
>
|
|
100
|
+
<Icon name="refresh" size={14} />
|
|
101
|
+
{status === 'loading'
|
|
102
|
+
? t('reports.action.refreshing')
|
|
103
|
+
: t('reports.action.refresh')}
|
|
104
|
+
</Button>
|
|
105
|
+
</PageHeader>
|
|
106
|
+
@if (surface === 'denied') {
|
|
107
|
+
<section class="ui-card">
|
|
108
|
+
<EmptyState icon="shield" title={t('reports.denied.title')}>{t(
|
|
109
|
+
'reports.denied.hint',
|
|
110
|
+
)}</EmptyState>
|
|
111
|
+
</section>
|
|
112
|
+
} @else {
|
|
113
|
+
<>
|
|
114
|
+
@if (surface === 'error') {
|
|
115
|
+
<Alert>{error}</Alert>
|
|
116
|
+
}
|
|
117
|
+
<section class="ui-card">
|
|
118
|
+
<div class="ui-card__body">
|
|
119
|
+
<DateRangeField
|
|
120
|
+
id="reports-range"
|
|
121
|
+
legend={t('reports.range.legend')}
|
|
122
|
+
fromLabel={t('reports.range.from')}
|
|
123
|
+
toLabel={t('reports.range.to')}
|
|
124
|
+
value={{ from, to }}
|
|
125
|
+
locale={locale}
|
|
126
|
+
reversedMessage={t('reports.range.reversed')}
|
|
127
|
+
help={t('reports.range.help')}
|
|
128
|
+
error={surface === 'error' ? error : ''}
|
|
129
|
+
disabled={status === 'loading'}
|
|
130
|
+
onChange={(value: { from: string; to: string }) => {
|
|
131
|
+
setFrom(value.from);
|
|
132
|
+
setTo(value.to);
|
|
133
|
+
if (
|
|
134
|
+
value.from !== '' && value.to !== '' && value.from <= value.to
|
|
135
|
+
) {
|
|
136
|
+
ask(value);
|
|
137
|
+
}
|
|
138
|
+
}}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
</section>
|
|
142
|
+
</>
|
|
143
|
+
}
|
|
144
|
+
@if (surface !== 'denied' && surface !== 'error') {
|
|
145
|
+
<>
|
|
146
|
+
@if (unavailable.length > 0) {
|
|
147
|
+
<Alert tone="warning">{t('reports.unavailable', {
|
|
148
|
+
providers: unavailable.join(', '),
|
|
149
|
+
})}</Alert>
|
|
150
|
+
}
|
|
151
|
+
@if (surface === 'loading') {
|
|
152
|
+
<section class="ui-card">
|
|
153
|
+
<EmptyState icon="activity" title={t('reports.loading.title')}>{t(
|
|
154
|
+
'reports.loading.hint',
|
|
155
|
+
)}</EmptyState>
|
|
156
|
+
</section>
|
|
157
|
+
} @else if (surface === 'empty') {
|
|
158
|
+
<section class="ui-card">
|
|
159
|
+
<EmptyState icon="activity" title={t('reports.empty.title')}>{t(
|
|
160
|
+
'reports.empty.hint',
|
|
161
|
+
)}</EmptyState>
|
|
162
|
+
</section>
|
|
163
|
+
} @else {
|
|
164
|
+
<>
|
|
165
|
+
@for (const report of reports; key report.key) {
|
|
166
|
+
<section class="ui-card">
|
|
167
|
+
<div class="ui-card__head">
|
|
168
|
+
<span class="ui-card__title">
|
|
169
|
+
{resolvedLabel(t, report.label, report.labelKey)}
|
|
170
|
+
<small>{reportCaption(
|
|
171
|
+
t,
|
|
172
|
+
(value: string) => dayLabel(locale, value),
|
|
173
|
+
report,
|
|
174
|
+
range,
|
|
175
|
+
)}</small>
|
|
176
|
+
</span>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="ui-card__body">
|
|
179
|
+
@if (report.tiles.length === 0) {
|
|
180
|
+
<EmptyState
|
|
181
|
+
icon="activity"
|
|
182
|
+
title={t('reports.report.emptyTitle')}
|
|
183
|
+
>{t('reports.report.emptyHint')}</EmptyState>
|
|
184
|
+
} @else {
|
|
185
|
+
<div class="ui-kpi-grid">
|
|
186
|
+
@for (const tile of report.tiles; key tile.key) {
|
|
187
|
+
<Kpi
|
|
188
|
+
label={resolvedLabel(
|
|
189
|
+
t,
|
|
190
|
+
tile.label,
|
|
191
|
+
tile.tileLabelKey,
|
|
192
|
+
)}
|
|
193
|
+
value={numberLabel(locale, tile.value)}
|
|
194
|
+
unit={tile.unit ?? ''}
|
|
195
|
+
note={tile.delta === undefined
|
|
196
|
+
? ''
|
|
197
|
+
: t('reports.tile.delta', {
|
|
198
|
+
delta: deltaLabel(locale, tile.delta),
|
|
199
|
+
})}
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
202
|
+
</div>
|
|
203
|
+
}
|
|
204
|
+
@for (const series of report.series; key series.key) {
|
|
205
|
+
<Chart
|
|
206
|
+
type="area"
|
|
207
|
+
xKey="at"
|
|
208
|
+
height={CHART_HEIGHT}
|
|
209
|
+
title={resolvedLabel(
|
|
210
|
+
t,
|
|
211
|
+
series.label,
|
|
212
|
+
series.seriesLabelKey,
|
|
213
|
+
)}
|
|
214
|
+
data={series.points}
|
|
215
|
+
series={[
|
|
216
|
+
{
|
|
217
|
+
key: 'value',
|
|
218
|
+
label: resolvedLabel(
|
|
219
|
+
t,
|
|
220
|
+
series.label,
|
|
221
|
+
series.seriesLabelKey,
|
|
222
|
+
),
|
|
223
|
+
},
|
|
224
|
+
]}
|
|
225
|
+
xTickFormatter={(value: string) => dayLabel(
|
|
226
|
+
locale,
|
|
227
|
+
value,
|
|
228
|
+
)}
|
|
229
|
+
valueFormatter={(value: number) => numberLabel(
|
|
230
|
+
locale,
|
|
231
|
+
value,
|
|
232
|
+
)}
|
|
233
|
+
emptyIcon="activity"
|
|
234
|
+
emptyTitle={t('reports.series.emptyTitle')}
|
|
235
|
+
emptyHint={t('reports.series.emptyHint')}
|
|
236
|
+
/>
|
|
237
|
+
}
|
|
238
|
+
</div>
|
|
239
|
+
</section>
|
|
240
|
+
}
|
|
241
|
+
</>
|
|
242
|
+
}
|
|
243
|
+
</>
|
|
244
|
+
}
|
|
245
|
+
</div>
|
|
246
|
+
}
|