sea-dev 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/tasks/README.md +89 -0
- package/.cursor/rules/commits.mdc +31 -0
- package/.cursor/rules/general.mdc +84 -0
- package/.github/workflows/ci-cd.yml +141 -0
- package/CLAUDE.md +337 -0
- package/README.md +129 -0
- package/apps/api/.prettierignore +6 -0
- package/apps/api/.prettierrc.js +3 -0
- package/apps/api/dotenvx-safe.sh +11 -0
- package/apps/api/eslint.config.mjs +3 -0
- package/apps/api/package.json +58 -0
- package/apps/api/src/clients/posthog.ts +25 -0
- package/apps/api/src/dal/submission.ts +59 -0
- package/apps/api/src/errors.ts +55 -0
- package/apps/api/src/index.ts +21 -0
- package/apps/api/src/lib/channel.ts +28 -0
- package/apps/api/src/lib/config.ts +9 -0
- package/apps/api/src/lib/fmt.test.ts +9 -0
- package/apps/api/src/lib/fmt.ts +62 -0
- package/apps/api/src/lib/invariant.ts +23 -0
- package/apps/api/src/middleware/auth.ts +66 -0
- package/apps/api/src/routes/index.ts +20 -0
- package/apps/api/src/routes/v2/chat/handlers.ts +693 -0
- package/apps/api/src/routes/v2/chat/index.ts +257 -0
- package/apps/api/src/routes/v2/chat/schemas.ts +43 -0
- package/apps/api/src/routes/v2/deals/handlers.ts +64 -0
- package/apps/api/src/routes/v2/deals/index.ts +88 -0
- package/apps/api/src/routes/v2/deals/schemas.ts +38 -0
- package/apps/api/src/routes/v2/forms/handlers.ts +415 -0
- package/apps/api/src/routes/v2/forms/index.ts +382 -0
- package/apps/api/src/routes/v2/forms/schemas.ts +243 -0
- package/apps/api/src/routes/v2/index.ts +19 -0
- package/apps/api/src/routes/v2/pipelines/handlers.ts +261 -0
- package/apps/api/src/routes/v2/pipelines/index.ts +224 -0
- package/apps/api/src/routes/v2/pipelines/schemas.ts +173 -0
- package/apps/api/src/routes/v2/submissions/handlers.ts +555 -0
- package/apps/api/src/routes/v2/submissions/index.ts +366 -0
- package/apps/api/src/routes/v2/submissions/schemas.ts +233 -0
- package/apps/api/src/routes/v2/workflows/handlers.ts +81 -0
- package/apps/api/src/routes/v2/workflows/index.ts +88 -0
- package/apps/api/src/routes/v2/workflows/schemas.ts +40 -0
- package/apps/api/src/server.ts +146 -0
- package/apps/api/src/static/favicon.ico +0 -0
- package/apps/api/src/types/api.ts +14 -0
- package/apps/api/src/types/result.ts +3 -0
- package/apps/api/tsconfig.json +22 -0
- package/apps/api/vite.config.ts +28 -0
- package/apps/api/vitest.config.ts +14 -0
- package/apps/conversion-worker/Dockerfile +59 -0
- package/apps/conversion-worker/package.json +31 -0
- package/apps/conversion-worker/src/lib/config.ts +7 -0
- package/apps/conversion-worker/src/main.ts +22 -0
- package/apps/conversion-worker/src/workflows/convert-pptx.ts +116 -0
- package/apps/conversion-worker/tsconfig.json +27 -0
- package/apps/conversion-worker/vite.config.ts +33 -0
- package/apps/main/.prettierignore +6 -0
- package/apps/main/.prettierrc.js +3 -0
- package/apps/main/CLAUDE.md +245 -0
- package/apps/main/Procfile +1 -0
- package/apps/main/README.md +193 -0
- package/apps/main/db-tests.jsonl +116 -0
- package/apps/main/dotenvx-safe.sh +11 -0
- package/apps/main/drizzle/meta/_journal.json +1 -0
- package/apps/main/drizzle.config.ts +25 -0
- package/apps/main/eslint.config.mjs +3 -0
- package/apps/main/generate-routes.mjs +5 -0
- package/apps/main/package.json +131 -0
- package/apps/main/playwright.config.ts +23 -0
- package/apps/main/postcss.config.ts +5 -0
- package/apps/main/public/bg-dark.svg +10 -0
- package/apps/main/public/bg.svg +10 -0
- package/apps/main/public/favicon.ico +0 -0
- package/apps/main/run.sh +146 -0
- package/apps/main/scripts/browser.ts +14 -0
- package/apps/main/scripts/db-test-cov.ts +277 -0
- package/apps/main/scripts/login.ts +78 -0
- package/apps/main/scripts/repl.ts +61 -0
- package/apps/main/src/_foo.ts +31 -0
- package/apps/main/src/_tests/db.test.ts +19 -0
- package/apps/main/src/_tests/mock-db.ts +60 -0
- package/apps/main/src/client.tsx +13 -0
- package/apps/main/src/clients/loops.ts +13 -0
- package/apps/main/src/clients/polar.ts +12 -0
- package/apps/main/src/clients/posthog.ts +12 -0
- package/apps/main/src/components/chat/chat-context.tsx +99 -0
- package/apps/main/src/components/chat/chat-messages.tsx +184 -0
- package/apps/main/src/components/chat/chat-status.tsx +140 -0
- package/apps/main/src/components/chat/chat.tsx +458 -0
- package/apps/main/src/components/chat/citation-modal.tsx +54 -0
- package/apps/main/src/components/cta.tsx +21 -0
- package/apps/main/src/components/data-display/derived.tsx +40 -0
- package/apps/main/src/components/data-display/group-single.tsx +57 -0
- package/apps/main/src/components/data-display/group-table.tsx +165 -0
- package/apps/main/src/components/data-display/group-wrapper.tsx +54 -0
- package/apps/main/src/components/data-display/item.tsx +678 -0
- package/apps/main/src/components/error.tsx +45 -0
- package/apps/main/src/components/forms/error.tsx +22 -0
- package/apps/main/src/components/grid.tsx +7 -0
- package/apps/main/src/components/header/container.tsx +73 -0
- package/apps/main/src/components/header/header-bar.tsx +102 -0
- package/apps/main/src/components/modals/copy-display.tsx +37 -0
- package/apps/main/src/components/modals/copy-form.tsx +152 -0
- package/apps/main/src/components/modals/duplicate-workflow.tsx +89 -0
- package/apps/main/src/components/modals/field-correction.tsx +323 -0
- package/apps/main/src/components/modals/form-viewer.tsx +126 -0
- package/apps/main/src/components/modals/modals.tsx +44 -0
- package/apps/main/src/components/modals/new-deal.tsx +78 -0
- package/apps/main/src/components/modals/new-form.tsx +133 -0
- package/apps/main/src/components/modals/new-pipeline.tsx +70 -0
- package/apps/main/src/components/modals/new-submission.tsx +321 -0
- package/apps/main/src/components/modals/new-workflow.tsx +342 -0
- package/apps/main/src/components/modals/transformation-sources-modal.tsx +157 -0
- package/apps/main/src/components/modals/view-report.tsx +193 -0
- package/apps/main/src/components/not-found.tsx +14 -0
- package/apps/main/src/components/search/search-bar.tsx +178 -0
- package/apps/main/src/components/sheet-selector.tsx +135 -0
- package/apps/main/src/components/side-panel/doc-list.tsx +480 -0
- package/apps/main/src/components/sidebar/admin-sidebar.tsx +75 -0
- package/apps/main/src/components/sidebar/app-sidebar.tsx +417 -0
- package/apps/main/src/components/sidebar/model-select.tsx +134 -0
- package/apps/main/src/components/sidebar/settings-sidebar.tsx +132 -0
- package/apps/main/src/components/sidebar/sidebar-right.tsx +22 -0
- package/apps/main/src/components/sidebar/stop-impersonate.tsx +21 -0
- package/apps/main/src/components/svg/loading.tsx +33 -0
- package/apps/main/src/components/theme-selector.tsx +43 -0
- package/apps/main/src/components/unsaved-badge.tsx +19 -0
- package/apps/main/src/components/upload/file-upload.tsx +354 -0
- package/apps/main/src/fns/submission-groups.ts +28 -0
- package/apps/main/src/fns/submission-items.ts +11 -0
- package/apps/main/src/global-middleware.ts +16 -0
- package/apps/main/src/hooks/use-update-state.ts +18 -0
- package/apps/main/src/lib/auth-client.ts +16 -0
- package/apps/main/src/lib/auth.test.ts +359 -0
- package/apps/main/src/lib/auth.ts +144 -0
- package/apps/main/src/lib/billing.ts +23 -0
- package/apps/main/src/lib/config-iso.ts +76 -0
- package/apps/main/src/lib/config.ts +61 -0
- package/apps/main/src/lib/excel.ts +16 -0
- package/apps/main/src/lib/feedback-cache.ts +70 -0
- package/apps/main/src/lib/logger.ts +44 -0
- package/apps/main/src/lib/models.ts +22 -0
- package/apps/main/src/lib/not-found.ts +17 -0
- package/apps/main/src/lib/pdf.ts +16 -0
- package/apps/main/src/lib/tabularize.ts +54 -0
- package/apps/main/src/lib/utils.ts +10 -0
- package/apps/main/src/lib/zfd.ts +217 -0
- package/apps/main/src/middleware.ts +55 -0
- package/apps/main/src/routeTree.gen.ts +1255 -0
- package/apps/main/src/router.tsx +24 -0
- package/apps/main/src/routes/__root.tsx +92 -0
- package/apps/main/src/routes/_authed/_app/(dashboard)/index.tsx +227 -0
- package/apps/main/src/routes/_authed/_app/agents/$agentId/config.tsx +224 -0
- package/apps/main/src/routes/_authed/_app/agents/$agentId/index.tsx +206 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-actions-menu.tsx +94 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-artifacts.tsx +153 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-chat.tsx +220 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-history-menu.tsx +81 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-model-select.tsx +84 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-relevant-items.tsx +226 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-upload-button.tsx +298 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/context-modal.tsx +187 -0
- package/apps/main/src/routes/_authed/_app/agents/-fns.ts +560 -0
- package/apps/main/src/routes/_authed/_app/agents/index.tsx +65 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId/-components/citation-tree.tsx +268 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId.tsx +655 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/doc-loading.tsx +37 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/share-link.tsx +42 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-card.tsx +89 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-filter.tsx +193 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submissions.tsx +36 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/summary.tsx +82 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/upload-doc.tsx +120 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-fns.ts +653 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/index.tsx +259 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/route.tsx +29 -0
- package/apps/main/src/routes/_authed/_app/deals/index.tsx +104 -0
- package/apps/main/src/routes/_authed/_app/feedback/index.tsx +639 -0
- package/apps/main/src/routes/_authed/_app/feedback/insights.tsx +250 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/blockers-panel.tsx +260 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/manual-input-panel.tsx +301 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/submission-selector-modal.tsx +143 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/upload-doc.tsx +120 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/index.tsx +1485 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/dag-view.tsx +296 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/step-config-modal.tsx +634 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/index.tsx +911 -0
- package/apps/main/src/routes/_authed/_app/pipelines/-fns.ts +510 -0
- package/apps/main/src/routes/_authed/_app/pipelines/index.tsx +103 -0
- package/apps/main/src/routes/_authed/_app/reports/$reportId.tsx +397 -0
- package/apps/main/src/routes/_authed/_app/reports/-fns.ts +11 -0
- package/apps/main/src/routes/_authed/_app/reports/index.tsx +22 -0
- package/apps/main/src/routes/_authed/_app/route.tsx +48 -0
- package/apps/main/src/routes/_authed/_app/submissions/-columns.tsx +161 -0
- package/apps/main/src/routes/_authed/_app/submissions/-fns.ts +128 -0
- package/apps/main/src/routes/_authed/_app/submissions/index.tsx +190 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/$formId.tsx +542 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/derived.tsx +154 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/field.tsx +369 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/group.tsx +475 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/index.tsx +263 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/route.tsx +33 -0
- package/apps/main/src/routes/_authed/_app/workflows/-components/form-card.tsx +315 -0
- package/apps/main/src/routes/_authed/_app/workflows/index.tsx +86 -0
- package/apps/main/src/routes/_authed/admin/index.tsx +12 -0
- package/apps/main/src/routes/_authed/admin/route.tsx +42 -0
- package/apps/main/src/routes/_authed/admin/users/-columns.tsx +124 -0
- package/apps/main/src/routes/_authed/admin/users/-fns.ts +30 -0
- package/apps/main/src/routes/_authed/admin/users/index.tsx +29 -0
- package/apps/main/src/routes/_authed/catchNotFound.tsx +114 -0
- package/apps/main/src/routes/_authed/redirects/forms.$id.tsx +29 -0
- package/apps/main/src/routes/_authed/redirects/submissions.$id.tsx +27 -0
- package/apps/main/src/routes/_authed/redirects/workflows.$id.tsx +27 -0
- package/apps/main/src/routes/_authed/route.tsx +51 -0
- package/apps/main/src/routes/_authed/settings/-components/new-api-key.tsx +85 -0
- package/apps/main/src/routes/_authed/settings/-components/new-invite.tsx +100 -0
- package/apps/main/src/routes/_authed/settings/analytics.tsx +1710 -0
- package/apps/main/src/routes/_authed/settings/billing/-components/price-table.tsx +129 -0
- package/apps/main/src/routes/_authed/settings/billing/-fns.ts +76 -0
- package/apps/main/src/routes/_authed/settings/billing/index.tsx +119 -0
- package/apps/main/src/routes/_authed/settings/embed.tsx +337 -0
- package/apps/main/src/routes/_authed/settings/index.tsx +12 -0
- package/apps/main/src/routes/_authed/settings/keys.tsx +157 -0
- package/apps/main/src/routes/_authed/settings/members.tsx +276 -0
- package/apps/main/src/routes/_authed/settings/route.tsx +22 -0
- package/apps/main/src/routes/_authed/settings/user.tsx +87 -0
- package/apps/main/src/routes/_authed/settings/workspace.tsx +206 -0
- package/apps/main/src/routes/_public/-components/sign-in-up.tsx +96 -0
- package/apps/main/src/routes/_public/embedded.tsx +57 -0
- package/apps/main/src/routes/_public/invite.$inviteId.tsx +143 -0
- package/apps/main/src/routes/_public/no-access.tsx +38 -0
- package/apps/main/src/routes/_public/no-invite.tsx +39 -0
- package/apps/main/src/routes/_public/otp.tsx +103 -0
- package/apps/main/src/routes/_public/route.tsx +15 -0
- package/apps/main/src/routes/_public/sign-in.tsx +111 -0
- package/apps/main/src/routes/_public/sign-up.tsx +114 -0
- package/apps/main/src/routes/api/auth/$.ts +11 -0
- package/apps/main/src/routes/api/billing/paid.ts +42 -0
- package/apps/main/src/routes/api/billing/webhooks.ts +70 -0
- package/apps/main/src/routes/api/chat/agent.ts +40 -0
- package/apps/main/src/routes/api/chat/key.ts +42 -0
- package/apps/main/src/routes/api/chat/member.ts +35 -0
- package/apps/main/src/routes/api/test/index.ts +19 -0
- package/apps/main/src/server.tsx +6 -0
- package/apps/main/src/styles/app.css +23 -0
- package/apps/main/src/vite-env.d.ts +7 -0
- package/apps/main/test.http +6 -0
- package/apps/main/tsconfig.json +17 -0
- package/apps/main/vite.config.ts +24 -0
- package/apps/main/vitest.config.js +17 -0
- package/apps/mcp/README.md +171 -0
- package/apps/mcp/eslint.config.mjs +3 -0
- package/apps/mcp/package.json +37 -0
- package/apps/mcp/src/index.ts +414 -0
- package/apps/mcp/tsconfig.json +19 -0
- package/apps/mcp/vite.config.ts +22 -0
- package/apps/posthog-proxy/index.html +9 -0
- package/apps/workers/.prettierignore +7 -0
- package/apps/workers/.prettierrc.js +3 -0
- package/apps/workers/dotenvx-safe.sh +11 -0
- package/apps/workers/eslint.config.mjs +3 -0
- package/apps/workers/package.json +65 -0
- package/apps/workers/src/lib/config.ts +7 -0
- package/apps/workers/src/lib/messages.ts +0 -0
- package/apps/workers/src/lib/posthog.ts +25 -0
- package/apps/workers/src/main.ts +58 -0
- package/apps/workers/src/workflows/extraction.ts +866 -0
- package/apps/workers/src/workflows/index.ts +3 -0
- package/apps/workers/src/workflows/pipeline-dag.ts +210 -0
- package/apps/workers/src/workflows/pipeline-steps.ts +1393 -0
- package/apps/workers/tsconfig.json +16 -0
- package/apps/workers/vite.config.ts +35 -0
- package/docs/CHANGELOG.md +84 -0
- package/docs/agent-templates-and-runs.md +859 -0
- package/docs/aws-migration-plan.md +267 -0
- package/docs/impl-p0-form-builder-improvements.md +683 -0
- package/docs/on-prem-deployment-spec.docx +0 -0
- package/docs/on-prem-deployment-spec.md +378 -0
- package/docs/prd-form-builder-strategy.md +1120 -0
- package/docs/widget-ng-apf-packaging-spec.md +43 -0
- package/infra/k8s/charts/seadotdev/Chart.yaml +6 -0
- package/infra/k8s/charts/seadotdev/templates/_helpers.tpl +27 -0
- package/infra/k8s/charts/seadotdev/templates/api-v2.yaml +105 -0
- package/infra/k8s/charts/seadotdev/templates/external-secrets.yaml +83 -0
- package/infra/k8s/charts/seadotdev/templates/ingress.yaml +54 -0
- package/infra/k8s/charts/seadotdev/templates/main-app.yaml +104 -0
- package/infra/k8s/charts/seadotdev/templates/workers.yaml +182 -0
- package/infra/k8s/charts/seadotdev/values.yaml +143 -0
- package/infra/terraform/main.tf +399 -0
- package/libs/ai/.prettierignore +2 -0
- package/libs/ai/.prettierrc.js +5 -0
- package/libs/ai/README.md +139 -0
- package/libs/ai/eslint.config.mjs +3 -0
- package/libs/ai/package.json +42 -0
- package/libs/ai/src/index.ts +5 -0
- package/libs/ai/src/models.ts +19 -0
- package/libs/ai/src/rag/index.ts +1 -0
- package/libs/ai/src/rag/rag.test.ts +99 -0
- package/libs/ai/src/rag/rag.ts +510 -0
- package/libs/ai/tsconfig.json +21 -0
- package/libs/ai/vite.config.ts +38 -0
- package/libs/cache/.prettierignore +2 -0
- package/libs/cache/eslint.config.mjs +3 -0
- package/libs/cache/package.json +35 -0
- package/libs/cache/src/feedback.ts +77 -0
- package/libs/cache/src/index.ts +2 -0
- package/libs/cache/tsconfig.json +19 -0
- package/libs/cache/vite.config.ts +36 -0
- package/libs/clients/.prettierignore +6 -0
- package/libs/clients/eslint.config.mjs +3 -0
- package/libs/clients/package.json +59 -0
- package/libs/clients/src/azure.ts +249 -0
- package/libs/clients/src/gcp.ts +220 -0
- package/libs/clients/src/hatchet.ts +86 -0
- package/libs/clients/src/index.ts +8 -0
- package/libs/clients/src/loops.ts +86 -0
- package/libs/clients/src/polar.ts +77 -0
- package/libs/clients/src/posthog.ts +55 -0
- package/libs/clients/tsconfig.json +19 -0
- package/libs/clients/vite.config.ts +35 -0
- package/libs/config/.prettierignore +6 -0
- package/libs/config/.prettierrc.js +12 -0
- package/libs/config/eslint.config.mjs +3 -0
- package/libs/config/package.json +50 -0
- package/libs/config/src/azure.ts +54 -0
- package/libs/config/src/db.ts +18 -0
- package/libs/config/src/gcp.ts +53 -0
- package/libs/config/src/google.ts +17 -0
- package/libs/config/src/hatchet.ts +20 -0
- package/libs/config/src/index.ts +108 -0
- package/libs/config/src/llm.ts +17 -0
- package/libs/config/src/polar.ts +24 -0
- package/libs/config/src/util.ts +8 -0
- package/libs/config/src/vercel.ts +26 -0
- package/libs/config/tsconfig.json +19 -0
- package/libs/config/vite.config.ts +34 -0
- package/libs/core/.prettierignore +2 -0
- package/libs/core/eslint.config.mjs +3 -0
- package/libs/core/package.json +59 -0
- package/libs/core/src/chat/derived.ts +97 -0
- package/libs/core/src/chat/feedback.ts +293 -0
- package/libs/core/src/chat/index.ts +6 -0
- package/libs/core/src/chat/model.ts +92 -0
- package/libs/core/src/chat/prepare-tools.ts +286 -0
- package/libs/core/src/chat/prompts.ts +623 -0
- package/libs/core/src/chat/stream.ts +311 -0
- package/libs/core/src/chat/summarize.ts +168 -0
- package/libs/core/src/chat/tools/agent.ts +403 -0
- package/libs/core/src/chat/tools/chart-agent.ts +526 -0
- package/libs/core/src/chat/tools/chart-helpers/sandbox.ts +47 -0
- package/libs/core/src/chat/tools/chart.ts +86 -0
- package/libs/core/src/chat/tools/credit-agent.ts +1383 -0
- package/libs/core/src/chat/tools/credit.ts +1435 -0
- package/libs/core/src/chat/tools/deep-dive-agent.ts +100 -0
- package/libs/core/src/chat/tools/deep-dive.ts +141 -0
- package/libs/core/src/chat/tools/form.ts +449 -0
- package/libs/core/src/chat/tools/helpers.ts +91 -0
- package/libs/core/src/chat/tools/index.ts +42 -0
- package/libs/core/src/chat/tools/pipeline-artifact.ts +76 -0
- package/libs/core/src/chat/tools/report.ts +40 -0
- package/libs/core/src/chat/tools/search.ts +390 -0
- package/libs/core/src/chat/tools/submission.ts +227 -0
- package/libs/core/src/chat/tools/workflow.ts +684 -0
- package/libs/core/src/chat/types.ts +3 -0
- package/libs/core/src/data-extraction/classification/azure.ts +168 -0
- package/libs/core/src/data-extraction/classification/index.ts +1 -0
- package/libs/core/src/data-extraction/dal.ts +246 -0
- package/libs/core/src/data-extraction/form-structure-extractor.ts +294 -0
- package/libs/core/src/data-extraction/index.ts +4 -0
- package/libs/core/src/data-extraction/layout/azure.ts +730 -0
- package/libs/core/src/data-extraction/layout/excel.ts +180 -0
- package/libs/core/src/data-extraction/layout/gcp.ts +1071 -0
- package/libs/core/src/data-extraction/layout/index.ts +266 -0
- package/libs/core/src/data-extraction/layout/plaintext.ts +45 -0
- package/libs/core/src/data-extraction/models.ts +38 -0
- package/libs/core/src/data-extraction/pdf-utils.ts +96 -0
- package/libs/core/src/data-extraction/structuring/bank-statement.ts +1182 -0
- package/libs/core/src/data-extraction/structuring/custom.ts +495 -0
- package/libs/core/src/data-extraction/structuring/index.ts +290 -0
- package/libs/core/src/data-extraction/structuring/prompts.ts +69 -0
- package/libs/core/src/data-extraction/type-guards.ts +110 -0
- package/libs/core/src/data-extraction/types.ts +84 -0
- package/libs/core/src/data-extraction/utils.ts +31 -0
- package/libs/core/src/data-extraction/validation/bank-statement.ts +127 -0
- package/libs/core/src/deals.ts +17 -0
- package/libs/core/src/documents.ts +152 -0
- package/libs/core/src/index.ts +5 -0
- package/libs/core/src/pipelines/display.ts +678 -0
- package/libs/core/src/pipelines/execute.ts +2342 -0
- package/libs/core/src/pipelines/index.ts +4 -0
- package/libs/core/src/pipelines/list.ts +12 -0
- package/libs/core/src/pipelines/runs.ts +53 -0
- package/libs/core/tsconfig.json +20 -0
- package/libs/core/vite.config.ts +56 -0
- package/libs/dal/.prettierignore +6 -0
- package/libs/dal/.prettierrc.js +12 -0
- package/libs/dal/eslint.config.mjs +3 -0
- package/libs/dal/package.json +57 -0
- package/libs/dal/src/_tests/db.test.ts +19 -0
- package/libs/dal/src/_tests/mock-db.ts +60 -0
- package/libs/dal/src/api-key.test.ts +397 -0
- package/libs/dal/src/api-key.ts +110 -0
- package/libs/dal/src/billing.ts +23 -0
- package/libs/dal/src/conversation.test.ts +655 -0
- package/libs/dal/src/conversation.ts +532 -0
- package/libs/dal/src/deal.test.ts +45 -0
- package/libs/dal/src/deal.ts +87 -0
- package/libs/dal/src/defaults-consumer-lending-uk.ts +33 -0
- package/libs/dal/src/defaults-consumer-lending-us.ts +33 -0
- package/libs/dal/src/defaults-private-credit.ts +57 -0
- package/libs/dal/src/defaults-private-equity.ts +51 -0
- package/libs/dal/src/defaults-smb-lending-us.ts +1569 -0
- package/libs/dal/src/defaults-sme-lending-uk-express.ts +1527 -0
- package/libs/dal/src/defaults-sme-lending-uk.ts +1669 -0
- package/libs/dal/src/defaults-types.ts +23 -0
- package/libs/dal/src/defaults.ts +550 -0
- package/libs/dal/src/document.test.ts +70 -0
- package/libs/dal/src/document.ts +192 -0
- package/libs/dal/src/feedback.ts +255 -0
- package/libs/dal/src/form.test.ts +637 -0
- package/libs/dal/src/form.ts +1165 -0
- package/libs/dal/src/index.ts +20 -0
- package/libs/dal/src/invitation.test.ts +746 -0
- package/libs/dal/src/invitation.ts +207 -0
- package/libs/dal/src/member.test.ts +185 -0
- package/libs/dal/src/member.ts +80 -0
- package/libs/dal/src/organization.ts +116 -0
- package/libs/dal/src/permission.ts +25 -0
- package/libs/dal/src/pipeline.test.ts +388 -0
- package/libs/dal/src/pipeline.ts +4222 -0
- package/libs/dal/src/report.ts +199 -0
- package/libs/dal/src/result.ts +16 -0
- package/libs/dal/src/search.ts +172 -0
- package/libs/dal/src/session.test.ts +110 -0
- package/libs/dal/src/session.ts +31 -0
- package/libs/dal/src/submission.test.ts +1304 -0
- package/libs/dal/src/submission.ts +1396 -0
- package/libs/dal/src/tool.ts +159 -0
- package/libs/dal/src/user.ts +16 -0
- package/libs/dal/src/workflow.test.ts +89 -0
- package/libs/dal/src/workflow.ts +262 -0
- package/libs/dal/tsconfig.build.json +4 -0
- package/libs/dal/tsconfig.json +22 -0
- package/libs/dal/vite.config.ts +34 -0
- package/libs/db/.prettierignore +6 -0
- package/libs/db/.prettierrc.js +12 -0
- package/libs/db/eslint.config.mjs +3 -0
- package/libs/db/package.json +52 -0
- package/libs/db/src/index.ts +24 -0
- package/libs/db/src/relations.ts +549 -0
- package/libs/db/src/schema.ts +2 -0
- package/libs/db/src/schemas/api.ts +35 -0
- package/libs/db/src/schemas/conversations.ts +175 -0
- package/libs/db/src/schemas/core.ts +359 -0
- package/libs/db/src/schemas/documents.ts +181 -0
- package/libs/db/src/schemas/feedback.ts +40 -0
- package/libs/db/src/schemas/index.ts +26 -0
- package/libs/db/src/schemas/organisations.ts +97 -0
- package/libs/db/src/schemas/pipelines.ts +440 -0
- package/libs/db/src/schemas/users.ts +95 -0
- package/libs/db/src/types.ts +190 -0
- package/libs/db/src/utils.ts +14 -0
- package/libs/db/tsconfig.json +19 -0
- package/libs/db/vite.config.ts +31 -0
- package/libs/lint/.prettierignore +6 -0
- package/libs/lint/eslint.config.mjs +61 -0
- package/libs/lint/package.json +29 -0
- package/libs/lint/prettier.config.js +12 -0
- package/libs/schemas/.prettierignore +6 -0
- package/libs/schemas/.prettierrc.js +12 -0
- package/libs/schemas/README.md +15 -0
- package/libs/schemas/eslint.config.mjs +3 -0
- package/libs/schemas/package.json +67 -0
- package/libs/schemas/src/core/chat.ts +67 -0
- package/libs/schemas/src/core/core-result.ts +15 -0
- package/libs/schemas/src/core/data-extraction.ts +184 -0
- package/libs/schemas/src/core/layout.ts +478 -0
- package/libs/schemas/src/core/pipeline.ts +128 -0
- package/libs/schemas/src/core/submission.ts +97 -0
- package/libs/schemas/src/db/account.ts +57 -0
- package/libs/schemas/src/db/apiKey.ts +57 -0
- package/libs/schemas/src/db/context.ts +33 -0
- package/libs/schemas/src/db/conversation.ts +65 -0
- package/libs/schemas/src/db/deal.ts +42 -0
- package/libs/schemas/src/db/document.ts +103 -0
- package/libs/schemas/src/db/documentCitation.ts +58 -0
- package/libs/schemas/src/db/documentExtraction.ts +69 -0
- package/libs/schemas/src/db/fieldCorrection.ts +85 -0
- package/libs/schemas/src/db/form.ts +45 -0
- package/libs/schemas/src/db/formField.ts +59 -0
- package/libs/schemas/src/db/formGroup.ts +42 -0
- package/libs/schemas/src/db/impersonation.ts +39 -0
- package/libs/schemas/src/db/index.ts +25 -0
- package/libs/schemas/src/db/invitation.ts +42 -0
- package/libs/schemas/src/db/member.ts +36 -0
- package/libs/schemas/src/db/message.ts +58 -0
- package/libs/schemas/src/db/organization.ts +62 -0
- package/libs/schemas/src/db/session.ts +48 -0
- package/libs/schemas/src/db/submission.ts +54 -0
- package/libs/schemas/src/db/submissionGroup.ts +36 -0
- package/libs/schemas/src/db/submissionItem.ts +33 -0
- package/libs/schemas/src/db/submissionItemVersion.ts +70 -0
- package/libs/schemas/src/db/user.ts +51 -0
- package/libs/schemas/src/db/utils.ts +3 -0
- package/libs/schemas/src/db/verification.ts +36 -0
- package/libs/schemas/src/db/workflow.ts +42 -0
- package/libs/schemas/src/index.ts +10 -0
- package/libs/schemas/tsconfig.json +21 -0
- package/libs/schemas/vite.config.ts +38 -0
- package/libs/ui/.prettierignore +6 -0
- package/libs/ui/.prettierrc.js +12 -0
- package/libs/ui/components.json +24 -0
- package/libs/ui/eslint.config.mjs +3 -0
- package/libs/ui/package.json +142 -0
- package/libs/ui/src/components/chart-viz/chart.tsx +255 -0
- package/libs/ui/src/components/chart-viz/converters.ts +474 -0
- package/libs/ui/src/components/chart-viz/dashboard.tsx +146 -0
- package/libs/ui/src/components/chart-viz/index.ts +37 -0
- package/libs/ui/src/components/chart-viz/markdown.tsx +344 -0
- package/libs/ui/src/components/chart-viz/table.tsx +446 -0
- package/libs/ui/src/components/chart-viz/theme-context.tsx +70 -0
- package/libs/ui/src/components/chart-viz/themes/dark.ts +98 -0
- package/libs/ui/src/components/chart-viz/themes/index.ts +69 -0
- package/libs/ui/src/components/chart-viz/themes/light.ts +98 -0
- package/libs/ui/src/components/chart-viz/themes/tailwind.ts +326 -0
- package/libs/ui/src/components/chart-viz/themes/types.ts +99 -0
- package/libs/ui/src/components/chart-viz/tool-display.tsx +150 -0
- package/libs/ui/src/components/chart-viz/types.ts +95 -0
- package/libs/ui/src/components/doc-viewers/excel/index.tsx +431 -0
- package/libs/ui/src/components/doc-viewers/excel/themes.ts +160 -0
- package/libs/ui/src/components/doc-viewers/image/index.tsx +410 -0
- package/libs/ui/src/components/doc-viewers/pdf/index.tsx +258 -0
- package/libs/ui/src/components/doc-viewers/pdf/virtualized-pdf.tsx +556 -0
- package/libs/ui/src/components/misc/rel-date.tsx +52 -0
- package/libs/ui/src/components/misc/styled-link.tsx +2 -0
- package/libs/ui/src/components/table/data-table.tsx +546 -0
- package/libs/ui/src/components/table/report-table.tsx +305 -0
- package/libs/ui/src/components/table/sortable-column.tsx +34 -0
- package/libs/ui/src/components/ui/accordion.tsx +62 -0
- package/libs/ui/src/components/ui/alert-dialog.tsx +142 -0
- package/libs/ui/src/components/ui/alert.tsx +62 -0
- package/libs/ui/src/components/ui/artifact.tsx +118 -0
- package/libs/ui/src/components/ui/attachments.tsx +388 -0
- package/libs/ui/src/components/ui/avatar.tsx +39 -0
- package/libs/ui/src/components/ui/badge.tsx +43 -0
- package/libs/ui/src/components/ui/breadcrumb.tsx +102 -0
- package/libs/ui/src/components/ui/button-group.tsx +78 -0
- package/libs/ui/src/components/ui/button.tsx +79 -0
- package/libs/ui/src/components/ui/card.tsx +32 -0
- package/libs/ui/src/components/ui/carousel.tsx +228 -0
- package/libs/ui/src/components/ui/chain-of-thought.tsx +198 -0
- package/libs/ui/src/components/ui/checkbox.tsx +27 -0
- package/libs/ui/src/components/ui/citation.tsx +34 -0
- package/libs/ui/src/components/ui/code-block.tsx +500 -0
- package/libs/ui/src/components/ui/collapsible.tsx +19 -0
- package/libs/ui/src/components/ui/command.tsx +161 -0
- package/libs/ui/src/components/ui/conversation.tsx +90 -0
- package/libs/ui/src/components/ui/dialog.tsx +142 -0
- package/libs/ui/src/components/ui/dropdown-menu.tsx +246 -0
- package/libs/ui/src/components/ui/highlight.tsx +3 -0
- package/libs/ui/src/components/ui/hover-card.tsx +36 -0
- package/libs/ui/src/components/ui/inline-citation.tsx +251 -0
- package/libs/ui/src/components/ui/input-group.tsx +156 -0
- package/libs/ui/src/components/ui/input-otp.tsx +78 -0
- package/libs/ui/src/components/ui/input.tsx +21 -0
- package/libs/ui/src/components/ui/label.tsx +19 -0
- package/libs/ui/src/components/ui/model-selector.tsx +174 -0
- package/libs/ui/src/components/ui/multisidebar.tsx +750 -0
- package/libs/ui/src/components/ui/popover.tsx +43 -0
- package/libs/ui/src/components/ui/progress.tsx +28 -0
- package/libs/ui/src/components/ui/reasoning.tsx +178 -0
- package/libs/ui/src/components/ui/resizable.tsx +49 -0
- package/libs/ui/src/components/ui/scroll-area.tsx +54 -0
- package/libs/ui/src/components/ui/select.tsx +171 -0
- package/libs/ui/src/components/ui/separator.tsx +26 -0
- package/libs/ui/src/components/ui/sheet.tsx +128 -0
- package/libs/ui/src/components/ui/shimmer.tsx +53 -0
- package/libs/ui/src/components/ui/skeleton.tsx +13 -0
- package/libs/ui/src/components/ui/sonner.tsx +23 -0
- package/libs/ui/src/components/ui/switch.tsx +26 -0
- package/libs/ui/src/components/ui/table.tsx +96 -0
- package/libs/ui/src/components/ui/tabs.tsx +52 -0
- package/libs/ui/src/components/ui/textarea.tsx +41 -0
- package/libs/ui/src/components/ui/tool.tsx +209 -0
- package/libs/ui/src/components/ui/tooltip.tsx +58 -0
- package/libs/ui/src/components/ui/typography.tsx +113 -0
- package/libs/ui/src/fonts/manrope-v15-latin-300.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-400.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-500.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-600.woff2 +0 -0
- package/libs/ui/src/hooks/use-mobile.ts +19 -0
- package/libs/ui/src/lib/utils.ts +6 -0
- package/libs/ui/src/styles/fonts.css +35 -0
- package/libs/ui/src/styles/style.css +218 -0
- package/libs/ui/tsconfig.json +21 -0
- package/libs/ui/vite.config.ts +80 -0
- package/libs/ui-lit/README.md +245 -0
- package/libs/ui-lit/TESTING_GUIDE.md +296 -0
- package/libs/ui-lit/eslint.config.mjs +3 -0
- package/libs/ui-lit/package.json +41 -0
- package/libs/ui-lit/scripts/build-css.js +43 -0
- package/libs/ui-lit/src/components/sea-alert.ts +132 -0
- package/libs/ui-lit/src/components/sea-button.ts +95 -0
- package/libs/ui-lit/src/components/sea-card.ts +113 -0
- package/libs/ui-lit/src/components/sea-input.ts +184 -0
- package/libs/ui-lit/src/components/sea-spinner.ts +65 -0
- package/libs/ui-lit/src/index.ts +15 -0
- package/libs/ui-lit/src/lib/utils.ts +6 -0
- package/libs/ui-lit/src/styles/tailwind.css +76 -0
- package/libs/ui-lit/src/theme.css +66 -0
- package/libs/ui-lit/src/theme.ts +79 -0
- package/libs/ui-lit/src/vite-env.d.ts +6 -0
- package/libs/ui-lit/tailwind.config.ts +50 -0
- package/libs/ui-lit/test.html +289 -0
- package/libs/ui-lit/tsconfig.json +23 -0
- package/libs/ui-lit/vite.config.ts +31 -0
- package/libs/ui-lit/vite.css.config.ts +20 -0
- package/libs/util/.prettierignore +6 -0
- package/libs/util/.prettierrc.js +12 -0
- package/libs/util/eslint.config.mjs +3 -0
- package/libs/util/package.json +45 -0
- package/libs/util/src/billing.ts +10 -0
- package/libs/util/src/data-transform.ts +19 -0
- package/libs/util/src/encryption.ts +45 -0
- package/libs/util/src/fmt.test.ts +9 -0
- package/libs/util/src/fmt.ts +71 -0
- package/libs/util/src/fuzzy.ts +47 -0
- package/libs/util/src/id.ts +24 -0
- package/libs/util/src/invariant.ts +31 -0
- package/libs/util/src/sub-name.ts +7 -0
- package/libs/util/tsconfig.json +19 -0
- package/libs/util/vite.config.ts +34 -0
- package/package.json +28 -0
- package/packages/widget/.prettierignore +6 -0
- package/packages/widget/.prettierrc.js +12 -0
- package/packages/widget/README.md +95 -0
- package/packages/widget/eslint.config.mjs +11 -0
- package/packages/widget/openapi-ts.config.ts +8 -0
- package/packages/widget/package.json +89 -0
- package/packages/widget/postcss.config.mjs +10 -0
- package/packages/widget/src/clients/api/client/client.ts +187 -0
- package/packages/widget/src/clients/api/client/index.ts +22 -0
- package/packages/widget/src/clients/api/client/types.ts +192 -0
- package/packages/widget/src/clients/api/client/utils.ts +394 -0
- package/packages/widget/src/clients/api/client.gen.ts +18 -0
- package/packages/widget/src/clients/api/core/auth.ts +39 -0
- package/packages/widget/src/clients/api/core/bodySerializer.ts +74 -0
- package/packages/widget/src/clients/api/core/params.ts +132 -0
- package/packages/widget/src/clients/api/core/pathSerializer.ts +169 -0
- package/packages/widget/src/clients/api/core/types.ts +80 -0
- package/packages/widget/src/clients/api/index.ts +3 -0
- package/packages/widget/src/clients/api/sdk.gen.ts +805 -0
- package/packages/widget/src/clients/api/types.gen.ts +2085 -0
- package/packages/widget/src/components/container.tsx +42 -0
- package/packages/widget/src/components/data-display.tsx +384 -0
- package/packages/widget/src/components/data-viewer.tsx +311 -0
- package/packages/widget/src/components/doc-list.tsx +102 -0
- package/packages/widget/src/components/field-correction-modal.tsx +265 -0
- package/packages/widget/src/components/header.tsx +71 -0
- package/packages/widget/src/components/new-submission.tsx +290 -0
- package/packages/widget/src/components/sidebar-right.tsx +19 -0
- package/packages/widget/src/components/submission-card.tsx +66 -0
- package/packages/widget/src/components/submission-page.tsx +75 -0
- package/packages/widget/src/components/upload-doc.tsx +241 -0
- package/packages/widget/src/components/widget.tsx +101 -0
- package/packages/widget/src/index.tsx +167 -0
- package/packages/widget/src/lib/config.ts +2 -0
- package/packages/widget/src/lib/util.ts +40 -0
- package/packages/widget/src/styles/index.css +5 -0
- package/packages/widget/src/styles/tw-properties.css +337 -0
- package/packages/widget/src/vite-env.d.ts +3 -0
- package/packages/widget/tsconfig.app.json +35 -0
- package/packages/widget/tsconfig.json +4 -0
- package/packages/widget/tsconfig.node.json +24 -0
- package/packages/widget/vite.config.ts +116 -0
- package/packages/widget-lit/BOTTLENECKS.md +250 -0
- package/packages/widget-lit/IMPLEMENTATION_SUMMARY.md +295 -0
- package/packages/widget-lit/README.md +232 -0
- package/packages/widget-lit/eslint.config.mjs +3 -0
- package/packages/widget-lit/package.json +52 -0
- package/packages/widget-lit/src/api-client.ts +230 -0
- package/packages/widget-lit/src/api-client.ts.backup +218 -0
- package/packages/widget-lit/src/components/sea-chat.ts +382 -0
- package/packages/widget-lit/src/components/sea-submission-viewer.ts +267 -0
- package/packages/widget-lit/src/components/sea-widget.ts +317 -0
- package/packages/widget-lit/src/index.ts +48 -0
- package/packages/widget-lit/src/react.ts +58 -0
- package/packages/widget-lit/src/style.css +47 -0
- package/packages/widget-lit/tsconfig.json +24 -0
- package/packages/widget-lit/vite.config.ts +29 -0
- package/packages/widget-ng/DEVELOPMENT.md +74 -0
- package/packages/widget-ng/README.md +657 -0
- package/packages/widget-ng/dev.sh +14 -0
- package/packages/widget-ng/eslint.config.mjs +24 -0
- package/packages/widget-ng/ng-package.json +9 -0
- package/packages/widget-ng/package.json +85 -0
- package/packages/widget-ng/src/index.ts +45 -0
- package/packages/widget-ng/src/lib/components/sea-chat.component.ts +737 -0
- package/packages/widget-ng/src/lib/components/sea-data-viewer.component.ts +2240 -0
- package/packages/widget-ng/src/lib/components/sea-deal-form-modal.component.ts +702 -0
- package/packages/widget-ng/src/lib/components/sea-document-list.component.ts +350 -0
- package/packages/widget-ng/src/lib/components/sea-feedback-modal.component.ts +461 -0
- package/packages/widget-ng/src/lib/components/sea-file-upload.component.ts +655 -0
- package/packages/widget-ng/src/lib/components/sea-model-selection-modal.component.ts +367 -0
- package/packages/widget-ng/src/lib/components/sea-new-submission-modal.component.ts +414 -0
- package/packages/widget-ng/src/lib/components/sea-pdf-viewer.component.ts +869 -0
- package/packages/widget-ng/src/lib/components/sea-submission-card.component.ts +251 -0
- package/packages/widget-ng/src/lib/components/sea-widget.component.ts +684 -0
- package/packages/widget-ng/src/lib/models/submission.model.ts +170 -0
- package/packages/widget-ng/src/lib/pipes/markdown.pipe.ts +57 -0
- package/packages/widget-ng/src/lib/services/api-client.service.ts +715 -0
- package/packages/widget-ng/src/lib/services/chat.service.ts +330 -0
- package/packages/widget-ng/src/lib/services/config.service.ts +107 -0
- package/packages/widget-ng/src/web-component.ts +56 -0
- package/packages/widget-ng/tsconfig.json +25 -0
- package/packages/widget-ng/tsconfig.lib.json +9 -0
- package/packages/widget-ng/vite.config.elements.ts +26 -0
- package/packages/widget-ng/vitest.config.ts +19 -0
- package/packages/widget-ng/vitest.setup.ts +13 -0
- package/pnpm-workspace.yaml +18 -0
- package/render.yaml +136 -0
- package/scripts/README.md +57 -0
- package/scripts/package.json +22 -0
- package/scripts/python/.python-version +1 -0
- package/scripts/python/README.md +3 -0
- package/scripts/python/export-org-data.py +693 -0
- package/scripts/python/pyproject.toml +29 -0
- package/scripts/python/requirements-dev.lock +36 -0
- package/scripts/python/requirements.lock +36 -0
- package/scripts/python/src/gen.py +297 -0
- package/scripts/python/test.py +34 -0
- package/scripts/src/fix-storage-provider-mismatch.ts +239 -0
- package/scripts/src/sync-render-yaml.ts +290 -0
- package/scripts/src/test-chat-stream.ts +300 -0
- package/scripts/src/test-reconciliation.ts +230 -0
- package/scripts/tsconfig.json +15 -0
- package/tests/angular-test-app/.vscode/extensions.json +4 -0
- package/tests/angular-test-app/.vscode/launch.json +13 -0
- package/tests/angular-test-app/.vscode/tasks.json +24 -0
- package/tests/angular-test-app/README.md +59 -0
- package/tests/angular-test-app/angular.json +111 -0
- package/tests/angular-test-app/clean-start.sh +14 -0
- package/tests/angular-test-app/package.json +36 -0
- package/tests/angular-test-app/public/favicon.ico +0 -0
- package/tests/angular-test-app/src/app/app.component.ts +220 -0
- package/tests/angular-test-app/src/app/app.config.ts +5 -0
- package/tests/angular-test-app/src/env.d.ts +13 -0
- package/tests/angular-test-app/src/index.html +13 -0
- package/tests/angular-test-app/src/main.ts +6 -0
- package/tests/angular-test-app/src/styles.css +8 -0
- package/tests/angular-test-app/tsconfig.app.json +15 -0
- package/tests/angular-test-app/tsconfig.json +27 -0
- package/tests/crm-viewer-app/API_INTEGRATION_SUMMARY.md +295 -0
- package/tests/crm-viewer-app/CURRENT_ASSETS_FIELDS.md +148 -0
- package/tests/crm-viewer-app/FIELD_ID_MAPPING.md +206 -0
- package/tests/crm-viewer-app/INTEGRATION_GUIDE.md +309 -0
- package/tests/crm-viewer-app/README.md +174 -0
- package/tests/crm-viewer-app/REAL_API_INTEGRATION.md +240 -0
- package/tests/crm-viewer-app/UPDATED_IMPLEMENTATION.md +279 -0
- package/tests/crm-viewer-app/angular.json +114 -0
- package/tests/crm-viewer-app/package.json +35 -0
- package/tests/crm-viewer-app/src/app/app.component.ts +534 -0
- package/tests/crm-viewer-app/src/app/citation.service.ts +316 -0
- package/tests/crm-viewer-app/src/env.d.ts +16 -0
- package/tests/crm-viewer-app/src/index.html +19 -0
- package/tests/crm-viewer-app/src/main.ts +7 -0
- package/tests/crm-viewer-app/src/styles.css +409 -0
- package/tests/crm-viewer-app/src/template.html +2678 -0
- package/tests/crm-viewer-app/tsconfig.app.json +15 -0
- package/tests/crm-viewer-app/tsconfig.json +27 -0
- package/tests/e2e/package.json +17 -0
- package/tests/e2e/playwright.config.ts +75 -0
- package/tests/e2e/tests/api/health.spec.ts +10 -0
- package/tests/e2e/tests/app/example.spec.ts +10 -0
- package/tests/widget-test-app/.prettierignore +6 -0
- package/tests/widget-test-app/README.md +48 -0
- package/tests/widget-test-app/index.html +12 -0
- package/tests/widget-test-app/package.json +24 -0
- package/tests/widget-test-app/src/App.css +192 -0
- package/tests/widget-test-app/src/App.tsx +80 -0
- package/tests/widget-test-app/src/main.tsx +9 -0
- package/tests/widget-test-app/src/vite-env.d.ts +4 -0
- package/tests/widget-test-app/tsconfig.json +25 -0
- package/tests/widget-test-app/tsconfig.node.json +11 -0
- package/tests/widget-test-app/vite.config.ts +14 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
# Implementation Plan: P0 Form Builder Improvements
|
|
2
|
+
|
|
3
|
+
This document provides detailed implementation plans for all P0 items from the Form Builder Strategy PRD.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
| Item | Summary | Files to Change | Effort |
|
|
10
|
+
|------|---------|-----------------|--------|
|
|
11
|
+
| **A** | Enable derived fields in chat builder | `tools.ts` | ~30 min |
|
|
12
|
+
| **B** | Enhanced system prompt with form knowledge | `prompts.ts` | ~45 min |
|
|
13
|
+
| **G** | Extraction guidance in prompts | `prompts.ts` | ~15 min |
|
|
14
|
+
| **K** | Submission-aware edit restrictions | `tools.ts`, `prompts.ts`, `form.ts` | ~1 hr |
|
|
15
|
+
|
|
16
|
+
**Total estimated implementation time:** ~2.5 hours
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## P0-A: Enable Derived Fields in Chat Builder
|
|
21
|
+
|
|
22
|
+
### Problem
|
|
23
|
+
The chat builder schema (`formGroupSchema` in `tools.ts`) omits derived fields. Users cannot create assessment/AI fields through the chat interface.
|
|
24
|
+
|
|
25
|
+
### Current State
|
|
26
|
+
|
|
27
|
+
**File:** `apps/main/src/llm/tools.ts:42-57`
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
const formGroupSchema = z.object({
|
|
31
|
+
id: z.string().optional().describe("..."),
|
|
32
|
+
name: z.string().describe("The user-facing name of this group"),
|
|
33
|
+
hint: z.string().describe("LLM-facing hint for the group"),
|
|
34
|
+
multi: z.boolean().describe("Whether this group should allow multiple entries..."),
|
|
35
|
+
fields: z.array(formFieldSchema),
|
|
36
|
+
// NOTE: No derived field array!
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**File:** `libs/dal/src/form.ts:30-50` - `getForm()` does NOT include derived fields:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
with: {
|
|
44
|
+
groups: {
|
|
45
|
+
with: {
|
|
46
|
+
fields: { orderBy: asc(schema.formField.order) },
|
|
47
|
+
// NOTE: Missing `derived` relation!
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Solution
|
|
54
|
+
|
|
55
|
+
#### Step 1: Add derived schema to tools.ts
|
|
56
|
+
|
|
57
|
+
**File:** `apps/main/src/llm/tools.ts`
|
|
58
|
+
|
|
59
|
+
Add after line 40 (after `formFieldSchema`):
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const formDerivedSchema = z.object({
|
|
63
|
+
id: z
|
|
64
|
+
.string()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe(
|
|
67
|
+
"Provide this only for existing derived fields that have an id. Don't generate an id for new items",
|
|
68
|
+
),
|
|
69
|
+
name: z.string().describe("The user-facing name of this derived/assessment field"),
|
|
70
|
+
prompt: z.string().describe(
|
|
71
|
+
"The LLM prompt that will be used to generate this field's value after extraction. " +
|
|
72
|
+
"Example: 'Based on the extracted financial data, assess whether this borrower shows signs of financial distress. Return YES or NO with a brief explanation.'"
|
|
73
|
+
),
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Update `formGroupSchema` (line 42-57):
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
const formGroupSchema = z.object({
|
|
81
|
+
id: z
|
|
82
|
+
.string()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe(
|
|
85
|
+
"Provide this only for existing items that have an id. Don't generate an id for new groups",
|
|
86
|
+
),
|
|
87
|
+
name: z.string().describe("The user-facing name of this group"),
|
|
88
|
+
hint: z.string().describe("LLM-facing hint for the group"),
|
|
89
|
+
multi: z
|
|
90
|
+
.boolean()
|
|
91
|
+
.describe(
|
|
92
|
+
"Whether this group should allow multiple entries, eg data this is repeated for multiple years",
|
|
93
|
+
),
|
|
94
|
+
fields: z.array(formFieldSchema),
|
|
95
|
+
derived: z
|
|
96
|
+
.array(formDerivedSchema)
|
|
97
|
+
.optional()
|
|
98
|
+
.describe(
|
|
99
|
+
"Assessment fields that are populated by AI AFTER extraction completes. " +
|
|
100
|
+
"Use these for judgments, risk flags, or calculations based on extracted data. " +
|
|
101
|
+
"Do NOT use for direct extraction from documents."
|
|
102
|
+
),
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Step 2: Update getForm() to include derived fields
|
|
107
|
+
|
|
108
|
+
**File:** `libs/dal/src/form.ts:30-50`
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
export async function getForm({ member, formId }: { member: Member; formId: string }) {
|
|
112
|
+
const form = await db.query.form.findFirst({
|
|
113
|
+
where: and(
|
|
114
|
+
eq(schema.form.organizationId, member.organizationId),
|
|
115
|
+
isNull(schema.form.deletedAt),
|
|
116
|
+
eq(schema.form.id, formId),
|
|
117
|
+
),
|
|
118
|
+
with: {
|
|
119
|
+
groups: {
|
|
120
|
+
with: {
|
|
121
|
+
fields: {
|
|
122
|
+
orderBy: asc(schema.formField.order),
|
|
123
|
+
},
|
|
124
|
+
derived: true, // ADD THIS LINE
|
|
125
|
+
},
|
|
126
|
+
orderBy: asc(schema.formGroup.order),
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
invariant(form, `no form found for ${formId}`);
|
|
131
|
+
return form;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Step 3: Update persistFormInner() to handle derived fields
|
|
136
|
+
|
|
137
|
+
**File:** `apps/main/src/llm/tools.ts:107-189`
|
|
138
|
+
|
|
139
|
+
Add derived field handling in the `persistFormInner` function. After processing fields for each group:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Inside the group processing loop, after field handling (around line 187):
|
|
143
|
+
|
|
144
|
+
// Handle derived fields
|
|
145
|
+
if (group.derived && group.derived.length > 0) {
|
|
146
|
+
const formGroupId = group.id || newGroup.id;
|
|
147
|
+
|
|
148
|
+
// Get existing derived fields for this group
|
|
149
|
+
const existingDerived = await db.query.formDerived.findMany({
|
|
150
|
+
where: eq(schema.formDerived.formGroupId, formGroupId),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Delete derived fields that are no longer in the new list
|
|
154
|
+
const derivedIdsToKeep = group.derived.filter(d => d.id).map(d => d.id);
|
|
155
|
+
const derivedIdsToDelete = existingDerived
|
|
156
|
+
.filter(ed => !derivedIdsToKeep.includes(ed.id))
|
|
157
|
+
.map(d => d.id);
|
|
158
|
+
|
|
159
|
+
if (derivedIdsToDelete.length > 0) {
|
|
160
|
+
await db.delete(schema.formDerived).where(inArray(schema.formDerived.id, derivedIdsToDelete));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Upsert derived fields
|
|
164
|
+
for (const derived of group.derived) {
|
|
165
|
+
if (derived.id) {
|
|
166
|
+
await db
|
|
167
|
+
.update(schema.formDerived)
|
|
168
|
+
.set({ name: derived.name, prompt: derived.prompt })
|
|
169
|
+
.where(eq(schema.formDerived.id, derived.id));
|
|
170
|
+
} else {
|
|
171
|
+
await db.insert(schema.formDerived).values({
|
|
172
|
+
formGroupId,
|
|
173
|
+
name: derived.name,
|
|
174
|
+
prompt: derived.prompt,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Step 4: Update type for Group
|
|
182
|
+
|
|
183
|
+
**File:** `apps/main/src/llm/tools.ts:60`
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
type Group = z.infer<typeof formGroupSchema>;
|
|
187
|
+
type DerivedField = z.infer<typeof formDerivedSchema>;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Testing Checklist
|
|
191
|
+
- [ ] Chat can fetch forms with existing derived fields
|
|
192
|
+
- [ ] Chat can add new derived fields to a group
|
|
193
|
+
- [ ] Chat can update existing derived field names and prompts
|
|
194
|
+
- [ ] Chat can remove derived fields (with confirmation)
|
|
195
|
+
- [ ] Forms without derived fields still work correctly
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## P0-B: Enhanced System Prompt with Form Knowledge
|
|
200
|
+
|
|
201
|
+
### Problem
|
|
202
|
+
The form system prompt (in `prompts.ts`) only knows form name and workflow name. It doesn't understand form primitives, best practices, or semantic meaning of form components.
|
|
203
|
+
|
|
204
|
+
### Current State
|
|
205
|
+
|
|
206
|
+
**File:** `apps/main/src/llm/prompts.ts:37-99`
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
async function formSystemPrompt({ member, conversationId }) {
|
|
210
|
+
// Only fetches form.name and workflow.name
|
|
211
|
+
// Generic instructions about fetch/draft/persist phases
|
|
212
|
+
// No knowledge of:
|
|
213
|
+
// - Collection groups (multi)
|
|
214
|
+
// - Derived fields
|
|
215
|
+
// - Field types and when to use them
|
|
216
|
+
// - Extraction best practices
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Solution
|
|
221
|
+
|
|
222
|
+
**File:** `apps/main/src/llm/prompts.ts`
|
|
223
|
+
|
|
224
|
+
Replace the `formSystemPrompt` function:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
async function formSystemPrompt({
|
|
228
|
+
member,
|
|
229
|
+
conversationId,
|
|
230
|
+
}: {
|
|
231
|
+
member: MemberHydrated;
|
|
232
|
+
conversationId: string;
|
|
233
|
+
}) {
|
|
234
|
+
const form = await db.query.form.findFirst({
|
|
235
|
+
where: and(
|
|
236
|
+
eq(schema.form.organizationId, member.organizationId),
|
|
237
|
+
eq(schema.form.conversationId, conversationId),
|
|
238
|
+
),
|
|
239
|
+
columns: { name: true },
|
|
240
|
+
with: { workflow: { columns: { name: true } } },
|
|
241
|
+
});
|
|
242
|
+
invariant(form);
|
|
243
|
+
|
|
244
|
+
const context = `
|
|
245
|
+
- You are an assistant developed by sea.dev to help users with their data processing needs.
|
|
246
|
+
- The current date is ${formatISODate(new Date())}
|
|
247
|
+
- The current user is ${member.user.name}, who is a member of ${member.organization.name}
|
|
248
|
+
- The current form is called "${form.name}"
|
|
249
|
+
- It is part of a workflow called "${form.workflow.name}"
|
|
250
|
+
`;
|
|
251
|
+
|
|
252
|
+
const formKnowledge = `
|
|
253
|
+
## Form Structure Knowledge
|
|
254
|
+
|
|
255
|
+
You are building forms that serve as **data extraction targets**. Documents (PDFs, bank statements, financial reports) are uploaded and AI extracts structured data into the shape defined by the form.
|
|
256
|
+
|
|
257
|
+
### Form Primitives
|
|
258
|
+
|
|
259
|
+
1. **Groups** - Logical sections that organize related fields
|
|
260
|
+
- Regular groups: For single-instance data (e.g., "Company Information")
|
|
261
|
+
- Collection groups (\`multi: true\`): For repeating data (e.g., "Transactions", "Monthly Figures")
|
|
262
|
+
|
|
263
|
+
2. **Fields** - Individual data points with types:
|
|
264
|
+
- \`string\`: Short text (names, IDs, descriptions)
|
|
265
|
+
- \`string-long\`: Long text (notes, addresses)
|
|
266
|
+
- \`number\`: Numeric values (quantities, counts)
|
|
267
|
+
- \`money\`: Currency amounts (always use for financial figures)
|
|
268
|
+
- \`date\`: Dates (statement date, transaction date)
|
|
269
|
+
- \`email\`: Email addresses
|
|
270
|
+
- \`url\`: Web URLs
|
|
271
|
+
- \`boolean\`: Yes/No values
|
|
272
|
+
|
|
273
|
+
3. **Derived Fields** - AI assessment fields that run AFTER extraction
|
|
274
|
+
- Use for: Risk flags, quality assessments, calculations, judgments
|
|
275
|
+
- NOT for: Direct document extraction
|
|
276
|
+
- Example: "Based on the transactions, is this account showing signs of financial distress?"
|
|
277
|
+
|
|
278
|
+
### Collection Groups Best Practices
|
|
279
|
+
|
|
280
|
+
When creating collection groups (multi: true):
|
|
281
|
+
- **Pin the key identifier first** - The first field should be what other fields relate to
|
|
282
|
+
- For transactions: Date first
|
|
283
|
+
- For periods: Period/Year first
|
|
284
|
+
- For line items: Item name first
|
|
285
|
+
- Common patterns:
|
|
286
|
+
- Bank statement transactions: Date, Description, Amount, Balance
|
|
287
|
+
- Income statement periods: Period, Revenue, Expenses, Net Income
|
|
288
|
+
- Balance sheet items: Item, Value, Notes
|
|
289
|
+
|
|
290
|
+
### Field Hints Are Critical
|
|
291
|
+
|
|
292
|
+
Field hints tell the extraction AI where to find data. Be specific:
|
|
293
|
+
- ✅ Good: "Net income after tax, typically on line 28 of the income statement"
|
|
294
|
+
- ❌ Bad: "Net income"
|
|
295
|
+
- ✅ Good: "Transaction date in DD/MM/YYYY format from the first column"
|
|
296
|
+
- ❌ Bad: "Date"
|
|
297
|
+
|
|
298
|
+
### Extractability Constraint
|
|
299
|
+
|
|
300
|
+
**Only include fields that could conceivably be extracted from an uploaded document.**
|
|
301
|
+
|
|
302
|
+
Cannot be extracted (avoid these):
|
|
303
|
+
- Data from external APIs (credit scores, company registry lookups)
|
|
304
|
+
- Calculated aggregates across multiple documents
|
|
305
|
+
- Real-time data that changes after document creation
|
|
306
|
+
- Information requiring human judgment not in the document
|
|
307
|
+
|
|
308
|
+
Can be extracted:
|
|
309
|
+
- Any text, number, or date visible in the document
|
|
310
|
+
- Calculated values shown in the document (totals, subtotals)
|
|
311
|
+
- Information that can be inferred from document content
|
|
312
|
+
`;
|
|
313
|
+
|
|
314
|
+
const text = `
|
|
315
|
+
You are a helpful AI agent that builds and updates data extraction forms.
|
|
316
|
+
|
|
317
|
+
${formKnowledge}
|
|
318
|
+
|
|
319
|
+
## Workflow
|
|
320
|
+
|
|
321
|
+
If the user asks you to update the form, follow these steps:
|
|
322
|
+
|
|
323
|
+
**Phase 1: Retrieve**
|
|
324
|
+
You MUST always begin by calling \`fetchCurrentForm()\` to get the latest form structure.
|
|
325
|
+
|
|
326
|
+
**Phase 2: Draft**
|
|
327
|
+
1. Analyze the user's request against the current form
|
|
328
|
+
2. If the request is ambiguous, ask clarifying questions
|
|
329
|
+
3. Draft changes following the form structure knowledge above
|
|
330
|
+
4. Write a concise summary of proposed changes
|
|
331
|
+
|
|
332
|
+
**Phase 3: Confirm & Persist**
|
|
333
|
+
1. Present your summary and ask for explicit confirmation
|
|
334
|
+
2. If confirmed, call \`persistForm()\` with the complete updated form
|
|
335
|
+
3. Confirm what was done
|
|
336
|
+
|
|
337
|
+
## General Rules
|
|
338
|
+
- Always fetch the current form first - never assume its contents
|
|
339
|
+
- Any deletion or major restructuring is [DESTRUCTIVE] - require confirmation
|
|
340
|
+
- When adding collection groups, always consider what the key/pinned first field should be
|
|
341
|
+
- Prefer \`money\` type for any financial amounts
|
|
342
|
+
- Write detailed field hints that help extraction
|
|
343
|
+
|
|
344
|
+
Background context:
|
|
345
|
+
${context}
|
|
346
|
+
`;
|
|
347
|
+
|
|
348
|
+
return text;
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Testing Checklist
|
|
353
|
+
- [ ] Chat understands and can explain collection groups
|
|
354
|
+
- [ ] Chat suggests appropriate first fields for collections
|
|
355
|
+
- [ ] Chat uses correct field types (money for amounts)
|
|
356
|
+
- [ ] Chat writes detailed field hints
|
|
357
|
+
- [ ] Chat warns about non-extractable fields
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## P0-G: Extraction Guidance in Prompts
|
|
362
|
+
|
|
363
|
+
### Problem
|
|
364
|
+
Users don't know what makes a good form for AI extraction. The chat should proactively guide form design.
|
|
365
|
+
|
|
366
|
+
### Solution
|
|
367
|
+
|
|
368
|
+
This is largely addressed by P0-B above. The form knowledge section includes extraction guidance.
|
|
369
|
+
|
|
370
|
+
**Additional enhancement** - Add specific examples to the prompt:
|
|
371
|
+
|
|
372
|
+
Add to the `formKnowledge` section in `prompts.ts`:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
const extractionExamples = `
|
|
376
|
+
### Common Form Patterns
|
|
377
|
+
|
|
378
|
+
**Bank Statement Form:**
|
|
379
|
+
\`\`\`
|
|
380
|
+
Group: Account Information (multi: false)
|
|
381
|
+
- Account Number (string): "Bank account number, typically at top of statement"
|
|
382
|
+
- Account Holder (string): "Name of the account holder"
|
|
383
|
+
- Statement Date (date): "Statement period end date"
|
|
384
|
+
- Opening Balance (money): "Balance at start of period"
|
|
385
|
+
- Closing Balance (money): "Balance at end of period"
|
|
386
|
+
|
|
387
|
+
Group: Transactions (multi: true)
|
|
388
|
+
- Date (date): "Transaction date in first column" [PINNED FIRST]
|
|
389
|
+
- Description (string): "Transaction description or reference"
|
|
390
|
+
- Amount (money): "Transaction amount, negative for debits"
|
|
391
|
+
- Running Balance (money): "Balance after transaction"
|
|
392
|
+
\`\`\`
|
|
393
|
+
|
|
394
|
+
**Income Statement Form:**
|
|
395
|
+
\`\`\`
|
|
396
|
+
Group: Company Info (multi: false)
|
|
397
|
+
- Company Name (string): "Company name from header"
|
|
398
|
+
- Report Period (string): "Reporting period, e.g., 'FY 2024' or 'Q3 2024'"
|
|
399
|
+
|
|
400
|
+
Group: Financial Lines (multi: true)
|
|
401
|
+
- Line Item (string): "Name of the financial line item" [PINNED FIRST]
|
|
402
|
+
- Amount (money): "Value for this line item"
|
|
403
|
+
- Prior Period (money): "Comparison value from prior period, if shown"
|
|
404
|
+
|
|
405
|
+
Group: Assessment (multi: false)
|
|
406
|
+
- Revenue Trend (derived): "Based on revenue figures, is revenue growing, stable, or declining?"
|
|
407
|
+
- Profitability Flag (derived): "Is the company profitable based on net income? YES/NO"
|
|
408
|
+
\`\`\`
|
|
409
|
+
`;
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Testing Checklist
|
|
413
|
+
- [ ] Chat can suggest bank statement form structure
|
|
414
|
+
- [ ] Chat can suggest income statement form structure
|
|
415
|
+
- [ ] Examples help users understand the pattern
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## P0-K: Submission-Aware Edit Restrictions
|
|
420
|
+
|
|
421
|
+
### Problem
|
|
422
|
+
When a form has existing submissions, deleting fields/groups fails silently due to foreign key constraints. The chat doesn't know about submissions and can't warn users.
|
|
423
|
+
|
|
424
|
+
### Current Behavior
|
|
425
|
+
1. User asks: "Remove the Revenue field"
|
|
426
|
+
2. Chat attempts `persistForm()` with field removed
|
|
427
|
+
3. Database rejects (FK constraint on `submission_item.form_field_id`)
|
|
428
|
+
4. User sees generic error
|
|
429
|
+
|
|
430
|
+
### Solution
|
|
431
|
+
|
|
432
|
+
#### Step 1: Add new tool to check form editability
|
|
433
|
+
|
|
434
|
+
**File:** `apps/main/src/llm/tools.ts`
|
|
435
|
+
|
|
436
|
+
Add new tool after `fetchCurrentForm`:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
export function fetchFormEditability({ member, formId }: { member: Member; formId: string }) {
|
|
440
|
+
return tool({
|
|
441
|
+
description:
|
|
442
|
+
"Check what edits are allowed on this form. MUST be called before any form modifications " +
|
|
443
|
+
"to understand if the form has submissions that restrict certain changes.",
|
|
444
|
+
inputSchema: z.object({}),
|
|
445
|
+
execute: async () => {
|
|
446
|
+
try {
|
|
447
|
+
// Count submissions for this form
|
|
448
|
+
const [result] = await db
|
|
449
|
+
.select({ count: sql<number>`count(*)::int` })
|
|
450
|
+
.from(schema.submission)
|
|
451
|
+
.where(
|
|
452
|
+
and(
|
|
453
|
+
eq(schema.submission.formId, formId),
|
|
454
|
+
eq(schema.submission.organizationId, member.organizationId),
|
|
455
|
+
isNull(schema.submission.deletedAt),
|
|
456
|
+
),
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
const submissionCount = result?.count ?? 0;
|
|
460
|
+
const hasSubmissions = submissionCount > 0;
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
ok: true,
|
|
464
|
+
data: {
|
|
465
|
+
hasSubmissions,
|
|
466
|
+
submissionCount,
|
|
467
|
+
restrictions: {
|
|
468
|
+
canDeleteFields: !hasSubmissions,
|
|
469
|
+
canDeleteGroups: !hasSubmissions,
|
|
470
|
+
canChangeFieldTypes: !hasSubmissions,
|
|
471
|
+
canRenameFields: true,
|
|
472
|
+
canUpdateHints: true,
|
|
473
|
+
canAddFields: true,
|
|
474
|
+
canAddGroups: true,
|
|
475
|
+
canAddDerivedFields: true,
|
|
476
|
+
canReorderFields: true,
|
|
477
|
+
},
|
|
478
|
+
message: hasSubmissions
|
|
479
|
+
? `This form has ${submissionCount} submission(s) with data. ` +
|
|
480
|
+
`You CAN: add fields, rename fields, update hints, add derived fields, reorder fields. ` +
|
|
481
|
+
`You CANNOT: delete fields, delete groups, or change field types (would break existing data).`
|
|
482
|
+
: "This form has no submissions. All edits are allowed.",
|
|
483
|
+
},
|
|
484
|
+
};
|
|
485
|
+
} catch (err) {
|
|
486
|
+
return returnErr(err);
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
#### Step 2: Update system prompt to require editability check
|
|
494
|
+
|
|
495
|
+
**File:** `apps/main/src/llm/prompts.ts`
|
|
496
|
+
|
|
497
|
+
Update the workflow section:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
const text = `
|
|
501
|
+
You are a helpful AI agent that builds and updates data extraction forms.
|
|
502
|
+
|
|
503
|
+
${formKnowledge}
|
|
504
|
+
|
|
505
|
+
## Workflow
|
|
506
|
+
|
|
507
|
+
If the user asks you to update the form, follow these steps:
|
|
508
|
+
|
|
509
|
+
**Phase 1: Retrieve & Check Restrictions**
|
|
510
|
+
1. Call \`fetchCurrentForm()\` to get the latest form structure
|
|
511
|
+
2. Call \`fetchFormEditability()\` to check if the form has submissions
|
|
512
|
+
|
|
513
|
+
**Phase 2: Draft**
|
|
514
|
+
1. Review the editability restrictions from Phase 1
|
|
515
|
+
2. If the user requests a restricted action (delete field/group, change type) AND the form has submissions:
|
|
516
|
+
- Explain why it's not allowed
|
|
517
|
+
- Suggest alternatives:
|
|
518
|
+
- Add a new field instead of modifying existing
|
|
519
|
+
- Update field hints to improve extraction
|
|
520
|
+
- Clone the form if they need a fresh start
|
|
521
|
+
3. For allowed changes, draft the updates following form structure best practices
|
|
522
|
+
4. Write a concise summary of proposed changes
|
|
523
|
+
|
|
524
|
+
**Phase 3: Confirm & Persist**
|
|
525
|
+
1. Present your summary and ask for explicit confirmation
|
|
526
|
+
2. If confirmed, call \`persistForm()\` with the complete updated form
|
|
527
|
+
3. Confirm what was done
|
|
528
|
+
|
|
529
|
+
## Edit Restrictions
|
|
530
|
+
|
|
531
|
+
Forms with existing submissions have data integrity constraints:
|
|
532
|
+
|
|
533
|
+
| Action | Allowed? | Why |
|
|
534
|
+
|--------|----------|-----|
|
|
535
|
+
| Add new fields | ✅ Yes | Existing data unaffected |
|
|
536
|
+
| Add new groups | ✅ Yes | Existing data unaffected |
|
|
537
|
+
| Add derived fields | ✅ Yes | These are computed, not stored |
|
|
538
|
+
| Rename fields | ✅ Yes | Only label changes, data preserved |
|
|
539
|
+
| Update hints | ✅ Yes | Only affects future extraction |
|
|
540
|
+
| Reorder fields | ✅ Yes | Display only, data preserved |
|
|
541
|
+
| Delete fields | ❌ No | Would orphan submission data |
|
|
542
|
+
| Delete groups | ❌ No | Would orphan submission data |
|
|
543
|
+
| Change field type | ❌ No | Could corrupt existing values |
|
|
544
|
+
|
|
545
|
+
If a user wants to make restricted changes, suggest:
|
|
546
|
+
1. "Clone this form to create a fresh version you can fully edit"
|
|
547
|
+
2. "Delete existing submissions first (if they're test data)"
|
|
548
|
+
3. "Add a new field alongside the existing one"
|
|
549
|
+
|
|
550
|
+
## General Rules
|
|
551
|
+
- Always check editability before proposing changes
|
|
552
|
+
- Any deletion or major restructuring is [DESTRUCTIVE] - require confirmation
|
|
553
|
+
- When a form has submissions, be extra careful about data integrity
|
|
554
|
+
|
|
555
|
+
Background context:
|
|
556
|
+
${context}
|
|
557
|
+
`;
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
#### Step 3: Register the new tool
|
|
561
|
+
|
|
562
|
+
**File:** Where form chat tools are registered (likely in a route handler)
|
|
563
|
+
|
|
564
|
+
Ensure `fetchFormEditability` is included in the tools passed to the chat:
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
// In the form chat handler
|
|
568
|
+
const tools = {
|
|
569
|
+
fetchCurrentForm: fetchCurrentForm({ member, formId }),
|
|
570
|
+
fetchFormEditability: fetchFormEditability({ member, formId }), // ADD THIS
|
|
571
|
+
persistForm: persistForm({ member, formId }),
|
|
572
|
+
};
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
#### Step 4: Add validation in persistFormInner (defense in depth)
|
|
576
|
+
|
|
577
|
+
**File:** `apps/main/src/llm/tools.ts:107-189`
|
|
578
|
+
|
|
579
|
+
Add validation at the start of `persistFormInner`:
|
|
580
|
+
|
|
581
|
+
```typescript
|
|
582
|
+
async function persistFormInner({
|
|
583
|
+
member,
|
|
584
|
+
formId,
|
|
585
|
+
groups,
|
|
586
|
+
}: {
|
|
587
|
+
member: Member;
|
|
588
|
+
formId: string;
|
|
589
|
+
groups: Group[];
|
|
590
|
+
}) {
|
|
591
|
+
const form = await db.query.form.findFirst({
|
|
592
|
+
where: and(eq(schema.form.organizationId, member.organizationId), eq(schema.form.id, formId)),
|
|
593
|
+
with: { groups: { with: { fields: true } } },
|
|
594
|
+
});
|
|
595
|
+
invariant(form);
|
|
596
|
+
|
|
597
|
+
// Check if form has submissions
|
|
598
|
+
const [submissionResult] = await db
|
|
599
|
+
.select({ count: sql<number>`count(*)::int` })
|
|
600
|
+
.from(schema.submission)
|
|
601
|
+
.where(
|
|
602
|
+
and(
|
|
603
|
+
eq(schema.submission.formId, formId),
|
|
604
|
+
eq(schema.submission.organizationId, member.organizationId),
|
|
605
|
+
isNull(schema.submission.deletedAt),
|
|
606
|
+
),
|
|
607
|
+
);
|
|
608
|
+
const hasSubmissions = (submissionResult?.count ?? 0) > 0;
|
|
609
|
+
|
|
610
|
+
if (hasSubmissions) {
|
|
611
|
+
// Validate no destructive changes
|
|
612
|
+
const existingFieldIds = new Set(form.groups.flatMap(g => g.fields.map(f => f.id)));
|
|
613
|
+
const existingGroupIds = new Set(form.groups.map(g => g.id));
|
|
614
|
+
|
|
615
|
+
const newFieldIds = new Set(groups.flatMap(g => g.fields.filter(f => f.id).map(f => f.id)));
|
|
616
|
+
const newGroupIds = new Set(groups.filter(g => g.id).map(g => g.id));
|
|
617
|
+
|
|
618
|
+
// Check for deleted fields
|
|
619
|
+
for (const existingId of existingFieldIds) {
|
|
620
|
+
if (!newFieldIds.has(existingId)) {
|
|
621
|
+
throw new Error(
|
|
622
|
+
`Cannot delete field (ID: ${existingId}) because this form has existing submissions. ` +
|
|
623
|
+
`To delete fields, first remove all submissions or clone the form.`
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Check for deleted groups
|
|
629
|
+
for (const existingId of existingGroupIds) {
|
|
630
|
+
if (!newGroupIds.has(existingId)) {
|
|
631
|
+
throw new Error(
|
|
632
|
+
`Cannot delete group (ID: ${existingId}) because this form has existing submissions. ` +
|
|
633
|
+
`To delete groups, first remove all submissions or clone the form.`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// ... rest of existing logic
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Testing Checklist
|
|
644
|
+
- [ ] `fetchFormEditability` returns correct submission count
|
|
645
|
+
- [ ] Chat calls `fetchFormEditability` before proposing changes
|
|
646
|
+
- [ ] Chat explains restrictions when form has submissions
|
|
647
|
+
- [ ] Chat suggests alternatives (clone, add new field)
|
|
648
|
+
- [ ] `persistFormInner` throws clear error if restricted change attempted
|
|
649
|
+
- [ ] Forms without submissions allow all operations
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
## Implementation Order
|
|
654
|
+
|
|
655
|
+
Recommended order for implementation:
|
|
656
|
+
|
|
657
|
+
1. **P0-K** (Submission-aware restrictions) - Most impactful UX fix
|
|
658
|
+
2. **P0-A** (Derived fields) - Enables new functionality
|
|
659
|
+
3. **P0-B + P0-G** (Enhanced prompts) - Can be done together
|
|
660
|
+
|
|
661
|
+
---
|
|
662
|
+
|
|
663
|
+
## File Change Summary
|
|
664
|
+
|
|
665
|
+
| File | Changes |
|
|
666
|
+
|------|---------|
|
|
667
|
+
| `apps/main/src/llm/tools.ts` | Add `formDerivedSchema`, update `formGroupSchema`, add `fetchFormEditability`, update `persistFormInner` |
|
|
668
|
+
| `apps/main/src/llm/prompts.ts` | Complete rewrite of `formSystemPrompt` with form knowledge |
|
|
669
|
+
| `libs/dal/src/form.ts` | Update `getForm` to include derived fields |
|
|
670
|
+
| Route handler | Register `fetchFormEditability` tool |
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## Rollback Plan
|
|
675
|
+
|
|
676
|
+
All changes are additive and backward-compatible:
|
|
677
|
+
|
|
678
|
+
1. **Derived fields**: Existing forms without derived fields continue to work
|
|
679
|
+
2. **Enhanced prompts**: Only changes AI behavior, no data changes
|
|
680
|
+
3. **Editability check**: New tool, existing tools unchanged
|
|
681
|
+
4. **Validation in persistFormInner**: Only prevents operations that would fail anyway
|
|
682
|
+
|
|
683
|
+
If issues arise, changes can be reverted file-by-file without data migration.
|
|
Binary file
|