@taskforcehq/taskforce 0.3.169 → 0.3.300
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/README.md +52 -21
- package/dist/Taskforce.module.css +3394 -5981
- package/dist/TaskforceCore.CategoryFallback.test.js +5 -2
- package/dist/TaskforceCore.filter-persistence.test.js +402 -0
- package/dist/TaskforceCore.js +388 -71
- package/dist/TaskforceCore.routing.test.js +311 -0
- package/dist/TaskforceCore.test.js +3344 -615
- package/dist/TaskforceWidget.js +3 -2
- package/dist/__tests__/localizationCatalogs.test.js +48 -31
- package/dist/__tests__/workflowSimulation.test.js +2 -2
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.d.ts +60 -0
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +324 -0
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.test.js +278 -0
- package/dist/annotatedAttachments/payload.d.ts +2 -0
- package/dist/annotatedAttachments/payload.js +54 -0
- package/dist/annotatedAttachments/payload.test.js +67 -0
- package/dist/annotatedAttachments/service.d.ts +49 -0
- package/dist/annotatedAttachments/service.js +121 -0
- package/dist/annotatedAttachments/types.d.ts +86 -0
- package/dist/cli.js +74 -25
- package/dist/compat/deploymentCompat.d.ts +12 -0
- package/dist/compat/deploymentCompat.js +43 -0
- package/dist/compat/workspaceSyncCompat.d.ts +6 -0
- package/dist/compat/workspaceSyncCompat.js +79 -0
- package/dist/compat/workspaceSyncCompat.test.js +87 -0
- package/dist/components/features/AgentsModule.d.ts +5 -0
- package/dist/components/features/AgentsModule.js +131 -0
- package/dist/components/features/AgentsModule.test.js +102 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +24 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +1942 -0
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +2831 -0
- package/dist/components/features/DocumentGenerateModal.js +8 -16
- package/dist/components/features/DocumentIndex.d.ts +3 -4
- package/dist/components/features/DocumentIndex.js +22 -10
- package/dist/components/features/DocumentViewer.d.ts +6 -2
- package/dist/components/features/DocumentViewer.js +1000 -18
- package/dist/components/features/DocumentWorkspace.d.ts +40 -2
- package/dist/components/features/DocumentWorkspace.js +96 -16
- package/dist/components/features/DocumentWorkspace.test.js +1202 -0
- package/dist/components/features/InitiativesModule.d.ts +22 -0
- package/dist/components/features/InitiativesModule.js +33 -0
- package/dist/components/features/TaskSettings.d.ts +41 -32
- package/dist/components/features/TaskSettings.js +798 -313
- package/dist/components/features/TaskSettings.test.js +1221 -47
- package/dist/components/features/WorkflowsModule.d.ts +27 -0
- package/dist/components/features/WorkflowsModule.js +21 -0
- package/dist/components/features/documentWorkspaceFilters.d.ts +10 -0
- package/dist/components/features/documentWorkspaceFilters.js +11 -0
- package/dist/components/features/settings/CategoryManager.d.ts +2 -0
- package/dist/components/features/settings/CategoryManager.js +15 -8
- package/dist/components/features/settings/PriorityManager.d.ts +18 -0
- package/dist/components/features/settings/PriorityManager.js +51 -0
- package/dist/components/features/settings/TaxonomyEditor.d.ts +2 -1
- package/dist/components/features/settings/TaxonomyEditor.js +41 -18
- package/dist/components/features/settings/TaxonomyLibraryManager.d.ts +26 -0
- package/dist/components/features/settings/TaxonomyLibraryManager.js +301 -0
- package/dist/components/features/settings/TaxonomyLibraryManager.test.js +141 -0
- package/dist/components/features/settings/TaxonomyManager.d.ts +35 -12
- package/dist/components/features/settings/TaxonomyManager.js +59 -27
- package/dist/components/features/settings/TypeManager.d.ts +11 -0
- package/dist/components/features/settings/TypeManager.js +48 -11
- package/dist/components/features/settings/{WorkflowEditorPrototype.d.ts → WorkflowEditor.d.ts} +2 -2
- package/dist/components/features/settings/{WorkflowEditorPrototype.js → WorkflowEditor.js} +3 -3
- package/dist/components/task/TaskActionHeader.d.ts +12 -2
- package/dist/components/task/TaskActionHeader.js +64 -8
- package/dist/components/task/TaskActionHeader.test.js +73 -0
- package/dist/components/task/TaskCard.d.ts +14 -16
- package/dist/components/task/TaskCard.js +144 -174
- package/dist/components/task/TaskCard.test.js +416 -64
- package/dist/components/task/TaskContextUpload.d.ts +6 -5
- package/dist/components/task/TaskContextUpload.js +199 -64
- package/dist/components/task/TaskContextUpload.test.js +331 -14
- package/dist/components/task/TaskForm.d.ts +23 -29
- package/dist/components/task/TaskForm.js +348 -169
- package/dist/components/task/TaskForm.test.js +419 -23
- package/dist/components/task/TaskKanban.d.ts +20 -21
- package/dist/components/task/TaskKanban.js +176 -316
- package/dist/components/task/TaskKanban.planning-drop.test.js +93 -0
- package/dist/components/task/TaskList.d.ts +22 -11
- package/dist/components/task/TaskList.js +98 -12
- package/dist/components/task/TaskList.test.js +206 -7
- package/dist/components/task/TaskReferenceBadge.d.ts +12 -0
- package/dist/components/task/TaskReferenceBadge.js +5 -0
- package/dist/components/task/TaskStatusActions.d.ts +12 -0
- package/dist/components/task/TaskStatusActions.js +18 -0
- package/dist/components/task/TaskStatusActions.test.js +45 -0
- package/dist/components/ui/ImageReferenceBadge.d.ts +12 -0
- package/dist/components/ui/ImageReferenceBadge.js +5 -0
- package/dist/components/ui/LevelSelector.d.ts +2 -1
- package/dist/components/ui/LevelSelector.js +2 -2
- package/dist/components/ui/Markdown.d.ts +1 -2
- package/dist/components/ui/Markdown.js +2 -13
- package/dist/components/ui/Modal.d.ts +3 -2
- package/dist/components/ui/Modal.js +4 -3
- package/dist/components/ui/MultiSelectFilter.d.ts +3 -1
- package/dist/components/ui/MultiSelectFilter.js +2 -2
- package/dist/components/ui/ReferenceBadgeButton.d.ts +13 -0
- package/dist/components/ui/ReferenceBadgeButton.js +6 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +7 -1
- package/dist/components/ui/TaxonomyDropdown.js +58 -23
- package/dist/components/ui/TopNoticeLayer.d.ts +7 -0
- package/dist/components/ui/TopNoticeLayer.js +14 -0
- package/dist/components/ui/TopNoticeLayer.test.js +25 -0
- package/dist/components/views/AppShellHeader.d.ts +13 -0
- package/dist/components/views/AppShellHeader.js +19 -0
- package/dist/components/views/AppShellHeader.test.js +21 -0
- package/dist/components/views/PlanComparisonPage.d.ts +73 -0
- package/dist/components/views/PlanComparisonPage.js +196 -0
- package/dist/components/views/PlanComparisonPage.test.js +251 -0
- package/dist/components/views/PlansPage.d.ts +14 -0
- package/dist/components/views/PlansPage.js +355 -0
- package/dist/components/views/StandaloneLayout.d.ts +2 -2
- package/dist/components/views/StandaloneLayout.js +2212 -1194
- package/dist/components/views/WidgetView.d.ts +2 -2
- package/dist/components/views/WidgetView.js +149 -43
- package/dist/components/views/chrome/WorkspaceChromeSections.d.ts +57 -0
- package/dist/components/views/chrome/WorkspaceChromeSections.js +38 -0
- package/dist/components/views/chrome/WorkspaceChromeSections.test.js +54 -0
- package/dist/components/views/chrome/workspaceChrome.d.ts +31 -0
- package/dist/components/views/chrome/workspaceChrome.js +108 -0
- package/dist/components/views/chrome/workspaceChrome.test.js +52 -0
- package/dist/components/views/panels/DocumentFilterToolbar.d.ts +10 -0
- package/dist/components/views/panels/DocumentFilterToolbar.js +7 -0
- package/dist/components/views/panels/DocumentFilterToolbar.test.js +19 -0
- package/dist/components/views/panels/FilterToolbar.d.ts +66 -0
- package/dist/components/views/panels/FilterToolbar.js +21 -0
- package/dist/components/views/panels/FilterToolbar.test.d.ts +1 -0
- package/dist/components/views/panels/FilterToolbar.test.js +45 -0
- package/dist/components/views/panels/FilterToolbarControls.d.ts +46 -0
- package/dist/components/views/panels/FilterToolbarControls.js +61 -0
- package/dist/components/views/panels/PlanningDrawer.d.ts +115 -0
- package/dist/components/views/panels/PlanningDrawer.js +220 -0
- package/dist/components/views/panels/ScheduleSidebar.d.ts +52 -0
- package/dist/components/views/panels/ScheduleSidebar.js +127 -0
- package/dist/components/views/panels/scheduleUtils.d.ts +14 -0
- package/dist/components/views/panels/scheduleUtils.js +79 -0
- package/dist/components/views/teamManagementAccess.d.ts +6 -0
- package/dist/components/views/teamManagementAccess.js +18 -0
- package/dist/components/views/teamManagementAccess.test.d.ts +1 -0
- package/dist/components/views/teamManagementAccess.test.js +44 -0
- package/dist/config/clientDeployment.d.ts +2 -0
- package/dist/config/clientDeployment.js +13 -0
- package/dist/config/cloudEnvironment.d.ts +15 -0
- package/dist/config/cloudEnvironment.js +60 -0
- package/dist/config/deployment.d.ts +20 -0
- package/dist/config/deployment.js +67 -0
- package/dist/config/deployment.test.d.ts +1 -0
- package/dist/config/deployment.test.js +88 -0
- package/dist/config/envSchema.js +36 -8
- package/dist/config/envSchema.test.js +28 -0
- package/dist/core/AiProfileService.d.ts +66 -0
- package/dist/core/AiProfileService.js +320 -0
- package/dist/core/AiProfileService.test.d.ts +1 -0
- package/dist/core/AiProfileService.test.js +164 -0
- package/dist/core/AiProfiles.test.d.ts +1 -0
- package/dist/core/AiProfiles.test.js +449 -0
- package/dist/core/AttachmentLinkService.d.ts +15 -0
- package/dist/core/AttachmentLinkService.js +157 -0
- package/dist/core/AuthTokenService.d.ts +44 -0
- package/dist/core/AuthTokenService.js +207 -0
- package/dist/core/CreatedBy.test.js +134 -6
- package/dist/core/DeletedTaskLifecycleService.d.ts +33 -0
- package/dist/core/DeletedTaskLifecycleService.js +158 -0
- package/dist/core/DeletedTaskTrash.test.d.ts +1 -0
- package/dist/core/DeletedTaskTrash.test.js +104 -0
- package/dist/core/EntitlementsPolicy.test.js +78 -5
- package/dist/core/GlobalSettingsService.d.ts +16 -0
- package/dist/core/GlobalSettingsService.js +370 -0
- package/dist/core/JsonBackupRuntime.test.d.ts +1 -0
- package/dist/core/JsonBackupRuntime.test.js +155 -0
- package/dist/core/McpTokenService.d.ts +118 -0
- package/dist/core/McpTokenService.js +921 -0
- package/dist/core/PlanEntitlementService.d.ts +201 -0
- package/dist/core/PlanEntitlementService.js +1442 -0
- package/dist/core/PlanVersionPolicy.test.d.ts +1 -0
- package/dist/core/PlanVersionPolicy.test.js +178 -0
- package/dist/core/PlanningEntities.test.d.ts +1 -0
- package/dist/core/PlanningEntities.test.js +95 -0
- package/dist/core/ScheduleFields.test.js +15 -19
- package/dist/core/SignupMonetizationSettings.test.d.ts +1 -0
- package/dist/core/SignupMonetizationSettings.test.js +159 -0
- package/dist/core/Stats.test.d.ts +1 -0
- package/dist/core/Stats.test.js +36 -0
- package/dist/core/SyncReconciliationService.d.ts +93 -0
- package/dist/core/SyncReconciliationService.js +406 -0
- package/dist/core/SystemAdmin.test.js +578 -13
- package/dist/core/TaskActivityService.d.ts +21 -0
- package/dist/core/TaskActivityService.js +130 -0
- package/dist/core/TaskAttachmentsCanonical.test.d.ts +1 -0
- package/dist/core/TaskAttachmentsCanonical.test.js +306 -0
- package/dist/core/TaskAuditTimeline.test.d.ts +1 -0
- package/dist/core/TaskAuditTimeline.test.js +132 -0
- package/dist/core/TaskTaxonomyValidation.test.js +338 -15
- package/dist/core/Taskforce.d.ts +930 -183
- package/dist/core/Taskforce.ids.test.js +252 -0
- package/dist/core/Taskforce.js +3848 -2532
- package/dist/core/Taskforce.mcpAuth.test.d.ts +1 -0
- package/dist/core/Taskforce.mcpAuth.test.js +343 -0
- package/dist/core/Taskforce.realtimeMutation.test.js +57 -2
- package/dist/core/TaxonomySettingsService.d.ts +18 -0
- package/dist/core/TaxonomySettingsService.js +162 -0
- package/dist/core/WorkspaceDelete.test.js +32 -13
- package/dist/core/WorkspaceLifecycleService.d.ts +11 -0
- package/dist/core/WorkspaceLifecycleService.js +88 -0
- package/dist/core/WorkspacePermissions.test.js +95 -0
- package/dist/core/WorkspacePlanMode.test.js +114 -1
- package/dist/core/WorkspacePreferenceService.d.ts +41 -0
- package/dist/core/WorkspacePreferenceService.js +246 -0
- package/dist/core/WorkspaceSyncSettings.test.d.ts +1 -0
- package/dist/core/WorkspaceSyncSettings.test.js +65 -0
- package/dist/core/__tests__/TaskAttachmentsCanonical.test.d.ts +1 -0
- package/dist/core/__tests__/TaskAttachmentsCanonical.test.js +212 -0
- package/dist/core/shared.d.ts +36 -0
- package/dist/core/shared.js +128 -0
- package/dist/core/types.d.ts +614 -0
- package/dist/core/types.js +27 -0
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +56 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +230 -0
- package/dist/documentReviews/DocumentReviewSessionStore.d.ts +52 -0
- package/dist/documentReviews/DocumentReviewSessionStore.js +193 -0
- package/dist/documentReviews/DocumentReviewSessionStore.test.d.ts +1 -0
- package/dist/documentReviews/DocumentReviewSessionStore.test.js +127 -0
- package/dist/documentReviews/service.d.ts +68 -0
- package/dist/documentReviews/service.js +210 -0
- package/dist/documentReviews/types.d.ts +58 -0
- package/dist/documentReviews/types.js +1 -0
- package/dist/hooks/auth/useAuthGuardPolicy.d.ts +2 -0
- package/dist/hooks/auth/useAuthGuardPolicy.js +1 -0
- package/dist/hooks/tasks/useCurrentTaskRelations.d.ts +15 -0
- package/dist/hooks/tasks/useCurrentTaskRelations.js +37 -0
- package/dist/hooks/tasks/useTaskActions.d.ts +3 -0
- package/dist/hooks/tasks/useTaskActions.js +2 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +65 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.js +235 -0
- package/dist/hooks/tasks/useTaskFilters.d.ts +2 -0
- package/dist/hooks/tasks/useTaskFilters.js +2 -0
- package/dist/hooks/tasks/useTaskFormActions.d.ts +58 -0
- package/dist/hooks/tasks/useTaskFormActions.js +365 -0
- package/dist/hooks/tasks/useTaskRelationships.d.ts +16 -0
- package/dist/hooks/tasks/useTaskRelationships.js +64 -0
- package/dist/hooks/ui/useResourceExport.d.ts +19 -0
- package/dist/hooks/ui/useResourceExport.js +84 -0
- package/dist/hooks/ui/useSettingsModel.d.ts +203 -0
- package/dist/hooks/ui/useSettingsModel.js +125 -0
- package/dist/hooks/ui/useSettingsPersistence.d.ts +36 -0
- package/dist/hooks/ui/useSettingsPersistence.js +254 -0
- package/dist/hooks/ui/useSettingsTaxonomyManagement.d.ts +119 -0
- package/dist/hooks/ui/useSettingsTaxonomyManagement.js +536 -0
- package/dist/hooks/ui/useUiNotice.d.ts +1 -0
- package/dist/hooks/ui/useUiNotice.js +1 -0
- package/dist/hooks/ui/useWorkflowTemplates.d.ts +37 -0
- package/dist/hooks/ui/useWorkflowTemplates.js +111 -0
- package/dist/hooks/ui/useZenMode.d.ts +5 -0
- package/dist/hooks/ui/useZenMode.js +32 -0
- package/dist/hooks/useFilterSort.d.ts +60 -0
- package/dist/hooks/useFilterSort.js +362 -0
- package/dist/hooks/useFilterSort.test.d.ts +1 -0
- package/dist/hooks/useFilterSort.test.js +333 -0
- package/dist/hooks/useRealtimeSync.d.ts +1 -0
- package/dist/hooks/useRealtimeSync.js +24 -9
- package/dist/hooks/useRealtimeSync.test.js +28 -1
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.d.ts +1 -0
- package/dist/hooks/useSyncOrchestrator.aiProfiles.test.js +34 -0
- package/dist/hooks/useSyncOrchestrator.d.ts +65 -103
- package/dist/hooks/useSyncOrchestrator.js +1538 -670
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +700 -174
- package/dist/hooks/useTaskData.d.ts +35 -0
- package/dist/hooks/useTaskData.js +239 -0
- package/dist/hooks/useTaskData.test.d.ts +1 -0
- package/dist/hooks/useTaskData.test.js +119 -0
- package/dist/hooks/useTaskMutations.d.ts +46 -0
- package/dist/hooks/useTaskMutations.js +472 -0
- package/dist/hooks/useTaskMutations.test.d.ts +1 -0
- package/dist/hooks/useTaskMutations.test.js +80 -0
- package/dist/hooks/useTaskforce.contract.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.contract.test.js +7 -0
- package/dist/hooks/useTaskforce.d.ts +260 -295
- package/dist/hooks/useTaskforce.js +1954 -2623
- package/dist/hooks/useTaskforce.priority-filters.test.js +6 -11
- package/dist/hooks/useTaskforce.sync-behavior.test.d.ts +1 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +1120 -0
- package/dist/hooks/useUiNotice.d.ts +16 -0
- package/dist/hooks/useUiNotice.js +49 -0
- package/dist/hooks/useWorkspaceSyncController.d.ts +23 -46
- package/dist/hooks/useWorkspaceSyncController.js +280 -461
- package/dist/hooks/useWorkspaceSyncController.test.js +106 -199
- package/dist/hooks/workspace/useTaskforceApiRouting.d.ts +8 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.js +91 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.test.d.ts +1 -0
- package/dist/hooks/workspace/useTaskforceApiRouting.test.js +60 -0
- package/dist/hooks/workspace/useWorkspaceSyncController.d.ts +1 -0
- package/dist/hooks/workspace/useWorkspaceSyncController.js +1 -0
- package/dist/hooks/workspace/workspaceLocalState.d.ts +30 -0
- package/dist/hooks/workspace/workspaceLocalState.js +101 -0
- package/dist/localization/locales/en-US.d.ts +1 -8
- package/dist/localization/locales/en-US.js +4 -11
- package/dist/localization/locales/es-419.js +2 -9
- package/dist/localization/locales/pt-BR.js +2 -9
- package/dist/localization/localizationCatalogs.test.d.ts +1 -0
- package/dist/localization/localizationCatalogs.test.js +37 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +9 -15
- package/dist/mcp/clientIntegrations.d.ts +33 -0
- package/dist/mcp/clientIntegrations.js +199 -0
- package/dist/mcp/clientIntegrations.test.d.ts +1 -0
- package/dist/mcp/clientIntegrations.test.js +110 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/optionResolution.test.js +6 -2
- package/dist/mcp/runtime.d.ts +120 -0
- package/dist/mcp/runtime.js +5668 -0
- package/dist/mcp/runtime.test.d.ts +1 -0
- package/dist/mcp/runtime.test.js +3293 -0
- package/dist/mcp/server.js +2 -1793
- package/dist/mcp/structuredCommentValidation.test.d.ts +1 -0
- package/dist/{__tests__ → mcp}/structuredCommentValidation.test.js +1 -1
- package/dist/mcp/structuredDocValidation.js +1 -2
- package/dist/mcp/structuredDocValidation.test.d.ts +1 -0
- package/dist/{__tests__ → mcp}/structuredDocValidation.test.js +9 -4
- package/dist/mcp/toolRegistry.d.ts +570 -0
- package/dist/mcp/toolRegistry.js +90 -0
- package/dist/mcp/toolRegistry.test.d.ts +1 -0
- package/dist/mcp/toolRegistry.test.js +30 -0
- package/dist/migrations/billingSchemaParity.test.js +111 -0
- package/dist/migrations/taskSchemaMigrations.d.ts +5 -0
- package/dist/migrations/taskSchemaMigrations.js +681 -39
- package/dist/migrations/taskSchemaMigrations.test.d.ts +1 -0
- package/dist/migrations/taskSchemaMigrations.test.js +210 -0
- package/dist/plugins/vite.js +13 -7
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/archive/phoenix/apple-touch-icon.png +0 -0
- package/dist/public/archive/phoenix/favicon.ico +0 -0
- package/dist/public/archive/phoenix/site.webmanifest +1 -0
- package/dist/public/favicon-96x96.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/favicon.svg +17 -0
- package/dist/public/site.webmanifest +21 -1
- package/dist/public/web-app-manifest-192x192.png +0 -0
- package/dist/public/web-app-manifest-512x512.png +0 -0
- package/dist/releaseVersion.test.d.ts +1 -0
- package/dist/{__tests__/releaseVersion.test.js → releaseVersion.test.js} +1 -1
- package/dist/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
- package/dist/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
- package/dist/resources/templates/workflows/collaborate.yaml +11 -5
- package/dist/resources/templates/workflows/do.yaml +8 -2
- package/dist/resources/templates/workflows/evaluate.yaml +13 -7
- package/dist/resources/templates/workflows/execute.yaml +40 -23
- package/dist/resources/templates/workflows/plan.yaml +15 -8
- package/dist/resources/templates/workflows/review.yaml +14 -8
- package/dist/runtime/appGateDefinitions.d.ts +32 -0
- package/dist/runtime/appGateDefinitions.js +32 -0
- package/dist/runtime/appGates.d.ts +29 -0
- package/dist/runtime/appGates.js +53 -0
- package/dist/runtime/appGates.test.d.ts +1 -0
- package/dist/runtime/appGates.test.js +42 -0
- package/dist/runtime/migrationFlags.d.ts +1 -0
- package/dist/runtime/migrationFlags.js +1 -0
- package/dist/server/annotatedAttachmentsRoutes.test.d.ts +1 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +473 -0
- package/dist/server/auth.js +14 -2
- package/dist/server/auth.test.js +21 -1
- package/dist/server/cors.js +11 -5
- package/dist/server/cors.test.js +6 -0
- package/dist/server/documentReviewRoutes.test.d.ts +1 -0
- package/dist/server/documentReviewRoutes.test.js +157 -0
- package/dist/server/index.cookieProxy.test.js +46 -1
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.js +168 -41
- package/dist/server/index.rateLimit.test.js +6 -0
- package/dist/server/index.test.js +133 -2
- package/dist/server/mockStripe.d.ts +72 -0
- package/dist/server/mockStripe.js +357 -0
- package/dist/server/realtimeSyncWs.js +4 -0
- package/dist/server/routes/admin.d.ts +114 -0
- package/dist/server/routes/admin.js +2226 -0
- package/dist/server/routes/annotatedAttachments.d.ts +24 -0
- package/dist/server/routes/annotatedAttachments.js +235 -0
- package/dist/server/routes/auth.d.ts +61 -0
- package/dist/server/routes/auth.js +1296 -0
- package/dist/server/{routes.billing.d.ts → routes/billing.d.ts} +3 -2
- package/dist/server/routes/billing.js +2001 -0
- package/dist/server/routes/billing.test.d.ts +1 -0
- package/dist/server/routes/billing.test.js +1631 -0
- package/dist/server/routes/documentReviews.d.ts +11 -0
- package/dist/server/routes/documentReviews.js +191 -0
- package/dist/server/routes/documents.d.ts +118 -0
- package/dist/server/routes/documents.js +1113 -0
- package/dist/server/routes/resources.d.ts +25 -0
- package/dist/server/routes/resources.js +225 -0
- package/dist/server/routes/shared.d.ts +35 -0
- package/dist/server/routes/shared.js +305 -0
- package/dist/server/routes/shared.test.d.ts +1 -0
- package/dist/server/routes/shared.test.js +32 -0
- package/dist/server/{routes.sync.d.ts → routes/sync.d.ts} +5 -5
- package/dist/server/routes/sync.integration.test.d.ts +1 -0
- package/dist/server/routes/sync.integration.test.js +2003 -0
- package/dist/server/routes/sync.js +3143 -0
- package/dist/server/routes/tasks.d.ts +72 -0
- package/dist/server/routes/tasks.js +1252 -0
- package/dist/server/routes/workspaces.d.ts +32 -0
- package/dist/server/routes/workspaces.js +307 -0
- package/dist/server/routes.d.ts +8 -9
- package/dist/server/routes.js +968 -4092
- package/dist/server/routes.test.js +9043 -2415
- package/dist/server/runtimeMode.d.ts +1 -1
- package/dist/server/runtimeMode.js +3 -18
- package/dist/server/runtimeMode.test.js +3 -3
- package/dist/server/securityHeaders.d.ts +1 -1
- package/dist/server/securityHeaders.js +65 -6
- package/dist/server/securityHeaders.test.js +40 -2
- package/dist/services/templateEngine.test.d.ts +1 -0
- package/dist/{__tests__ → services}/templateEngine.test.js +1 -1
- package/dist/services/templates.test.d.ts +1 -0
- package/dist/{__tests__ → services}/templates.test.js +1 -1
- package/dist/services/workflowDocumentFixtures.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowDocumentFixtures.test.js +4 -4
- package/dist/services/workflowExportMatrix.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowExportMatrix.test.js +1 -1
- package/dist/services/workflowExportSnapshots.test.d.ts +1 -0
- package/dist/services/workflowGeneration.test.d.ts +1 -0
- package/dist/services/workflowSimulation.test.d.ts +1 -0
- package/dist/services/workflowSimulation.test.js +113 -0
- package/dist/services/workflowV2Policy.test.d.ts +1 -0
- package/dist/{__tests__ → services}/workflowV2Policy.test.js +2 -2
- package/dist/shared/aiProfileSurfaceType.d.ts +9 -0
- package/dist/shared/aiProfileSurfaceType.js +49 -0
- package/dist/shared/customTaxonomyLibrary.d.ts +11 -0
- package/dist/shared/customTaxonomyLibrary.js +276 -0
- package/dist/shared/customTaxonomyLibrary.test.d.ts +1 -0
- package/dist/shared/customTaxonomyLibrary.test.js +20 -0
- package/dist/shared/taxonomyCatalog.d.ts +19 -0
- package/dist/shared/taxonomyCatalog.js +36 -0
- package/dist/shared/taxonomyDefaults.d.ts +29 -0
- package/dist/shared/taxonomyDefaults.js +26 -0
- package/dist/shared/taxonomyLibrary.d.ts +15 -0
- package/dist/shared/taxonomyLibrary.js +98 -0
- package/dist/shared/taxonomyLibrary.test.d.ts +1 -0
- package/dist/shared/taxonomyLibrary.test.js +26 -0
- package/dist/shared/taxonomyState.d.ts +36 -0
- package/dist/shared/taxonomyState.js +73 -0
- package/dist/shared/taxonomyState.test.d.ts +1 -0
- package/dist/shared/taxonomyState.test.js +71 -0
- package/dist/shared/workflowDefaults.d.ts +9 -0
- package/dist/shared/workflowDefaults.js +11 -0
- package/dist/storage/documentIntegrity.d.ts +2 -0
- package/dist/storage/documentIntegrity.js +34 -17
- package/dist/storage/documentPurge.d.ts +2 -1
- package/dist/storage/documentPurge.js +35 -8
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/objectStorage.d.ts +1 -1
- package/dist/storage/objectStorageClient.d.ts +6 -4
- package/dist/storage/objectStorageClient.js +77 -29
- package/dist/storage/objectStorageClient.test.d.ts +1 -0
- package/dist/storage/objectStorageClient.test.js +57 -0
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.d.ts +1 -0
- package/dist/storage/objectStorageConfig.test.js +38 -0
- package/dist/storage/postgresAdapter.d.ts +5 -0
- package/dist/storage/postgresAdapter.js +2 -2
- package/dist/storage/postgresAdapter.test.d.ts +1 -0
- package/dist/storage/postgresAdapter.test.js +29 -0
- package/dist/storage/taskAssetStore.d.ts +7 -4
- package/dist/storage/taskAssetStore.js +65 -60
- package/dist/storage/workspaceAssetStore.d.ts +122 -0
- package/dist/storage/workspaceAssetStore.js +496 -0
- package/dist/storage/workspaceAssetStore.test.d.ts +1 -0
- package/dist/storage/workspaceAssetStore.test.js +501 -0
- package/dist/sync/cloudSyncApi.d.ts +33 -2
- package/dist/sync/cloudSyncApi.js +37 -15
- package/dist/sync/cloudSyncApi.test.js +60 -3
- package/dist/sync/index.d.ts +2 -0
- package/dist/sync/index.js +3 -0
- package/dist/sync/syncService.d.ts +25 -0
- package/dist/sync/syncService.js +184 -16
- package/dist/sync/syncService.test.js +289 -25
- package/dist/sync/workspaceRepair.d.ts +114 -0
- package/dist/sync/workspaceRepair.js +566 -0
- package/dist/sync/workspaceSyncModel.d.ts +230 -2
- package/dist/sync/workspaceSyncModel.js +456 -17
- package/dist/sync/workspaceSyncModel.test.js +642 -0
- package/dist/sync/workspaceSyncState.d.ts +12 -0
- package/dist/sync/workspaceSyncState.js +12 -0
- package/dist/sync/workspaceSyncSurface.d.ts +33 -0
- package/dist/sync/workspaceSyncSurface.js +74 -0
- package/dist/types.d.ts +143 -18
- package/dist/types.js +9 -24
- package/dist/ui/assets/AgentsModule-TVmCgizS.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CAyhnPeR.js +3 -0
- package/dist/ui/assets/DocumentWorkspace-BOCw5e4D.js +250 -0
- package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +1 -0
- package/dist/ui/assets/InitiativesModule-CN0r02Oi.js +1 -0
- package/dist/ui/assets/PlansPage-BlVC_lRq.css +1 -0
- package/dist/ui/assets/PlansPage-FcQSNLZd.js +1 -0
- package/dist/ui/assets/TaskSettings-BwB9NtmJ.css +1 -0
- package/dist/ui/assets/TaskSettings-Cw5zYD1L.js +8 -0
- package/dist/ui/assets/WorkflowsModule-CY9R2zPB.js +5 -0
- package/dist/ui/assets/index-Bzqy5QGm.js +6 -0
- package/dist/ui/assets/index-DxRiI3tY.css +1 -0
- package/dist/ui/assets/vendor-dnd-DRzYolkg.js +5 -0
- package/dist/ui/assets/{vendor-icons-ZFG3SGwo.js → vendor-icons-QZyhEwgT.js} +1 -1
- package/dist/ui/assets/{vendor-markdown-CKYkQHfj.js → vendor-markdown-BUxTU7dS.js} +1 -1
- package/dist/ui/assets/vendor-react-CKJs5o3c.js +61 -0
- package/dist/ui/assets/vendor-router-BbWMxlnO.js +3 -0
- package/dist/ui/branding/logos/logo.png +0 -0
- package/dist/ui/branding/logos/logo_dark.svg +27 -0
- package/dist/ui/branding/logos/logo_favicon.svg +35 -0
- package/dist/ui/branding/logos/logo_light.svg +27 -0
- package/dist/ui/favicon/apple-touch-icon.png +0 -0
- package/dist/ui/favicon/archive/phoenix/apple-touch-icon.png +0 -0
- package/dist/ui/favicon/archive/phoenix/favicon.ico +0 -0
- package/dist/ui/favicon/archive/phoenix/site.webmanifest +1 -0
- package/dist/ui/favicon/favicon-96x96.png +0 -0
- package/dist/ui/favicon/favicon.ico +0 -0
- package/dist/ui/favicon/favicon.svg +17 -0
- package/dist/ui/favicon/site.webmanifest +21 -1
- package/dist/ui/favicon/web-app-manifest-192x192.png +0 -0
- package/dist/ui/favicon/web-app-manifest-512x512.png +0 -0
- package/dist/ui/index.html +10 -7
- package/dist/ui/product/screen_01.png +0 -0
- package/dist/ui/product/screen_02.png +0 -0
- package/dist/ui/product/screen_03.png +0 -0
- package/dist/utils/annotatedAttachments.d.ts +20 -0
- package/dist/utils/annotatedAttachments.js +74 -0
- package/dist/utils/annotatedAttachments.test.d.ts +1 -0
- package/dist/utils/annotatedAttachments.test.js +108 -0
- package/dist/utils/assignees.d.ts +26 -0
- package/dist/utils/assignees.js +132 -0
- package/dist/utils/canonicalAssetKind.d.ts +16 -0
- package/dist/utils/canonicalAssetKind.js +39 -0
- package/dist/utils/canonicalAssetKind.test.d.ts +1 -0
- package/dist/utils/canonicalAssetKind.test.js +24 -0
- package/dist/utils/coalescedRefresh.d.ts +5 -0
- package/dist/utils/coalescedRefresh.js +16 -0
- package/dist/utils/coalescedRefresh.test.d.ts +1 -0
- package/dist/utils/coalescedRefresh.test.js +30 -0
- package/dist/utils/constants.d.ts +16 -3
- package/dist/utils/constants.icons.test.js +2 -1
- package/dist/utils/constants.js +70 -13
- package/dist/utils/contextAssetEvents.d.ts +7 -0
- package/dist/utils/contextAssetEvents.js +6 -0
- package/dist/utils/contextFiles.d.ts +14 -3
- package/dist/utils/contextFiles.js +40 -8
- package/dist/utils/documentManagerApi.d.ts +6 -0
- package/dist/utils/documentManagerApi.js +19 -0
- package/dist/utils/documentNames.d.ts +24 -0
- package/dist/utils/documentNames.js +91 -0
- package/dist/utils/documentReferences.d.ts +9 -0
- package/dist/utils/documentReferences.js +11 -0
- package/dist/utils/entityReferences.d.ts +9 -0
- package/dist/utils/entityReferences.js +32 -0
- package/dist/utils/imageReferences.d.ts +9 -0
- package/dist/utils/imageReferences.js +11 -0
- package/dist/utils/planParser.d.ts +2 -2
- package/dist/utils/planParser.js +11 -11
- package/dist/utils/planParser.test.d.ts +1 -0
- package/dist/{__tests__ → utils}/planParser.test.js +22 -22
- package/dist/utils/planningReferences.d.ts +17 -0
- package/dist/utils/planningReferences.js +30 -0
- package/dist/utils/planningReferences.test.d.ts +1 -0
- package/dist/utils/planningReferences.test.js +17 -0
- package/dist/utils/taskActivity.d.ts +9 -0
- package/dist/utils/taskActivity.js +147 -0
- package/dist/utils/taskActivity.test.d.ts +1 -0
- package/dist/utils/taskActivity.test.js +34 -0
- package/dist/utils/taskDraftDefaults.d.ts +21 -0
- package/dist/utils/taskDraftDefaults.js +40 -0
- package/dist/utils/taskDraftDefaults.test.d.ts +1 -0
- package/dist/utils/taskDraftDefaults.test.js +34 -0
- package/dist/utils/taskNormalization.d.ts +25 -0
- package/dist/utils/taskNormalization.js +161 -0
- package/dist/utils/taskNormalization.test.d.ts +1 -0
- package/dist/utils/taskNormalization.test.js +158 -0
- package/dist/utils/taskReferences.d.ts +5 -0
- package/dist/utils/taskReferences.js +11 -0
- package/dist/utils/taskforceApiClient.d.ts +2 -0
- package/dist/utils/taskforceApiClient.js +101 -3
- package/dist/utils/taskforceApiClient.test.d.ts +1 -0
- package/dist/utils/taskforceApiClient.test.js +44 -0
- package/dist/utils/taxonomyFilterOptions.d.ts +2 -0
- package/dist/utils/taxonomyFilterOptions.js +17 -0
- package/dist/utils/taxonomyFormDefaults.d.ts +3 -0
- package/dist/utils/taxonomyFormDefaults.js +28 -0
- package/dist/utils/taxonomyFormDefaults.test.d.ts +1 -0
- package/dist/utils/taxonomyFormDefaults.test.js +63 -0
- package/dist/utils/taxonomyLifecycle.d.ts +3 -0
- package/dist/utils/taxonomyLifecycle.js +17 -0
- package/dist/utils/taxonomySorting.d.ts +7 -0
- package/dist/utils/taxonomySorting.js +74 -0
- package/dist/utils/theme.d.ts +15 -0
- package/dist/utils/theme.js +23 -0
- package/dist/utils/uiNotice.d.ts +7 -0
- package/dist/utils/uiNotice.js +6 -0
- package/dist/utils/uiNotice.test.d.ts +1 -0
- package/dist/utils/uiNotice.test.js +18 -0
- package/dist/utils/workspaceIdentity.d.ts +14 -0
- package/dist/utils/workspaceIdentity.js +21 -0
- package/dist/utils/workspaceIdentity.test.js +30 -1
- package/dist/utils/workspaceSyncPresentation.d.ts +20 -0
- package/dist/utils/workspaceSyncPresentation.js +21 -0
- package/dist/utils/workspaceSyncPresentation.test.d.ts +1 -0
- package/dist/utils/workspaceSyncPresentation.test.js +36 -0
- package/package.json +28 -23
- package/scripts/bootstrap-playwright-auth.mjs +155 -0
- package/scripts/check-compat-boundaries.mjs +41 -0
- package/scripts/check-env.ts +9 -2
- package/scripts/debug-login.mjs +32 -0
- package/scripts/migrate-planning-model.ts +233 -0
- package/scripts/migrate-task-data-assets.mjs +408 -0
- package/scripts/playwright-auth.sh +11 -0
- package/scripts/run-dev-proxy.sh +2 -0
- package/scripts/update-homebrew-formula.sh +20 -3
- package/scripts/with-esbuild.sh +11 -0
- package/src/resources/templates/WORKFLOW_V2_POLICY.md +1 -1
- package/src/resources/templates/workflow-sources/workflowDocs.mjs +62 -52
- package/src/resources/templates/workflows/collaborate.yaml +11 -5
- package/src/resources/templates/workflows/do.yaml +8 -2
- package/src/resources/templates/workflows/evaluate.yaml +13 -7
- package/src/resources/templates/workflows/execute.yaml +40 -23
- package/src/resources/templates/workflows/plan.yaml +15 -8
- package/src/resources/templates/workflows/review.yaml +14 -8
- package/dist/TaskforceScreenshot.d.ts +0 -11
- package/dist/TaskforceScreenshot.js +0 -113
- package/dist/compat/priorityCompat.d.ts +0 -2
- package/dist/compat/priorityCompat.js +0 -24
- package/dist/components/features/settings/TaxonomyManager 2.d.ts +0 -52
- package/dist/components/features/settings/TaxonomyManager 2.js +0 -75
- package/dist/components/task/TaskKanban 2.d.ts +0 -76
- package/dist/components/task/TaskKanban 2.js +0 -1004
- package/dist/components/task/TaskScreenshotSection.d.ts +0 -15
- package/dist/components/task/TaskScreenshotSection.js +0 -22
- package/dist/components/views/StandaloneLayout 2.d.ts +0 -8
- package/dist/components/views/StandaloneLayout 2.js +0 -1660
- package/dist/core/InitiativeTemplates.test.js +0 -50
- package/dist/core/ParentLifecycle.test.js +0 -98
- package/dist/migrations/clientMigrations.d.ts +0 -9
- package/dist/migrations/clientMigrations.js +0 -74
- package/dist/migrations/flags.d.ts +0 -6
- package/dist/migrations/flags.js +0 -8
- package/dist/migrations/taskMigrations.d.ts +0 -71
- package/dist/migrations/taskMigrations.js +0 -236
- package/dist/migrations/taskMigrations.test.js +0 -34
- package/dist/server/routes.billing.js +0 -991
- package/dist/server/routes.billing.test.js +0 -387
- package/dist/server/routes.sync.integration.test.js +0 -470
- package/dist/server/routes.sync.js +0 -1141
- package/dist/soak/syncSoakHarness.d.ts +0 -6
- package/dist/soak/syncSoakHarness.js +0 -10
- package/dist/ui/assets/index-0W5vyCpn.css +0 -1
- package/dist/ui/assets/index-MCZuNNfn.js +0 -23
- package/dist/ui/assets/logo_white_01-0Vx-iIIv.png +0 -0
- package/dist/ui/assets/vendor-dnd-BI1K77C1.js +0 -5
- package/dist/ui/assets/vendor-react-DdIDsh7f.js +0 -9
- package/dist/ui/assets/vendor-router-BtiNU7Dl.js +0 -3
- package/dist/utils/taskHierarchy.d.ts +0 -4
- package/dist/utils/taskHierarchy.js +0 -69
- package/dist/utils/taskHierarchy.test.js +0 -38
- package/dist/utils/taskParenting.d.ts +0 -3
- package/dist/utils/taskParenting.js +0 -24
- package/dist/utils/taskParenting.test.js +0 -21
- package/dist/utils/taskRelations.d.ts +0 -6
- package/dist/utils/taskRelations.js +0 -24
- package/dist/utils/taskRelations.test.js +0 -34
- package/scripts/check-compat-boundaries.js +0 -48
- /package/dist/{__tests__/planParser.test.d.ts → TaskforceCore.filter-persistence.test.d.ts} +0 -0
- /package/dist/{__tests__/releaseVersion.test.d.ts → TaskforceCore.routing.test.d.ts} +0 -0
- /package/dist/{__tests__/structuredCommentValidation.test.d.ts → annotatedAttachments/AnnotatedAttachmentSessionStore.test.d.ts} +0 -0
- /package/dist/{__tests__/structuredDocValidation.test.d.ts → annotatedAttachments/payload.test.d.ts} +0 -0
- /package/dist/{__tests__/templateEngine.test.d.ts → annotatedAttachments/types.js} +0 -0
- /package/dist/{__tests__/templates.test.d.ts → compat/workspaceSyncCompat.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowDocumentFixtures.test.d.ts → components/features/AgentsModule.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowExportMatrix.test.d.ts → components/features/AnnotatedAttachmentWorkspace.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowExportSnapshots.test.d.ts → components/features/DocumentWorkspace.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowGeneration.test.d.ts → components/features/settings/TaxonomyLibraryManager.test.d.ts} +0 -0
- /package/dist/{__tests__/workflowV2Policy.test.d.ts → components/task/TaskActionHeader.test.d.ts} +0 -0
- /package/dist/{core/InitiativeTemplates.test.d.ts → components/task/TaskKanban.planning-drop.test.d.ts} +0 -0
- /package/dist/{core/ParentLifecycle.test.d.ts → components/task/TaskStatusActions.test.d.ts} +0 -0
- /package/dist/{migrations/taskMigrations.test.d.ts → components/ui/TopNoticeLayer.test.d.ts} +0 -0
- /package/dist/{server/routes.billing.test.d.ts → components/views/AppShellHeader.test.d.ts} +0 -0
- /package/dist/{server/routes.sync.integration.test.d.ts → components/views/PlanComparisonPage.test.d.ts} +0 -0
- /package/dist/{utils/taskHierarchy.test.d.ts → components/views/chrome/WorkspaceChromeSections.test.d.ts} +0 -0
- /package/dist/{utils/taskParenting.test.d.ts → components/views/chrome/workspaceChrome.test.d.ts} +0 -0
- /package/dist/{utils/taskRelations.test.d.ts → components/views/panels/DocumentFilterToolbar.test.d.ts} +0 -0
- /package/dist/public/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
- /package/dist/public/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
- /package/dist/public/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
- /package/dist/public/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
- /package/dist/public/{favicon.png → archive/phoenix/favicon.png} +0 -0
- /package/dist/{__tests__ → services}/workflowExportSnapshots.test.js +0 -0
- /package/dist/{__tests__ → services}/workflowGeneration.test.js +0 -0
- /package/dist/ui/favicon/{android-chrome-192x192.png → archive/phoenix/android-chrome-192x192.png} +0 -0
- /package/dist/ui/favicon/{android-chrome-512x512.png → archive/phoenix/android-chrome-512x512.png} +0 -0
- /package/dist/ui/favicon/{favicon-16x16.png → archive/phoenix/favicon-16x16.png} +0 -0
- /package/dist/ui/favicon/{favicon-32x32.png → archive/phoenix/favicon-32x32.png} +0 -0
- /package/dist/ui/favicon/{favicon.png → archive/phoenix/favicon.png} +0 -0
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
function hasTable(db, tableName) {
|
|
2
|
+
if (db.provider === 'postgres') {
|
|
3
|
+
const row = db.prepare(`
|
|
4
|
+
SELECT tablename AS name
|
|
5
|
+
FROM pg_catalog.pg_tables
|
|
6
|
+
WHERE schemaname = current_schema()
|
|
7
|
+
AND tablename = ?
|
|
8
|
+
LIMIT 1
|
|
9
|
+
`).get(tableName);
|
|
10
|
+
return Boolean(String(row?.name || '').trim());
|
|
11
|
+
}
|
|
12
|
+
const row = db.prepare(`
|
|
13
|
+
SELECT name
|
|
14
|
+
FROM sqlite_master
|
|
15
|
+
WHERE type = 'table' AND name = ?
|
|
16
|
+
LIMIT 1
|
|
17
|
+
`).get(tableName);
|
|
18
|
+
return Boolean(String(row?.name || '').trim());
|
|
19
|
+
}
|
|
1
20
|
export function ensureTenantSchema(db) {
|
|
2
21
|
const taskColumns = db.prepare(`PRAGMA table_info(tasks)`).all();
|
|
3
22
|
const hasTaskTenantColumn = taskColumns.some((c) => c.name === 'tenant_id');
|
|
@@ -9,16 +28,10 @@ export function ensureTenantSchema(db) {
|
|
|
9
28
|
if (!hasCommentTenantColumn) {
|
|
10
29
|
db.exec(`ALTER TABLE comments ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
11
30
|
}
|
|
12
|
-
const screenshotColumns = db.prepare(`PRAGMA table_info(screenshots)`).all();
|
|
13
|
-
const hasScreenshotTenantColumn = screenshotColumns.some((c) => c.name === 'tenant_id');
|
|
14
|
-
if (!hasScreenshotTenantColumn) {
|
|
15
|
-
db.exec(`ALTER TABLE screenshots ADD COLUMN tenant_id TEXT NOT NULL DEFAULT 'default'`);
|
|
16
|
-
}
|
|
17
31
|
db.exec(`
|
|
18
32
|
CREATE INDEX IF NOT EXISTS idx_tasks_tenant ON tasks(tenant_id);
|
|
19
33
|
CREATE INDEX IF NOT EXISTS idx_tasks_tenant_archived ON tasks(tenant_id, is_archived);
|
|
20
34
|
CREATE INDEX IF NOT EXISTS idx_comments_tenant_task ON comments(tenant_id, task_id);
|
|
21
|
-
CREATE INDEX IF NOT EXISTS idx_screenshots_tenant_task ON screenshots(tenant_id, task_id);
|
|
22
35
|
`);
|
|
23
36
|
}
|
|
24
37
|
export function ensureParentTaskSchema(db) {
|
|
@@ -106,6 +119,74 @@ export function ensureAssigneeTaskSchema(db) {
|
|
|
106
119
|
}
|
|
107
120
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee)`);
|
|
108
121
|
}
|
|
122
|
+
export function ensureTaskReferenceSchema(db) {
|
|
123
|
+
const columns = db.prepare(`PRAGMA table_info(tasks)`).all();
|
|
124
|
+
const hasReferenceNumberColumn = columns.some((c) => c.name === 'reference_number');
|
|
125
|
+
if (!hasReferenceNumberColumn) {
|
|
126
|
+
db.exec(`ALTER TABLE tasks ADD COLUMN reference_number INTEGER`);
|
|
127
|
+
}
|
|
128
|
+
db.exec(`
|
|
129
|
+
CREATE TABLE IF NOT EXISTS workspace_task_reference_sequences (
|
|
130
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
131
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
132
|
+
next_reference_number INTEGER NOT NULL DEFAULT 0,
|
|
133
|
+
PRIMARY KEY (tenant_id, workspace_id)
|
|
134
|
+
);
|
|
135
|
+
`);
|
|
136
|
+
const workspaceRows = db.prepare(`
|
|
137
|
+
SELECT DISTINCT
|
|
138
|
+
COALESCE(tenant_id, 'default') AS tenant_id,
|
|
139
|
+
COALESCE(workspace_id, 'default') AS workspace_id
|
|
140
|
+
FROM tasks
|
|
141
|
+
ORDER BY tenant_id ASC, workspace_id ASC
|
|
142
|
+
`).all();
|
|
143
|
+
const selectRows = db.prepare(`
|
|
144
|
+
SELECT id, reference_number, created_at
|
|
145
|
+
FROM tasks
|
|
146
|
+
WHERE tenant_id = ? AND workspace_id = ?
|
|
147
|
+
ORDER BY created_at ASC, id ASC
|
|
148
|
+
`);
|
|
149
|
+
const updateReference = db.prepare(`
|
|
150
|
+
UPDATE tasks
|
|
151
|
+
SET reference_number = ?
|
|
152
|
+
WHERE tenant_id = ? AND workspace_id = ? AND id = ?
|
|
153
|
+
`);
|
|
154
|
+
const upsertSequence = db.prepare(`
|
|
155
|
+
INSERT INTO workspace_task_reference_sequences (tenant_id, workspace_id, next_reference_number)
|
|
156
|
+
VALUES (?, ?, ?)
|
|
157
|
+
ON CONFLICT (tenant_id, workspace_id) DO UPDATE SET
|
|
158
|
+
next_reference_number = EXCLUDED.next_reference_number
|
|
159
|
+
`);
|
|
160
|
+
for (const workspaceRow of workspaceRows) {
|
|
161
|
+
const tenantId = String(workspaceRow.tenant_id || 'default').trim() || 'default';
|
|
162
|
+
const workspaceId = String(workspaceRow.workspace_id || 'default').trim() || 'default';
|
|
163
|
+
const taskRows = selectRows.all(tenantId, workspaceId);
|
|
164
|
+
const seen = new Set();
|
|
165
|
+
let nextReferenceNumber = 0;
|
|
166
|
+
for (const row of taskRows) {
|
|
167
|
+
const taskId = String(row.id || '').trim();
|
|
168
|
+
if (!taskId)
|
|
169
|
+
continue;
|
|
170
|
+
const rawReferenceNumber = Number(row.reference_number);
|
|
171
|
+
const currentReferenceNumber = Number.isFinite(rawReferenceNumber) && rawReferenceNumber > 0
|
|
172
|
+
? Math.floor(rawReferenceNumber)
|
|
173
|
+
: null;
|
|
174
|
+
if (currentReferenceNumber && !seen.has(currentReferenceNumber)) {
|
|
175
|
+
seen.add(currentReferenceNumber);
|
|
176
|
+
nextReferenceNumber = Math.max(nextReferenceNumber, currentReferenceNumber);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
nextReferenceNumber += 1;
|
|
180
|
+
seen.add(nextReferenceNumber);
|
|
181
|
+
updateReference.run(nextReferenceNumber, tenantId, workspaceId, taskId);
|
|
182
|
+
}
|
|
183
|
+
upsertSequence.run(tenantId, workspaceId, nextReferenceNumber);
|
|
184
|
+
}
|
|
185
|
+
db.exec(`
|
|
186
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_workspace_reference
|
|
187
|
+
ON tasks(tenant_id, workspace_id, reference_number);
|
|
188
|
+
`);
|
|
189
|
+
}
|
|
109
190
|
export function ensureWorkspaceSchema(db) {
|
|
110
191
|
db.exec(`
|
|
111
192
|
CREATE TABLE IF NOT EXISTS workspaces (
|
|
@@ -162,6 +243,29 @@ export function ensureWorkspaceSchema(db) {
|
|
|
162
243
|
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
163
244
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
164
245
|
);
|
|
246
|
+
|
|
247
|
+
CREATE TABLE IF NOT EXISTS mcp_access_tokens (
|
|
248
|
+
id TEXT PRIMARY KEY,
|
|
249
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
250
|
+
workspace_id TEXT NOT NULL,
|
|
251
|
+
user_id TEXT NOT NULL,
|
|
252
|
+
name TEXT NOT NULL,
|
|
253
|
+
scopes_json TEXT NOT NULL,
|
|
254
|
+
token_prefix TEXT NOT NULL,
|
|
255
|
+
token_hash TEXT NOT NULL,
|
|
256
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
257
|
+
last_used_at TEXT,
|
|
258
|
+
last_used_ip TEXT,
|
|
259
|
+
last_used_user_agent TEXT,
|
|
260
|
+
created_by_ip TEXT,
|
|
261
|
+
expires_at TEXT,
|
|
262
|
+
revoked_at TEXT,
|
|
263
|
+
revoked_by_user_id TEXT,
|
|
264
|
+
created_at TEXT NOT NULL,
|
|
265
|
+
updated_at TEXT NOT NULL,
|
|
266
|
+
FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
267
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
268
|
+
);
|
|
165
269
|
`);
|
|
166
270
|
const taskColumns = db.prepare(`PRAGMA table_info(tasks)`).all();
|
|
167
271
|
const hasTaskWorkspaceColumn = taskColumns.some((c) => c.name === 'workspace_id');
|
|
@@ -173,36 +277,75 @@ export function ensureWorkspaceSchema(db) {
|
|
|
173
277
|
if (!hasCommentWorkspaceColumn) {
|
|
174
278
|
db.exec(`ALTER TABLE comments ADD COLUMN workspace_id TEXT NOT NULL DEFAULT 'default'`);
|
|
175
279
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
280
|
+
if (db.provider === 'postgres') {
|
|
281
|
+
const postgresUserRepairs = [
|
|
282
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS display_name TEXT`,
|
|
283
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_url TEXT`,
|
|
284
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS auth_provider TEXT`,
|
|
285
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS external_auth_id TEXT`,
|
|
286
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS password_hash TEXT`,
|
|
287
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS email_verified_at TEXT`,
|
|
288
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS beta_access BOOLEAN NOT NULL DEFAULT TRUE`,
|
|
289
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS is_disabled BOOLEAN NOT NULL DEFAULT FALSE`,
|
|
290
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS updated_at TEXT`,
|
|
291
|
+
`ALTER TABLE users ADD COLUMN IF NOT EXISTS system_role TEXT NOT NULL DEFAULT 'user'`
|
|
292
|
+
];
|
|
293
|
+
for (const ddl of postgresUserRepairs) {
|
|
294
|
+
try {
|
|
295
|
+
db.exec(ddl);
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Best-effort repair for older deployments.
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const postgresMembershipRepairs = [
|
|
302
|
+
`ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS permission_mode TEXT NOT NULL DEFAULT 'read-write'`,
|
|
303
|
+
`ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS beta_access BOOLEAN NOT NULL DEFAULT TRUE`,
|
|
304
|
+
`ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'active'`,
|
|
305
|
+
`ALTER TABLE workspace_memberships ADD COLUMN IF NOT EXISTS updated_at TEXT`
|
|
306
|
+
];
|
|
307
|
+
for (const ddl of postgresMembershipRepairs) {
|
|
308
|
+
try {
|
|
309
|
+
db.exec(ddl);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Best-effort repair for older deployments.
|
|
313
|
+
}
|
|
314
|
+
}
|
|
193
315
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
316
|
+
else {
|
|
317
|
+
const userColumns = db.prepare(`PRAGMA table_info(users)`).all();
|
|
318
|
+
const existingUserColumns = new Set(userColumns.map((column) => String(column.name || '').trim()));
|
|
319
|
+
const sqliteUserRepairs = [
|
|
320
|
+
{ name: 'display_name', sql: `ALTER TABLE users ADD COLUMN display_name TEXT` },
|
|
321
|
+
{ name: 'avatar_url', sql: `ALTER TABLE users ADD COLUMN avatar_url TEXT` },
|
|
322
|
+
{ name: 'auth_provider', sql: `ALTER TABLE users ADD COLUMN auth_provider TEXT` },
|
|
323
|
+
{ name: 'external_auth_id', sql: `ALTER TABLE users ADD COLUMN external_auth_id TEXT` },
|
|
324
|
+
{ name: 'password_hash', sql: `ALTER TABLE users ADD COLUMN password_hash TEXT` },
|
|
325
|
+
{ name: 'email_verified_at', sql: `ALTER TABLE users ADD COLUMN email_verified_at TEXT` },
|
|
326
|
+
{ name: 'beta_access', sql: `ALTER TABLE users ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE` },
|
|
327
|
+
{ name: 'is_disabled', sql: `ALTER TABLE users ADD COLUMN is_disabled BOOLEAN NOT NULL DEFAULT FALSE` },
|
|
328
|
+
{ name: 'updated_at', sql: `ALTER TABLE users ADD COLUMN updated_at TEXT` },
|
|
329
|
+
{ name: 'system_role', sql: `ALTER TABLE users ADD COLUMN system_role TEXT NOT NULL DEFAULT 'user'` }
|
|
330
|
+
];
|
|
331
|
+
for (const column of sqliteUserRepairs) {
|
|
332
|
+
if (!existingUserColumns.has(column.name)) {
|
|
333
|
+
db.exec(column.sql);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const membershipColumns = db.prepare(`PRAGMA table_info(workspace_memberships)`).all();
|
|
337
|
+
const existingMembershipColumns = new Set(membershipColumns.map((column) => String(column.name || '').trim()));
|
|
338
|
+
const sqliteMembershipRepairs = [
|
|
339
|
+
{ name: 'permission_mode', sql: `ALTER TABLE workspace_memberships ADD COLUMN permission_mode TEXT NOT NULL DEFAULT 'read-write'` },
|
|
340
|
+
{ name: 'beta_access', sql: `ALTER TABLE workspace_memberships ADD COLUMN beta_access BOOLEAN NOT NULL DEFAULT TRUE` },
|
|
341
|
+
{ name: 'status', sql: `ALTER TABLE workspace_memberships ADD COLUMN status TEXT NOT NULL DEFAULT 'active'` },
|
|
342
|
+
{ name: 'updated_at', sql: `ALTER TABLE workspace_memberships ADD COLUMN updated_at TEXT` }
|
|
343
|
+
];
|
|
344
|
+
for (const column of sqliteMembershipRepairs) {
|
|
345
|
+
if (!existingMembershipColumns.has(column.name)) {
|
|
346
|
+
db.exec(column.sql);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
206
349
|
}
|
|
207
350
|
const authTokenColumns = db.prepare(`PRAGMA table_info(auth_tokens)`).all();
|
|
208
351
|
const hasRevokedAtColumn = authTokenColumns.some((c) => c.name === 'revoked_at');
|
|
@@ -213,6 +356,32 @@ export function ensureWorkspaceSchema(db) {
|
|
|
213
356
|
if (!hasWorkspaceIdColumn) {
|
|
214
357
|
db.exec(`ALTER TABLE auth_tokens ADD COLUMN workspace_id TEXT`);
|
|
215
358
|
}
|
|
359
|
+
const mcpTokenColumns = db.prepare(`PRAGMA table_info(mcp_access_tokens)`).all();
|
|
360
|
+
if (mcpTokenColumns.length > 0) {
|
|
361
|
+
const requiredColumns = [
|
|
362
|
+
{ name: 'workspace_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN workspace_id TEXT NOT NULL DEFAULT 'default'` },
|
|
363
|
+
{ name: 'user_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN user_id TEXT NOT NULL DEFAULT ''` },
|
|
364
|
+
{ name: 'name', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN name TEXT NOT NULL DEFAULT ''` },
|
|
365
|
+
{ name: 'scopes_json', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN scopes_json TEXT NOT NULL DEFAULT '[]'` },
|
|
366
|
+
{ name: 'token_prefix', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN token_prefix TEXT NOT NULL DEFAULT ''` },
|
|
367
|
+
{ name: 'token_hash', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN token_hash TEXT NOT NULL DEFAULT ''` },
|
|
368
|
+
{ name: 'status', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN status TEXT NOT NULL DEFAULT 'active'` },
|
|
369
|
+
{ name: 'last_used_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_at TEXT` },
|
|
370
|
+
{ name: 'last_used_ip', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_ip TEXT` },
|
|
371
|
+
{ name: 'last_used_user_agent', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN last_used_user_agent TEXT` },
|
|
372
|
+
{ name: 'created_by_ip', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN created_by_ip TEXT` },
|
|
373
|
+
{ name: 'expires_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN expires_at TEXT` },
|
|
374
|
+
{ name: 'revoked_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN revoked_at TEXT` },
|
|
375
|
+
{ name: 'revoked_by_user_id', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN revoked_by_user_id TEXT` },
|
|
376
|
+
{ name: 'created_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN created_at TEXT NOT NULL DEFAULT ''` },
|
|
377
|
+
{ name: 'updated_at', sql: `ALTER TABLE mcp_access_tokens ADD COLUMN updated_at TEXT NOT NULL DEFAULT ''` },
|
|
378
|
+
];
|
|
379
|
+
for (const column of requiredColumns) {
|
|
380
|
+
if (!mcpTokenColumns.some((c) => c.name === column.name)) {
|
|
381
|
+
db.exec(column.sql);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
216
385
|
db.exec(`
|
|
217
386
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspaces_tenant_slug ON workspaces(tenant_id, slug);
|
|
218
387
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_tenant_email ON users(tenant_id, email);
|
|
@@ -223,12 +392,15 @@ export function ensureWorkspaceSchema(db) {
|
|
|
223
392
|
CREATE INDEX IF NOT EXISTS idx_tasks_workspace ON tasks(workspace_id);
|
|
224
393
|
CREATE INDEX IF NOT EXISTS idx_tasks_tenant_workspace_archived ON tasks(tenant_id, workspace_id, is_archived);
|
|
225
394
|
CREATE INDEX IF NOT EXISTS idx_comments_workspace_task ON comments(workspace_id, task_id);
|
|
226
|
-
CREATE INDEX IF NOT EXISTS idx_screenshots_workspace_task ON screenshots(workspace_id, task_id);
|
|
227
395
|
CREATE INDEX IF NOT EXISTS idx_workspace_memberships_user ON workspace_memberships(user_id);
|
|
228
396
|
CREATE INDEX IF NOT EXISTS idx_workspace_memberships_workspace ON workspace_memberships(workspace_id);
|
|
229
397
|
CREATE INDEX IF NOT EXISTS idx_auth_tokens_user_purpose ON auth_tokens(user_id, purpose);
|
|
230
398
|
CREATE INDEX IF NOT EXISTS idx_auth_tokens_workspace_purpose ON auth_tokens(workspace_id, purpose);
|
|
231
399
|
CREATE INDEX IF NOT EXISTS idx_auth_tokens_expires ON auth_tokens(expires_at);
|
|
400
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_mcp_access_tokens_prefix ON mcp_access_tokens(token_prefix);
|
|
401
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_workspace_user ON mcp_access_tokens(workspace_id, user_id);
|
|
402
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_status ON mcp_access_tokens(status);
|
|
403
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_access_tokens_expires ON mcp_access_tokens(expires_at);
|
|
232
404
|
`);
|
|
233
405
|
}
|
|
234
406
|
export function ensureBillingSchema(db) {
|
|
@@ -240,9 +412,9 @@ export function ensureBillingSchema(db) {
|
|
|
240
412
|
stripe_subscription_id TEXT,
|
|
241
413
|
stripe_price_id TEXT,
|
|
242
414
|
stripe_status TEXT,
|
|
243
|
-
tier TEXT NOT NULL DEFAULT '
|
|
415
|
+
tier TEXT NOT NULL DEFAULT '',
|
|
244
416
|
billing_interval TEXT,
|
|
245
|
-
entitlement_state TEXT NOT NULL DEFAULT '
|
|
417
|
+
entitlement_state TEXT NOT NULL DEFAULT 'active',
|
|
246
418
|
trial_end TEXT,
|
|
247
419
|
current_period_end TEXT,
|
|
248
420
|
effective_until TEXT,
|
|
@@ -281,10 +453,13 @@ export function ensureBillingSchema(db) {
|
|
|
281
453
|
plan_version_id TEXT NOT NULL,
|
|
282
454
|
billing_interval TEXT NOT NULL,
|
|
283
455
|
stripe_price_id TEXT NOT NULL,
|
|
456
|
+
pricing_type TEXT NOT NULL DEFAULT 'stripe',
|
|
284
457
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
458
|
+
unit_amount INTEGER,
|
|
459
|
+
currency TEXT,
|
|
285
460
|
created_at TEXT NOT NULL,
|
|
286
461
|
updated_at TEXT NOT NULL,
|
|
287
|
-
PRIMARY KEY (tenant_id, stripe_price_id)
|
|
462
|
+
PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id)
|
|
288
463
|
);
|
|
289
464
|
|
|
290
465
|
CREATE INDEX IF NOT EXISTS idx_user_billing_tenant ON user_billing(tenant_id);
|
|
@@ -296,6 +471,159 @@ export function ensureBillingSchema(db) {
|
|
|
296
471
|
CREATE INDEX IF NOT EXISTS idx_billing_price_mappings_plan ON billing_price_mappings(tenant_id, plan_version_id);
|
|
297
472
|
CREATE INDEX IF NOT EXISTS idx_billing_price_mappings_active ON billing_price_mappings(tenant_id, active);
|
|
298
473
|
`);
|
|
474
|
+
const columns = db.prepare(`PRAGMA table_info(billing_price_mappings)`).all();
|
|
475
|
+
const hasUnitAmountColumn = columns.some((c) => c.name === 'unit_amount');
|
|
476
|
+
const hasCurrencyColumn = columns.some((c) => c.name === 'currency');
|
|
477
|
+
const hasPricingTypeColumn = columns.some((c) => c.name === 'pricing_type');
|
|
478
|
+
if (!hasUnitAmountColumn) {
|
|
479
|
+
db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN unit_amount INTEGER`);
|
|
480
|
+
}
|
|
481
|
+
if (!hasCurrencyColumn) {
|
|
482
|
+
db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN currency TEXT`);
|
|
483
|
+
}
|
|
484
|
+
if (!hasPricingTypeColumn) {
|
|
485
|
+
db.exec(`ALTER TABLE billing_price_mappings ADD COLUMN pricing_type TEXT NOT NULL DEFAULT 'stripe'`);
|
|
486
|
+
}
|
|
487
|
+
ensureBillingPriceMappingsConstraints(db);
|
|
488
|
+
normalizeUserBillingDefaults(db);
|
|
489
|
+
}
|
|
490
|
+
function ensureBillingPriceMappingsConstraints(db) {
|
|
491
|
+
if (db.provider === 'postgres') {
|
|
492
|
+
db.exec(`
|
|
493
|
+
ALTER TABLE billing_price_mappings DROP CONSTRAINT IF EXISTS billing_price_mappings_pkey;
|
|
494
|
+
ALTER TABLE billing_price_mappings
|
|
495
|
+
ADD CONSTRAINT billing_price_mappings_pkey
|
|
496
|
+
PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id);
|
|
497
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_billing_price_mappings_active_interval
|
|
498
|
+
ON billing_price_mappings(tenant_id, plan_version_id, billing_interval)
|
|
499
|
+
WHERE active = TRUE;
|
|
500
|
+
`);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
const indexes = db.prepare(`PRAGMA index_list(billing_price_mappings)`).all();
|
|
504
|
+
const tableInfo = db.prepare(`PRAGMA table_info(billing_price_mappings)`).all();
|
|
505
|
+
const hasActiveIntervalIndex = indexes.some((index) => index.name === 'idx_billing_price_mappings_active_interval');
|
|
506
|
+
const primaryKeyColumns = tableInfo
|
|
507
|
+
.filter((column) => Number(column.pk || 0) > 0)
|
|
508
|
+
.sort((a, b) => Number(a.pk || 0) - Number(b.pk || 0))
|
|
509
|
+
.map((column) => String(column.name || ''));
|
|
510
|
+
const needsPrimaryKeyRepair = primaryKeyColumns.join('|') !== 'tenant_id|plan_version_id|billing_interval|stripe_price_id';
|
|
511
|
+
if (needsPrimaryKeyRepair) {
|
|
512
|
+
db.exec(`
|
|
513
|
+
ALTER TABLE billing_price_mappings RENAME TO billing_price_mappings_legacy;
|
|
514
|
+
|
|
515
|
+
CREATE TABLE billing_price_mappings (
|
|
516
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
517
|
+
plan_version_id TEXT NOT NULL,
|
|
518
|
+
billing_interval TEXT NOT NULL,
|
|
519
|
+
stripe_price_id TEXT NOT NULL,
|
|
520
|
+
pricing_type TEXT NOT NULL DEFAULT 'stripe',
|
|
521
|
+
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
522
|
+
unit_amount INTEGER,
|
|
523
|
+
currency TEXT,
|
|
524
|
+
created_at TEXT NOT NULL,
|
|
525
|
+
updated_at TEXT NOT NULL,
|
|
526
|
+
PRIMARY KEY (tenant_id, plan_version_id, billing_interval, stripe_price_id)
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
INSERT INTO billing_price_mappings (
|
|
530
|
+
tenant_id, plan_version_id, billing_interval, stripe_price_id, pricing_type, active, unit_amount, currency, created_at, updated_at
|
|
531
|
+
)
|
|
532
|
+
SELECT
|
|
533
|
+
tenant_id, plan_version_id, billing_interval, stripe_price_id, COALESCE(pricing_type, 'stripe'), active, unit_amount, currency, created_at, updated_at
|
|
534
|
+
FROM billing_price_mappings_legacy;
|
|
535
|
+
|
|
536
|
+
DROP TABLE billing_price_mappings_legacy;
|
|
537
|
+
`);
|
|
538
|
+
}
|
|
539
|
+
if (!hasActiveIntervalIndex) {
|
|
540
|
+
db.exec(`
|
|
541
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_billing_price_mappings_active_interval
|
|
542
|
+
ON billing_price_mappings(tenant_id, plan_version_id, billing_interval)
|
|
543
|
+
WHERE active = 1;
|
|
544
|
+
`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function normalizeUserBillingDefaults(db) {
|
|
548
|
+
if (db.provider === 'postgres') {
|
|
549
|
+
db.exec(`
|
|
550
|
+
ALTER TABLE user_billing ALTER COLUMN tier SET DEFAULT '';
|
|
551
|
+
ALTER TABLE user_billing ALTER COLUMN entitlement_state SET DEFAULT 'active';
|
|
552
|
+
`);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
const columns = db.prepare(`PRAGMA table_info(user_billing)`).all();
|
|
556
|
+
const tierColumn = columns.find((column) => column.name === 'tier');
|
|
557
|
+
const stateColumn = columns.find((column) => column.name === 'entitlement_state');
|
|
558
|
+
const tierDefault = String(tierColumn?.dflt_value ?? '').trim();
|
|
559
|
+
const stateDefault = String(stateColumn?.dflt_value ?? '').trim().toLowerCase();
|
|
560
|
+
const tierNeedsRepair = tierDefault !== "''";
|
|
561
|
+
const stateNeedsRepair = stateDefault !== "'active'";
|
|
562
|
+
if (!tierNeedsRepair && !stateNeedsRepair) {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
const tx = db.transaction(() => {
|
|
566
|
+
db.exec(`
|
|
567
|
+
ALTER TABLE user_billing RENAME TO user_billing_legacy;
|
|
568
|
+
|
|
569
|
+
CREATE TABLE user_billing (
|
|
570
|
+
user_id TEXT PRIMARY KEY,
|
|
571
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
572
|
+
stripe_customer_id TEXT UNIQUE,
|
|
573
|
+
stripe_subscription_id TEXT,
|
|
574
|
+
stripe_price_id TEXT,
|
|
575
|
+
stripe_status TEXT,
|
|
576
|
+
tier TEXT NOT NULL DEFAULT '',
|
|
577
|
+
billing_interval TEXT,
|
|
578
|
+
entitlement_state TEXT NOT NULL DEFAULT 'active',
|
|
579
|
+
trial_end TEXT,
|
|
580
|
+
current_period_end TEXT,
|
|
581
|
+
effective_until TEXT,
|
|
582
|
+
created_at TEXT NOT NULL,
|
|
583
|
+
updated_at TEXT NOT NULL,
|
|
584
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
INSERT INTO user_billing (
|
|
588
|
+
user_id,
|
|
589
|
+
tenant_id,
|
|
590
|
+
stripe_customer_id,
|
|
591
|
+
stripe_subscription_id,
|
|
592
|
+
stripe_price_id,
|
|
593
|
+
stripe_status,
|
|
594
|
+
tier,
|
|
595
|
+
billing_interval,
|
|
596
|
+
entitlement_state,
|
|
597
|
+
trial_end,
|
|
598
|
+
current_period_end,
|
|
599
|
+
effective_until,
|
|
600
|
+
created_at,
|
|
601
|
+
updated_at
|
|
602
|
+
)
|
|
603
|
+
SELECT
|
|
604
|
+
user_id,
|
|
605
|
+
tenant_id,
|
|
606
|
+
stripe_customer_id,
|
|
607
|
+
stripe_subscription_id,
|
|
608
|
+
stripe_price_id,
|
|
609
|
+
stripe_status,
|
|
610
|
+
tier,
|
|
611
|
+
billing_interval,
|
|
612
|
+
entitlement_state,
|
|
613
|
+
trial_end,
|
|
614
|
+
current_period_end,
|
|
615
|
+
effective_until,
|
|
616
|
+
created_at,
|
|
617
|
+
updated_at
|
|
618
|
+
FROM user_billing_legacy;
|
|
619
|
+
|
|
620
|
+
DROP TABLE user_billing_legacy;
|
|
621
|
+
|
|
622
|
+
CREATE INDEX IF NOT EXISTS idx_user_billing_tenant ON user_billing(tenant_id);
|
|
623
|
+
CREATE INDEX IF NOT EXISTS idx_user_billing_customer ON user_billing(stripe_customer_id);
|
|
624
|
+
`);
|
|
625
|
+
});
|
|
626
|
+
tx();
|
|
299
627
|
}
|
|
300
628
|
export function ensureEntitlementsSchema(db) {
|
|
301
629
|
db.exec(`
|
|
@@ -416,6 +744,152 @@ export function ensureTaskAssetsSchema(db) {
|
|
|
416
744
|
db.exec(`ALTER TABLE task_assets ADD COLUMN quarantine_status TEXT NOT NULL DEFAULT 'none'`);
|
|
417
745
|
}
|
|
418
746
|
}
|
|
747
|
+
export function ensureWorkspaceAssetsSchema(db) {
|
|
748
|
+
db.exec(`
|
|
749
|
+
CREATE TABLE IF NOT EXISTS workspace_assets (
|
|
750
|
+
asset_id TEXT PRIMARY KEY,
|
|
751
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
752
|
+
workspace_id TEXT NOT NULL,
|
|
753
|
+
kind TEXT NOT NULL,
|
|
754
|
+
logical_name TEXT,
|
|
755
|
+
original_filename TEXT NOT NULL,
|
|
756
|
+
mime_type TEXT NOT NULL,
|
|
757
|
+
storage_provider TEXT NOT NULL,
|
|
758
|
+
storage_key TEXT NOT NULL,
|
|
759
|
+
content_sha256 TEXT NOT NULL,
|
|
760
|
+
size_bytes INTEGER NOT NULL,
|
|
761
|
+
document_id TEXT,
|
|
762
|
+
version INTEGER,
|
|
763
|
+
is_latest INTEGER NOT NULL DEFAULT 1,
|
|
764
|
+
scan_status TEXT NOT NULL DEFAULT 'clean',
|
|
765
|
+
scan_engine TEXT,
|
|
766
|
+
scan_details TEXT,
|
|
767
|
+
created_by_user_id TEXT,
|
|
768
|
+
created_at TEXT NOT NULL,
|
|
769
|
+
updated_at TEXT NOT NULL,
|
|
770
|
+
deleted_at TEXT,
|
|
771
|
+
purge_after TEXT
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_assets_workspace_deleted_updated
|
|
775
|
+
ON workspace_assets(tenant_id, workspace_id, deleted_at, updated_at);
|
|
776
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_assets_workspace_kind_updated
|
|
777
|
+
ON workspace_assets(tenant_id, workspace_id, kind, updated_at);
|
|
778
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_assets_document_version
|
|
779
|
+
ON workspace_assets(tenant_id, workspace_id, document_id, version);
|
|
780
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_assets_sha
|
|
781
|
+
ON workspace_assets(tenant_id, workspace_id, content_sha256);
|
|
782
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_assets_purge_after
|
|
783
|
+
ON workspace_assets(purge_after);
|
|
784
|
+
|
|
785
|
+
CREATE TABLE IF NOT EXISTS workspace_asset_links (
|
|
786
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
787
|
+
workspace_id TEXT NOT NULL,
|
|
788
|
+
asset_id TEXT NOT NULL,
|
|
789
|
+
task_id TEXT NOT NULL,
|
|
790
|
+
role TEXT NOT NULL,
|
|
791
|
+
display_name TEXT,
|
|
792
|
+
sort_order INTEGER,
|
|
793
|
+
created_at TEXT NOT NULL,
|
|
794
|
+
updated_at TEXT NOT NULL,
|
|
795
|
+
deleted_at TEXT,
|
|
796
|
+
PRIMARY KEY (tenant_id, workspace_id, asset_id, task_id, role)
|
|
797
|
+
);
|
|
798
|
+
|
|
799
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_asset_links_task
|
|
800
|
+
ON workspace_asset_links(tenant_id, workspace_id, task_id, deleted_at, updated_at);
|
|
801
|
+
CREATE INDEX IF NOT EXISTS idx_workspace_asset_links_asset
|
|
802
|
+
ON workspace_asset_links(tenant_id, workspace_id, asset_id, deleted_at, updated_at);
|
|
803
|
+
`);
|
|
804
|
+
const linkColumns = db.prepare(`PRAGMA table_info(workspace_asset_links)`).all();
|
|
805
|
+
const hasDisplayNameColumn = linkColumns.some((c) => c.name === 'display_name');
|
|
806
|
+
if (!hasDisplayNameColumn) {
|
|
807
|
+
db.exec(`ALTER TABLE workspace_asset_links ADD COLUMN display_name TEXT`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
export function ensureDocumentReferenceSchema(db) {
|
|
811
|
+
const columns = db.prepare(`PRAGMA table_info(workspace_assets)`).all();
|
|
812
|
+
const hasReferenceNumberColumn = columns.some((c) => c.name === 'reference_number');
|
|
813
|
+
if (!hasReferenceNumberColumn) {
|
|
814
|
+
db.exec(`ALTER TABLE workspace_assets ADD COLUMN reference_number INTEGER`);
|
|
815
|
+
}
|
|
816
|
+
// Drop the original cross-kind unique index before backfilling per-kind
|
|
817
|
+
// references. Otherwise existing D-### rows can block image backfills such
|
|
818
|
+
// as I-1 / I-2 while the old uniqueness rule is still active.
|
|
819
|
+
db.exec(`DROP INDEX IF EXISTS idx_workspace_assets_workspace_reference`);
|
|
820
|
+
db.exec(`
|
|
821
|
+
CREATE TABLE IF NOT EXISTS workspace_document_reference_sequences (
|
|
822
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
823
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
824
|
+
next_reference_number INTEGER NOT NULL DEFAULT 0,
|
|
825
|
+
PRIMARY KEY (tenant_id, workspace_id)
|
|
826
|
+
);
|
|
827
|
+
CREATE TABLE IF NOT EXISTS workspace_image_reference_sequences (
|
|
828
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
829
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
830
|
+
next_reference_number INTEGER NOT NULL DEFAULT 0,
|
|
831
|
+
PRIMARY KEY (tenant_id, workspace_id)
|
|
832
|
+
);
|
|
833
|
+
`);
|
|
834
|
+
const backfillKindReferences = (kind, sequenceTable) => {
|
|
835
|
+
const workspaceRows = db.prepare(`
|
|
836
|
+
SELECT DISTINCT
|
|
837
|
+
COALESCE(tenant_id, 'default') AS tenant_id,
|
|
838
|
+
COALESCE(workspace_id, 'default') AS workspace_id
|
|
839
|
+
FROM workspace_assets
|
|
840
|
+
WHERE kind = ?
|
|
841
|
+
ORDER BY tenant_id ASC, workspace_id ASC
|
|
842
|
+
`).all(kind);
|
|
843
|
+
const selectRows = db.prepare(`
|
|
844
|
+
SELECT asset_id, reference_number, created_at
|
|
845
|
+
FROM workspace_assets
|
|
846
|
+
WHERE tenant_id = ? AND workspace_id = ? AND kind = ?
|
|
847
|
+
ORDER BY created_at ASC, asset_id ASC
|
|
848
|
+
`);
|
|
849
|
+
const updateReference = db.prepare(`
|
|
850
|
+
UPDATE workspace_assets
|
|
851
|
+
SET reference_number = ?
|
|
852
|
+
WHERE tenant_id = ? AND workspace_id = ? AND asset_id = ?
|
|
853
|
+
`);
|
|
854
|
+
const upsertSequence = db.prepare(`
|
|
855
|
+
INSERT INTO ${sequenceTable} (tenant_id, workspace_id, next_reference_number)
|
|
856
|
+
VALUES (?, ?, ?)
|
|
857
|
+
ON CONFLICT (tenant_id, workspace_id) DO UPDATE SET
|
|
858
|
+
next_reference_number = EXCLUDED.next_reference_number
|
|
859
|
+
`);
|
|
860
|
+
for (const workspaceRow of workspaceRows) {
|
|
861
|
+
const tenantId = String(workspaceRow.tenant_id || 'default').trim() || 'default';
|
|
862
|
+
const workspaceId = String(workspaceRow.workspace_id || 'default').trim() || 'default';
|
|
863
|
+
const assetRows = selectRows.all(tenantId, workspaceId, kind);
|
|
864
|
+
const seen = new Set();
|
|
865
|
+
let nextReferenceNumber = 0;
|
|
866
|
+
for (const row of assetRows) {
|
|
867
|
+
const assetId = String(row.asset_id || '').trim();
|
|
868
|
+
if (!assetId)
|
|
869
|
+
continue;
|
|
870
|
+
const rawReferenceNumber = Number(row.reference_number);
|
|
871
|
+
const currentReferenceNumber = Number.isFinite(rawReferenceNumber) && rawReferenceNumber > 0
|
|
872
|
+
? Math.floor(rawReferenceNumber)
|
|
873
|
+
: null;
|
|
874
|
+
if (currentReferenceNumber && !seen.has(currentReferenceNumber)) {
|
|
875
|
+
seen.add(currentReferenceNumber);
|
|
876
|
+
nextReferenceNumber = Math.max(nextReferenceNumber, currentReferenceNumber);
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
nextReferenceNumber += 1;
|
|
880
|
+
seen.add(nextReferenceNumber);
|
|
881
|
+
updateReference.run(nextReferenceNumber, tenantId, workspaceId, assetId);
|
|
882
|
+
}
|
|
883
|
+
upsertSequence.run(tenantId, workspaceId, nextReferenceNumber);
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
backfillKindReferences('document', 'workspace_document_reference_sequences');
|
|
887
|
+
backfillKindReferences('image', 'workspace_image_reference_sequences');
|
|
888
|
+
db.exec(`
|
|
889
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_assets_workspace_kind_reference
|
|
890
|
+
ON workspace_assets(tenant_id, workspace_id, kind, reference_number);
|
|
891
|
+
`);
|
|
892
|
+
}
|
|
419
893
|
export function ensureSyncEventsSchema(db) {
|
|
420
894
|
const syncEventsIdColumnSql = db.provider === 'postgres'
|
|
421
895
|
? 'id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'
|
|
@@ -451,3 +925,171 @@ export function ensureWorkspaceDocumentsSchema(db) {
|
|
|
451
925
|
ON workspace_documents(tenant_id, workspace_id, path);
|
|
452
926
|
`);
|
|
453
927
|
}
|
|
928
|
+
export function ensureAnnotatedAttachmentSessionsSchema(db) {
|
|
929
|
+
db.exec(`
|
|
930
|
+
CREATE TABLE IF NOT EXISTS annotated_attachment_sessions (
|
|
931
|
+
id TEXT PRIMARY KEY,
|
|
932
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
933
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
934
|
+
task_id TEXT NOT NULL,
|
|
935
|
+
base_image_asset_id TEXT NOT NULL,
|
|
936
|
+
title TEXT,
|
|
937
|
+
global_instruction TEXT,
|
|
938
|
+
annotations_json TEXT NOT NULL DEFAULT '[]',
|
|
939
|
+
created_by_actor_id TEXT,
|
|
940
|
+
updated_by_actor_id TEXT,
|
|
941
|
+
created_at TEXT NOT NULL,
|
|
942
|
+
updated_at TEXT NOT NULL,
|
|
943
|
+
deleted_at TEXT
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
CREATE INDEX IF NOT EXISTS idx_annotated_attachment_sessions_task
|
|
947
|
+
ON annotated_attachment_sessions(tenant_id, workspace_id, task_id, deleted_at, updated_at);
|
|
948
|
+
CREATE INDEX IF NOT EXISTS idx_annotated_attachment_sessions_image
|
|
949
|
+
ON annotated_attachment_sessions(tenant_id, workspace_id, base_image_asset_id, deleted_at, updated_at);
|
|
950
|
+
`);
|
|
951
|
+
}
|
|
952
|
+
export function ensureDocumentReviewSessionsSchema(db) {
|
|
953
|
+
db.exec(`
|
|
954
|
+
CREATE TABLE IF NOT EXISTS document_review_sessions (
|
|
955
|
+
id TEXT PRIMARY KEY,
|
|
956
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
957
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
958
|
+
asset_id TEXT NOT NULL,
|
|
959
|
+
document_id TEXT,
|
|
960
|
+
document_version INTEGER,
|
|
961
|
+
title TEXT,
|
|
962
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
963
|
+
comments_json TEXT NOT NULL DEFAULT '[]',
|
|
964
|
+
created_by_actor_id TEXT,
|
|
965
|
+
updated_by_actor_id TEXT,
|
|
966
|
+
created_at TEXT NOT NULL,
|
|
967
|
+
updated_at TEXT NOT NULL,
|
|
968
|
+
deleted_at TEXT
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
CREATE INDEX IF NOT EXISTS idx_document_review_sessions_asset
|
|
972
|
+
ON document_review_sessions(tenant_id, workspace_id, asset_id, deleted_at, updated_at);
|
|
973
|
+
CREATE INDEX IF NOT EXISTS idx_document_review_sessions_workspace
|
|
974
|
+
ON document_review_sessions(tenant_id, workspace_id, updated_at, id);
|
|
975
|
+
|
|
976
|
+
CREATE TABLE IF NOT EXISTS document_review_comments (
|
|
977
|
+
id TEXT PRIMARY KEY,
|
|
978
|
+
session_id TEXT NOT NULL,
|
|
979
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
980
|
+
workspace_id TEXT NOT NULL DEFAULT 'default',
|
|
981
|
+
body TEXT NOT NULL,
|
|
982
|
+
anchor_json TEXT,
|
|
983
|
+
author_actor_id TEXT,
|
|
984
|
+
order_index INTEGER NOT NULL DEFAULT 0,
|
|
985
|
+
created_at TEXT NOT NULL,
|
|
986
|
+
updated_at TEXT NOT NULL,
|
|
987
|
+
deleted_at TEXT
|
|
988
|
+
);
|
|
989
|
+
|
|
990
|
+
CREATE INDEX IF NOT EXISTS idx_document_review_comments_session
|
|
991
|
+
ON document_review_comments(tenant_id, workspace_id, session_id, deleted_at, order_index, created_at, id);
|
|
992
|
+
CREATE INDEX IF NOT EXISTS idx_document_review_comments_workspace
|
|
993
|
+
ON document_review_comments(tenant_id, workspace_id, updated_at, id);
|
|
994
|
+
`);
|
|
995
|
+
const sessionRows = db.prepare(`
|
|
996
|
+
SELECT
|
|
997
|
+
id,
|
|
998
|
+
tenant_id,
|
|
999
|
+
workspace_id,
|
|
1000
|
+
comments_json
|
|
1001
|
+
FROM document_review_sessions
|
|
1002
|
+
WHERE comments_json IS NOT NULL
|
|
1003
|
+
AND TRIM(comments_json) <> ''
|
|
1004
|
+
AND comments_json <> '[]'
|
|
1005
|
+
`).all();
|
|
1006
|
+
const hasExistingComment = db.prepare(`
|
|
1007
|
+
SELECT id
|
|
1008
|
+
FROM document_review_comments
|
|
1009
|
+
WHERE tenant_id = ? AND workspace_id = ? AND session_id = ?
|
|
1010
|
+
LIMIT 1
|
|
1011
|
+
`);
|
|
1012
|
+
const insertComment = db.prepare(`
|
|
1013
|
+
INSERT INTO document_review_comments (
|
|
1014
|
+
id,
|
|
1015
|
+
session_id,
|
|
1016
|
+
tenant_id,
|
|
1017
|
+
workspace_id,
|
|
1018
|
+
body,
|
|
1019
|
+
anchor_json,
|
|
1020
|
+
author_actor_id,
|
|
1021
|
+
order_index,
|
|
1022
|
+
created_at,
|
|
1023
|
+
updated_at,
|
|
1024
|
+
deleted_at
|
|
1025
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1026
|
+
`);
|
|
1027
|
+
for (const row of sessionRows) {
|
|
1028
|
+
const sessionId = String(row.id || '').trim();
|
|
1029
|
+
const tenantId = String(row.tenant_id || 'default').trim() || 'default';
|
|
1030
|
+
const workspaceId = String(row.workspace_id || 'default').trim() || 'default';
|
|
1031
|
+
if (!sessionId)
|
|
1032
|
+
continue;
|
|
1033
|
+
const existing = hasExistingComment.get(tenantId, workspaceId, sessionId);
|
|
1034
|
+
if (existing?.id)
|
|
1035
|
+
continue;
|
|
1036
|
+
try {
|
|
1037
|
+
const parsed = JSON.parse(String(row.comments_json || '[]'));
|
|
1038
|
+
if (!Array.isArray(parsed))
|
|
1039
|
+
continue;
|
|
1040
|
+
for (let index = 0; index < parsed.length; index += 1) {
|
|
1041
|
+
const raw = parsed[index];
|
|
1042
|
+
if (!raw || typeof raw !== 'object')
|
|
1043
|
+
continue;
|
|
1044
|
+
const record = raw;
|
|
1045
|
+
const commentId = String(record.id || '').trim() || `${sessionId}-comment-${index + 1}`;
|
|
1046
|
+
const body = String(record.body || '').trim();
|
|
1047
|
+
if (!body)
|
|
1048
|
+
continue;
|
|
1049
|
+
const createdAt = String(record.createdAt || '').trim() || new Date().toISOString();
|
|
1050
|
+
const updatedAt = String(record.updatedAt || '').trim() || createdAt;
|
|
1051
|
+
const anchorJson = record.anchor && typeof record.anchor === 'object' ? JSON.stringify(record.anchor) : null;
|
|
1052
|
+
const rawOrder = Number(record.order);
|
|
1053
|
+
const orderIndex = Number.isFinite(rawOrder) ? Math.max(0, Math.floor(rawOrder)) : index;
|
|
1054
|
+
insertComment.run(commentId, sessionId, tenantId, workspaceId, body, anchorJson, String(record.authorActorId || '').trim() || null, orderIndex, createdAt, updatedAt, String(record.deletedAt || '').trim() || null);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
catch {
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
if (hasTable(db, 'workspace_memberships') && hasTable(db, 'users')) {
|
|
1062
|
+
const anonymousComments = db.prepare(`
|
|
1063
|
+
SELECT DISTINCT tenant_id, workspace_id
|
|
1064
|
+
FROM document_review_comments
|
|
1065
|
+
WHERE LOWER(COALESCE(author_actor_id, '')) = 'anonymous'
|
|
1066
|
+
`).all();
|
|
1067
|
+
const resolveFallbackActor = db.prepare(`
|
|
1068
|
+
SELECT m.user_id
|
|
1069
|
+
FROM workspace_memberships m
|
|
1070
|
+
JOIN users u
|
|
1071
|
+
ON u.tenant_id = m.tenant_id
|
|
1072
|
+
AND u.id = m.user_id
|
|
1073
|
+
WHERE m.tenant_id = ?
|
|
1074
|
+
AND m.workspace_id = ?
|
|
1075
|
+
AND LOWER(COALESCE(m.status, 'active')) = 'active'
|
|
1076
|
+
AND COALESCE(u.is_disabled, 0) = 0
|
|
1077
|
+
ORDER BY COALESCE(m.updated_at, m.created_at) DESC, u.created_at DESC, m.user_id ASC
|
|
1078
|
+
LIMIT 1
|
|
1079
|
+
`);
|
|
1080
|
+
const updateAnonymousComments = db.prepare(`
|
|
1081
|
+
UPDATE document_review_comments
|
|
1082
|
+
SET author_actor_id = ?
|
|
1083
|
+
WHERE tenant_id = ?
|
|
1084
|
+
AND workspace_id = ?
|
|
1085
|
+
AND LOWER(COALESCE(author_actor_id, '')) = 'anonymous'
|
|
1086
|
+
`);
|
|
1087
|
+
for (const row of anonymousComments) {
|
|
1088
|
+
const tenantId = String(row.tenant_id || 'default').trim() || 'default';
|
|
1089
|
+
const workspaceId = String(row.workspace_id || 'default').trim() || 'default';
|
|
1090
|
+
const fallbackActor = resolveFallbackActor.get(tenantId, workspaceId);
|
|
1091
|
+
const actorId = String(fallbackActor?.user_id || 'user').trim() || 'user';
|
|
1092
|
+
updateAnonymousComments.run(actorId, tenantId, workspaceId);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|