@allbluecn/web-app 0.22.4 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -14
- package/src/__tests__/integration/login-email-acceptance.test.ts +16 -0
- package/src/__tests__/story-view.test.ts +33 -1
- package/src/components/agents/__tests__/agent-bindings-tab.test.tsx +221 -0
- package/src/components/agents/__tests__/agents-page.test.tsx +284 -0
- package/src/components/agents/agent-bindings-tab.tsx +59 -45
- package/src/components/agents/agent-form-dialog.tsx +3 -3
- package/src/components/agents/agent-selector.tsx +2 -3
- package/src/components/agents/agents-page.tsx +66 -31
- package/src/components/agents/slash-skill-menu.tsx +2 -3
- package/src/components/auth/__tests__/session-guard.test.tsx +74 -0
- package/src/components/auth/session-guard.tsx +8 -0
- package/src/components/billing/login-prompt-dialog.tsx +1 -1
- package/src/components/billing/subscription-provider.tsx +2 -16
- package/src/components/bug/__tests__/peek-modes.test.tsx +8 -0
- package/src/components/bug/__tests__/subgroup-header.test.tsx +202 -40
- package/src/components/bug/peek-panel.tsx +5 -3
- package/src/components/bug/views/bug-list/group.tsx +12 -2
- package/src/components/bug/views/bug-list/index.tsx +94 -67
- package/src/components/command/command-palette.tsx +10 -9
- package/src/components/design/canvas/document/frame-custom-presets.ts +9 -1
- package/src/components/design/canvas/panels/toolbar.tsx +21 -22
- package/src/components/design/canvas/react/__tests__/canvas-context-load-echo.test.tsx +199 -0
- package/src/components/design/canvas/react/__tests__/hooks.test.tsx +17 -3
- package/src/components/design/canvas/react/canvas-context.tsx +47 -26
- package/src/components/design/canvas/react/hooks.ts +39 -34
- package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/context-menu.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/no-page-save-toast.test.tsx +17 -0
- package/src/components/design/editor/layout/__tests__/persistence-restore.test.tsx +17 -1
- package/src/components/design/editor/layout/__tests__/ssr-localstorage-smoke.test.tsx +17 -1
- package/src/components/design/editor/layout/design-editor-layout.tsx +13 -2
- package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +3 -19
- package/src/components/devtools/devtools-panel.tsx +56 -0
- package/src/components/forms/__tests__/create-app-form.test.tsx +131 -0
- package/src/components/forms/app-field-error.tsx +21 -1
- package/src/components/forms/app-field.tsx +8 -8
- package/src/components/forms/app-submit.tsx +12 -9
- package/src/components/forms/create-app-form.tsx +124 -0
- package/src/components/forms/index.ts +2 -3
- package/src/components/harness/__tests__/gallery-behavior.test.tsx +37 -1
- package/src/components/harness/__tests__/harness-workbench-first-send.test.tsx +4 -1
- package/src/components/harness/__tests__/message-actions.test.tsx +7 -6
- package/src/components/harness/__tests__/use-video-generation.test.tsx +165 -0
- package/src/components/harness/ai-chat-history/index.tsx +5 -3
- package/src/components/harness/gallery/gallery-card.tsx +57 -35
- package/src/components/harness/gallery/gallery-grid.tsx +32 -15
- package/src/components/harness/gallery/gallery-types.ts +19 -0
- package/src/components/harness/gallery/gallery-video-card.tsx +54 -0
- package/src/components/harness/gallery/types.ts +2 -0
- package/src/components/harness/gallery/use-video-generation.ts +95 -0
- package/src/components/harness/harness-workbench-page.tsx +2 -3
- package/src/components/harness/message-actions.tsx +5 -3
- package/src/components/hotkeys/shortcuts-panel.tsx +28 -13
- package/src/components/iteration/__tests__/burndown-chart.test.tsx +118 -0
- package/src/components/iteration/burndown-chart.tsx +54 -23
- package/src/components/knowledge/editor/__tests__/knowledge-doc-editor-collab.test.tsx +96 -0
- package/src/components/knowledge/editor/knowledge-doc-editor.tsx +56 -1
- package/src/components/knowledge/editor/mindmap-doc-editor.tsx +12 -0
- package/src/components/knowledge/editor/use-auto-save-channels.ts +3 -1
- package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +0 -4
- package/src/components/layout/sidebar-03/nav-knowledge.tsx +11 -11
- package/src/components/layout/sidebar-03/nav-main.tsx +12 -15
- package/src/components/layout/sidebar-03/nav-notifications.tsx +5 -8
- package/src/components/layout/sidebar-03/nav-workspace.tsx +11 -9
- package/src/components/notifications/__tests__/settings-notifications.test.tsx +158 -0
- package/src/components/notifications/settings-notifications.tsx +37 -13
- package/src/components/notifications/team-notifications.tsx +10 -14
- package/src/components/settings/personal-team/account/__tests__/account-client.test.tsx +170 -0
- package/src/components/settings/personal-team/account/account-client.tsx +44 -7
- package/src/components/settings/personal-team/team/team-client.tsx +17 -19
- package/src/components/shared-kit/list-kit/__tests__/frozen-header.test.ts +210 -41
- package/src/components/shared-kit/list-kit/frozen-header.ts +134 -21
- package/src/components/shared-kit/list-kit/kanban/frozen-header.ts +20 -27
- package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +8 -0
- package/src/components/story/__tests__/story-list-table.test.tsx +214 -0
- package/src/components/story/columns.tsx +11 -2
- package/src/components/story/peek-panel.tsx +4 -2
- package/src/components/story/story-list-table.tsx +16 -1
- package/src/components/story/views/story-list/__tests__/frozen-headers.test.tsx +186 -0
- package/src/components/story/views/story-list/group.tsx +12 -1
- package/src/components/story/views/story-list/index.tsx +101 -68
- package/src/components/testcase/__tests__/case-row.test.tsx +134 -2
- package/src/components/testcase/__tests__/peek-panel.test.tsx +8 -0
- package/src/components/testcase/__tests__/step-editor.test.tsx +106 -0
- package/src/components/testcase/list/grouped-list.tsx +50 -22
- package/src/components/testcase/peek-panel.tsx +7 -4
- package/src/components/testcase/step-editor.tsx +196 -150
- package/src/components/tiptap/notion-like/editor-extensions.ts +0 -3
- package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +1 -31
- package/src/components/tiptap/notion-like/notion-like-editor.tsx +32 -1
- package/src/components/workspace/__tests__/dialogs/create-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/__tests__/dialogs/edit-workspace-dialog.test.tsx +2 -28
- package/src/components/workspace/dialogs/create-workspace-dialog.tsx +45 -43
- package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +38 -36
- package/src/design-engine/engine/engine-decor.ts +2 -0
- package/src/design-engine/engine/engine-path.ts +2 -0
- package/src/hooks/__tests__/use-unsaved-guard.test.tsx +180 -0
- package/src/hooks/use-notifications.ts +9 -16
- package/src/hooks/use-unsaved-guard.tsx +87 -0
- package/src/lib/__tests__/pacer.test.ts +33 -96
- package/src/lib/__tests__/query-defaults.test.ts +169 -0
- package/src/lib/__tests__/query-global-error.test.ts +256 -0
- package/src/lib/anyhub/anyhub-store.ts +2 -2
- package/src/lib/changelog/sdk-versions.ts +2 -10
- package/src/lib/collab/presence-store.ts +5 -5
- package/src/lib/collab/use-presence-list-refresh.ts +2 -2
- package/src/lib/collab/use-share-presence.ts +2 -2
- package/src/lib/collections/query-keys.ts +7 -2
- package/src/lib/commands/__tests__/command-palette-state.test.ts +12 -14
- package/src/lib/commands/__tests__/registry.test.ts +6 -3
- package/src/lib/commands/command-palette-state.ts +8 -31
- package/src/lib/hotkeys/__tests__/registry.test.ts +71 -18
- package/src/lib/hotkeys/registry.ts +188 -85
- package/src/lib/hotkeys/types.ts +1 -13
- package/src/lib/pacer.ts +1 -79
- package/src/lib/queries/README.md +67 -0
- package/src/lib/queries/__tests__/agents-queries.test.ts +101 -0
- package/src/lib/queries/__tests__/compliance-queries.test.ts +136 -0
- package/src/lib/queries/__tests__/notifications-queries.test.ts +175 -0
- package/src/lib/queries/__tests__/team-queries.test.ts +87 -0
- package/src/lib/queries/agents.ts +40 -0
- package/src/lib/queries/compliance.ts +69 -0
- package/src/lib/queries/notifications.ts +63 -0
- package/src/lib/queries/team.ts +39 -0
- package/src/lib/query-defaults.ts +8 -0
- package/src/lib/query-global-error.ts +128 -0
- package/src/lib/remote-auth-client.ts +16 -0
- package/src/paraglide/README.md +1 -1
- package/src/paraglide/messages/_index.d.ts +11 -0
- package/src/paraglide/messages/_index.js +5659 -88285
- package/src/paraglide/messages/common_error_generic.d.ts +16 -0
- package/src/paraglide/messages/common_error_generic.js +29 -0
- package/src/paraglide/messages/common_unsaved_body.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_body.js +29 -0
- package/src/paraglide/messages/common_unsaved_leave.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_leave.js +29 -0
- package/src/paraglide/messages/common_unsaved_stay.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_stay.js +29 -0
- package/src/paraglide/messages/common_unsaved_title.d.ts +16 -0
- package/src/paraglide/messages/common_unsaved_title.js +29 -0
- package/src/paraglide/messages/gallery_videofailed1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videofailed1.js +30 -0
- package/src/paraglide/messages/gallery_videogenerating1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videogenerating1.js +30 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.d.ts +17 -0
- package/src/paraglide/messages/gallery_videomissingprompt2.js +30 -0
- package/src/paraglide/messages/gallery_videoprogress1.d.ts +19 -0
- package/src/paraglide/messages/gallery_videoprogress1.js +30 -0
- package/src/paraglide/messages/gallery_videostop1.d.ts +17 -0
- package/src/paraglide/messages/gallery_videostop1.js +30 -0
- package/src/paraglide/messages/story_table_resizecolumn1.d.ts +17 -0
- package/src/paraglide/messages/story_table_resizecolumn1.js +30 -0
- package/src/providers/index.tsx +5 -50
- package/src/routeTree.gen.ts +21 -0
- package/src/router.tsx +21 -8
- package/src/routes/__root.tsx +2 -1
- package/src/routes/__tests__/-edition-routing.test.tsx +6 -1
- package/src/routes/_login/forgot-password/route.lazy.tsx +7 -6
- package/src/routes/_login/login/route.lazy.tsx +10 -9
- package/src/routes/_login/register/route.lazy.tsx +19 -18
- package/src/routes/_login/reset-password/route.lazy.tsx +10 -9
- package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +9 -12
- package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +16 -13
- package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +1 -1
- package/src/routes/_nav/notifications/route.tsx +6 -16
- package/src/routes/_nav/settings/-settings-tabs.tsx +9 -12
- package/src/routes/api/generate/__tests__/media.test.ts +378 -0
- package/src/routes/api/generate/media.ts +179 -0
- package/src/server/__tests__/agent-client-graph.test.ts +0 -1
- package/src/server/__tests__/agent-crud.test.ts +37 -4
- package/src/server/__tests__/bug-groups-two-level.test.ts +34 -1
- package/src/server/__tests__/chat-conversations.test.ts +37 -4
- package/src/server/__tests__/chat-list-messages.test.ts +40 -7
- package/src/server/__tests__/csv-export.test.ts +36 -3
- package/src/server/__tests__/desktop-bootstrap.test.ts +189 -0
- package/src/server/__tests__/remote-auth.test.ts +72 -0
- package/src/server/__tests__/skill-crud.test.ts +37 -4
- package/src/server/__tests__/sso-domain.test.ts +1 -1
- package/src/server/__tests__/sso-rate-limit-singleton.test.ts +123 -0
- package/src/server/__tests__/task-serverfn-crud.test.ts +35 -2
- package/src/server/__tests__/task-serverfn-queries.test.ts +35 -2
- package/src/server/__tests__/testcase-board.test.ts +38 -5
- package/src/server/__tests__/testcase-bulk.test.ts +38 -5
- package/src/server/__tests__/testcase-list-scope.test.ts +38 -5
- package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +126 -2
- package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +4 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +30 -0
- package/src/server/ai-gateway/__tests__/pgvector-memory-conformance.test.ts +92 -0
- package/src/server/ai-gateway/__tests__/source-mode.test.ts +49 -8
- package/src/server/ai-gateway/ai-output-guard.ts +50 -2
- package/src/server/ai-gateway/chat-stream-builder.ts +3 -0
- package/src/server/ai-gateway/media/index.ts +36 -29
- package/src/server/ai-gateway/media/trim-input.ts +52 -0
- package/src/server/ai-gateway/memory/pgvector-adapter.ts +27 -13
- package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +252 -41
- package/src/server/ai-gateway/sandbox/harness-sandbox.ts +6 -67
- package/src/server/ai-gateway/source-mode.ts +24 -8
- package/src/server/desktop-bootstrap.ts +74 -0
- package/src/server/lib/__tests__/rate-limit.test.ts +0 -1
- package/src/server/lib/rate-limit.ts +0 -2
- package/src/server/middlewares/__tests__/auth-context.test.ts +156 -0
- package/src/server/middlewares/auth-context.ts +62 -0
- package/src/server/remote-auth.ts +58 -31
- package/src/server/serverFns/__tests__/ai-hosted-models.test.ts +47 -15
- package/src/server/serverFns/__tests__/ai-source-mode.test.ts +45 -15
- package/src/server/serverFns/__tests__/billing.test.ts +37 -2
- package/src/server/serverFns/__tests__/collab-snapshot.test.ts +41 -14
- package/src/server/serverFns/__tests__/collab.test.ts +41 -14
- package/src/server/serverFns/__tests__/compliance.test.ts +33 -1
- package/src/server/serverFns/__tests__/email-verification.test.ts +35 -1
- package/src/server/serverFns/__tests__/knowledge-breadcrumb.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-delete.test.ts +42 -14
- package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +46 -6
- package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +36 -2
- package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +42 -10
- package/src/server/serverFns/__tests__/knowledge-search.test.ts +45 -9
- package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +36 -2
- package/src/server/serverFns/__tests__/link-preview.test.ts +38 -4
- package/src/server/serverFns/__tests__/notifications-list.test.ts +36 -3
- package/src/server/serverFns/__tests__/ownership-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +39 -2
- package/src/server/serverFns/__tests__/project-kb.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-member-idor.test.ts +34 -1
- package/src/server/serverFns/__tests__/project-team-assign.test.ts +34 -1
- package/src/server/serverFns/__tests__/read-write-merge.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-comments.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-archive-detail.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +37 -3
- package/src/server/serverFns/__tests__/story-crud.test.ts +36 -3
- package/src/server/serverFns/__tests__/story-links.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-reactions.test.ts +38 -4
- package/src/server/serverFns/__tests__/story-tree.test.ts +38 -4
- package/src/server/serverFns/__tests__/team-accept.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-invitation.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-join-request.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-members.test.ts +34 -1
- package/src/server/serverFns/__tests__/team-ownership-merge.test.ts +34 -1
- package/src/server/serverFns/__tests__/update-bug-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/update-document-guard.test.ts +38 -4
- package/src/server/serverFns/__tests__/update-page-guard.test.ts +40 -4
- package/src/server/serverFns/__tests__/update-seats.test.ts +33 -1
- package/src/server/serverFns/__tests__/update-story-guard.test.ts +36 -3
- package/src/server/serverFns/__tests__/update-testcase-guard.test.ts +37 -3
- package/src/server/serverFns/__tests__/workspace-kb-idor.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace-kb.test.ts +36 -2
- package/src/server/serverFns/__tests__/workspace.test.ts +34 -1
- package/src/server/serverFns/activity.ts +10 -14
- package/src/server/serverFns/agents/agent-crud.ts +16 -15
- package/src/server/serverFns/agents/bindings.ts +12 -13
- package/src/server/serverFns/agents/skill-crud.ts +16 -15
- package/src/server/serverFns/ai/code-mode-readiness.ts +3 -4
- package/src/server/serverFns/ai/search-capability.ts +3 -4
- package/src/server/serverFns/anyhub/app.ts +10 -14
- package/src/server/serverFns/anyhub/index.ts +7 -10
- package/src/server/serverFns/anyhub/install.ts +4 -4
- package/src/server/serverFns/anyhub/permissions.ts +10 -14
- package/src/server/serverFns/anyhub/proxy.ts +4 -6
- package/src/server/serverFns/auth/email-verification.ts +4 -5
- package/src/server/serverFns/auth/session.ts +9 -0
- package/src/server/serverFns/billing.ts +18 -28
- package/src/server/serverFns/blob-upload.ts +6 -9
- package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-fix.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-reorder.test.ts +39 -5
- package/src/server/serverFns/bug/__tests__/bug-repro.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-story.test.ts +34 -1
- package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +34 -1
- package/src/server/serverFns/bug/bug-access-tokens.ts +16 -22
- package/src/server/serverFns/bug/bug-activities.ts +4 -6
- package/src/server/serverFns/bug/bug-collect-tokens.ts +13 -18
- package/src/server/serverFns/bug/bug-comments.ts +13 -18
- package/src/server/serverFns/bug/bug-crud/detail.ts +10 -14
- package/src/server/serverFns/bug/bug-crud.ts +28 -38
- package/src/server/serverFns/bug/bug-display-options.ts +8 -11
- package/src/server/serverFns/bug/bug-export.ts +5 -7
- package/src/server/serverFns/bug/bug-fix.ts +10 -14
- package/src/server/serverFns/bug/bug-groups.ts +10 -14
- package/src/server/serverFns/bug/bug-reactions.ts +10 -14
- package/src/server/serverFns/bug/bug-reorder.ts +4 -6
- package/src/server/serverFns/bug/bug-repro.ts +8 -11
- package/src/server/serverFns/bug/bug-story-bulk.ts +13 -18
- package/src/server/serverFns/bug/bug-story.ts +10 -14
- package/src/server/serverFns/bug/bug-views.ts +12 -18
- package/src/server/serverFns/bug/bug-webhooks.ts +13 -18
- package/src/server/serverFns/bug/test-bug-confirm.ts +7 -10
- package/src/server/serverFns/changelog/__tests__/fetch.test.ts +40 -1
- package/src/server/serverFns/changelog/fetch.ts +4 -6
- package/src/server/serverFns/chat/conversations.ts +17 -28
- package/src/server/serverFns/chat/list-messages.ts +4 -7
- package/src/server/serverFns/collab-presence.ts +11 -13
- package/src/server/serverFns/collab-snapshot.ts +6 -7
- package/src/server/serverFns/collab.ts +7 -7
- package/src/server/serverFns/compliance.ts +8 -8
- package/src/server/serverFns/design/__tests__/comments.test.ts +54 -10
- package/src/server/serverFns/design/__tests__/designs.test.ts +39 -16
- package/src/server/serverFns/design/__tests__/page-versions.test.ts +52 -14
- package/src/server/serverFns/design/__tests__/shares-password.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/shares.test.ts +44 -14
- package/src/server/serverFns/design/__tests__/versions.test.ts +44 -14
- package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +50 -21
- package/src/server/serverFns/design/ai/__tests__/providers.test.ts +42 -8
- package/src/server/serverFns/design/ai/agent-conversations.ts +19 -26
- package/src/server/serverFns/design/ai/fill-annotation.ts +5 -7
- package/src/server/serverFns/design/ai/generate-prototype.ts +5 -7
- package/src/server/serverFns/design/ai/hosted-models.ts +4 -5
- package/src/server/serverFns/design/ai/providers.ts +30 -39
- package/src/server/serverFns/design/ai/source-mode.ts +10 -12
- package/src/server/serverFns/design/comments.ts +14 -13
- package/src/server/serverFns/design/designs.ts +13 -19
- package/src/server/serverFns/design/page-versions.ts +17 -18
- package/src/server/serverFns/design/pages.ts +17 -18
- package/src/server/serverFns/design/reviews.ts +8 -9
- package/src/server/serverFns/design/shares-password.ts +13 -19
- package/src/server/serverFns/design/shares.ts +22 -31
- package/src/server/serverFns/design/versions.ts +8 -9
- package/src/server/serverFns/harness/__tests__/attach-prototype.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story-ssrf.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/cancel-run.test.ts +40 -15
- package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +52 -2
- package/src/server/serverFns/harness/__tests__/gallery.spec.ts +76 -12
- package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +38 -6
- package/src/server/serverFns/harness/__tests__/media-prototype.spec.ts +50 -6
- package/src/server/serverFns/harness/__tests__/media.spec.ts +55 -11
- package/src/server/serverFns/harness/__tests__/sandbox-policy.test.ts +41 -16
- package/src/server/serverFns/harness/__tests__/workspace-files.test.ts +41 -16
- package/src/server/serverFns/harness/attach-prototype.ts +4 -4
- package/src/server/serverFns/harness/attach-to-kb.ts +4 -4
- package/src/server/serverFns/harness/attach-to-story.ts +4 -4
- package/src/server/serverFns/harness/cancel-run.ts +4 -6
- package/src/server/serverFns/harness/extract-attachment.ts +3 -4
- package/src/server/serverFns/harness/gallery.ts +19 -23
- package/src/server/serverFns/harness/github-workspace.ts +14 -21
- package/src/server/serverFns/harness/media.ts +18 -117
- package/src/server/serverFns/harness/sandbox-policy.ts +11 -10
- package/src/server/serverFns/harness/search-mention-candidates.ts +4 -6
- package/src/server/serverFns/harness/workspace-files.ts +19 -26
- package/src/server/serverFns/iteration/__tests__/iteration-auto-schedule.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +35 -3
- package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +35 -3
- package/src/server/serverFns/iteration/iteration-auto-schedule.ts +7 -10
- package/src/server/serverFns/iteration/iteration-burndown.ts +4 -6
- package/src/server/serverFns/iteration/iteration-crud.ts +26 -35
- package/src/server/serverFns/iteration/iteration-stories.ts +10 -14
- package/src/server/serverFns/iteration/iteration-transfer.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +11 -15
- package/src/server/serverFns/knowledge/public/bookmarks/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +5 -7
- package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/bookmarks/update.ts +6 -8
- package/src/server/serverFns/knowledge/public/compliance/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/compliance/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/compliance/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/dictionary/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/dictionary/update.ts +5 -7
- package/src/server/serverFns/knowledge/public/entity-tags.ts +4 -6
- package/src/server/serverFns/knowledge/public/favorite.ts +7 -10
- package/src/server/serverFns/knowledge/public/legal/create.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/delete.ts +5 -7
- package/src/server/serverFns/knowledge/public/legal/detail.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/list.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/share.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/unshare.ts +4 -6
- package/src/server/serverFns/knowledge/public/legal/update.ts +5 -7
- package/src/server/serverFns/knowledge-index.ts +12 -16
- package/src/server/serverFns/knowledge.ts +50 -67
- package/src/server/serverFns/notifications.ts +25 -34
- package/src/server/serverFns/plugins/harness-plugins.ts +16 -23
- package/src/server/serverFns/project/module-overview.ts +7 -10
- package/src/server/serverFns/project.ts +48 -68
- package/src/server/serverFns/references/create.ts +4 -6
- package/src/server/serverFns/references/resolve.ts +4 -6
- package/src/server/serverFns/references/search.ts +4 -6
- package/src/server/serverFns/share/design/[designId]/events.ts +4 -6
- package/src/server/serverFns/sso.ts +1 -1
- package/src/server/serverFns/story/__tests__/bulk.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-assoc.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-attachments.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-crud-date-key.test.ts +42 -17
- package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-gantt-deps.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-groups.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +40 -4
- package/src/server/serverFns/story/__tests__/story-search.test.ts +34 -1
- package/src/server/serverFns/story/__tests__/story-transfer.test.ts +34 -1
- package/src/server/serverFns/story/link-preview.ts +5 -7
- package/src/server/serverFns/story/story-assoc.ts +28 -38
- package/src/server/serverFns/story/story-attachments.ts +7 -10
- package/src/server/serverFns/story/story-children.ts +4 -6
- package/src/server/serverFns/story/story-comments.ts +13 -18
- package/src/server/serverFns/story/story-crud/activities.ts +4 -6
- package/src/server/serverFns/story/story-crud/archive.ts +7 -10
- package/src/server/serverFns/story/story-crud/bulk.ts +10 -14
- package/src/server/serverFns/story/story-crud/detail.ts +7 -10
- package/src/server/serverFns/story/story-crud/label-suggest.ts +4 -6
- package/src/server/serverFns/story/story-crud/labels.ts +6 -9
- package/src/server/serverFns/story/story-crud/user-brief.ts +4 -6
- package/src/server/serverFns/story/story-crud.ts +13 -18
- package/src/server/serverFns/story/story-dependencies.ts +16 -22
- package/src/server/serverFns/story/story-groups.ts +10 -14
- package/src/server/serverFns/story/story-links.ts +13 -18
- package/src/server/serverFns/story/story-reactions.ts +13 -18
- package/src/server/serverFns/story/story-search.ts +7 -10
- package/src/server/serverFns/story/story-transfer.ts +10 -14
- package/src/server/serverFns/story/story-tree.ts +7 -10
- package/src/server/serverFns/story-display-options.ts +7 -8
- package/src/server/serverFns/story-view.ts +12 -18
- package/src/server/serverFns/tasks/task-crud.ts +13 -17
- package/src/server/serverFns/tasks/task-queries.ts +12 -18
- package/src/server/serverFns/team.ts +46 -66
- package/src/server/serverFns/testcase/__tests__/automation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/evidence-upload.test.ts +37 -3
- package/src/server/serverFns/testcase/__tests__/generation.test.ts +38 -5
- package/src/server/serverFns/testcase/__tests__/plans.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/regression.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/runs.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/stats.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-board.test.ts +39 -5
- package/src/server/serverFns/testcase/__tests__/testcase-crud.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-folders.test.ts +36 -3
- package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +38 -5
- package/src/server/serverFns/testcase/automation.ts +13 -17
- package/src/server/serverFns/testcase/bulk.ts +10 -14
- package/src/server/serverFns/testcase/evidence-upload.ts +5 -7
- package/src/server/serverFns/testcase/generation.ts +10 -13
- package/src/server/serverFns/testcase/plans.ts +23 -31
- package/src/server/serverFns/testcase/regression.ts +7 -10
- package/src/server/serverFns/testcase/run-cases.ts +13 -18
- package/src/server/serverFns/testcase/runs.ts +13 -18
- package/src/server/serverFns/testcase/stats.ts +13 -18
- package/src/server/serverFns/testcase/testcase-activities.ts +4 -6
- package/src/server/serverFns/testcase/testcase-board.ts +4 -6
- package/src/server/serverFns/testcase/testcase-crud.ts +20 -27
- package/src/server/serverFns/testcase/testcase-display-options.ts +8 -11
- package/src/server/serverFns/testcase/testcase-export.ts +5 -7
- package/src/server/serverFns/testcase/testcase-filter-views.ts +12 -18
- package/src/server/serverFns/testcase/testcase-folders.ts +16 -22
- package/src/server/serverFns/testcase/testcase-groups.ts +4 -6
- package/src/server/serverFns/testcase/testcase-reorder.ts +4 -6
- package/src/server/serverFns/translation.ts +4 -6
- package/src/server/serverFns/user/avatar.ts +4 -6
- package/src/server/serverFns/user/settings.ts +4 -6
- package/src/server/serverFns/user/update-locale.ts +4 -6
- package/src/server/serverFns/workspace-kb.ts +26 -35
- package/src/server/serverFns/workspace.ts +43 -59
- package/src/server/serverFns/ws.ts +4 -6
- package/src/server/serverfn-public-allowlist.ts +117 -0
- package/src/server/story/types.ts +0 -1
- package/src/server/sync/__tests__/scopes.test.ts +64 -0
- package/src/server/sync/scopes.ts +7 -0
- package/src/server/testcase/__tests__/auto-bug.test.ts +44 -12
- package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
- package/src/__typeprobe__.d.ts +0 -4
- package/src/components/forms/app-form-dialog.tsx +0 -126
- package/src/components/forms/hooks/use-form-submit.ts +0 -57
- package/src/components/forms/types.ts +0 -34
- package/src/components/harness/code/workspace-picker.tsx +0 -239
- package/src/components/tiptap/extensions/local-file/insert-local-file.ts +0 -35
- package/src/components/tiptap/extensions/local-file/local-file-node.ts +0 -71
- package/src/devframe-docks/ai-chat-iframe.tsx +0 -29
- package/src/devframe-docks/session-iframe.tsx +0 -90
- package/src/lib/__tests__/desktop-detect.test.ts +0 -19
- package/src/lib/collections/index.ts +0 -22
- package/src/lib/collections/knowledge/index.ts +0 -18
- package/src/lib/collections/knowledge/knowledge-bases-collection.ts +0 -34
- package/src/lib/collections/reference/bookmark-categories-collection.ts +0 -31
- package/src/lib/collections/reference/labels-collection.ts +0 -31
- package/src/lib/collections/reference/projects-collection.ts +0 -31
- package/src/lib/collections/reference/users-brief-collection.ts +0 -35
- package/src/lib/collections/reference/workspaces-collection.ts +0 -34
- package/src/lib/desktop-detect.ts +0 -29
- package/src/paraglide/messages/en.js +0 -28260
- package/src/paraglide/messages/zh.js +0 -28258
|
@@ -19,7 +19,7 @@ import { getPrisma } from "@allbluecn/database/get-prisma"
|
|
|
19
19
|
import { createServerFn } from "@tanstack/react-start";
|
|
20
20
|
import { getRequest } from "@tanstack/react-start/server";
|
|
21
21
|
import { z } from "zod";
|
|
22
|
-
import {
|
|
22
|
+
import { authContextMiddleware } from "@/server/middlewares/auth-context";
|
|
23
23
|
import { migrateStoriesToIndependentProject } from "@/server/builtin-project";
|
|
24
24
|
import { requireResource } from "@/server/resources";
|
|
25
25
|
import { USER_BRIEF_SELECT } from "@/server/story/user-brief";
|
|
@@ -37,12 +37,10 @@ async function requireWorkspaceOwner(workspaceId: string, userId: string) {
|
|
|
37
37
|
return ws;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export const listWorkspacesFn = createServerFn({ method: "GET" }).handler(
|
|
41
|
-
async () => {
|
|
40
|
+
export const listWorkspacesFn = createServerFn({ method: "GET" }).middleware([authContextMiddleware]).handler(
|
|
41
|
+
async ({ context }) => {
|
|
42
42
|
const prisma = await getPrisma()
|
|
43
|
-
const
|
|
44
|
-
const session = await requireAuth(request);
|
|
45
|
-
const userId = session.user.id;
|
|
43
|
+
const userId = context.user.id;
|
|
46
44
|
|
|
47
45
|
return prisma.workspace.findMany({
|
|
48
46
|
where: { ownerId: userId },
|
|
@@ -63,12 +61,10 @@ export const listWorkspacesFn = createServerFn({ method: "GET" }).handler(
|
|
|
63
61
|
},
|
|
64
62
|
);
|
|
65
63
|
|
|
66
|
-
export const listWorkspacesBriefFn = createServerFn({ method: "GET" }).handler(
|
|
67
|
-
async () => {
|
|
64
|
+
export const listWorkspacesBriefFn = createServerFn({ method: "GET" }).middleware([authContextMiddleware]).handler(
|
|
65
|
+
async ({ context }) => {
|
|
68
66
|
const prisma = await getPrisma()
|
|
69
|
-
const
|
|
70
|
-
const session = await requireAuth(request);
|
|
71
|
-
const userId = session.user.id;
|
|
67
|
+
const userId = context.user.id;
|
|
72
68
|
|
|
73
69
|
return prisma.workspace.findMany({
|
|
74
70
|
where: { ownerId: userId },
|
|
@@ -78,12 +74,10 @@ export const listWorkspacesBriefFn = createServerFn({ method: "GET" }).handler(
|
|
|
78
74
|
},
|
|
79
75
|
);
|
|
80
76
|
|
|
81
|
-
export const listPinnedWorkspacesBriefFn = createServerFn({ method: "GET" }).handler(
|
|
82
|
-
async () => {
|
|
77
|
+
export const listPinnedWorkspacesBriefFn = createServerFn({ method: "GET" }).middleware([authContextMiddleware]).handler(
|
|
78
|
+
async ({ context }) => {
|
|
83
79
|
const prisma = await getPrisma()
|
|
84
|
-
const
|
|
85
|
-
const session = await requireAuth(request);
|
|
86
|
-
const userId = session.user.id;
|
|
80
|
+
const userId = context.user.id;
|
|
87
81
|
|
|
88
82
|
return prisma.workspace.findMany({
|
|
89
83
|
where: { ownerId: userId, pinnedToSidebar: true },
|
|
@@ -99,12 +93,11 @@ const pinToggleSchema = z.object({
|
|
|
99
93
|
});
|
|
100
94
|
|
|
101
95
|
export const toggleWorkspacePinFn = createServerFn({ method: "POST" })
|
|
96
|
+
.middleware([authContextMiddleware])
|
|
102
97
|
.validator(pinToggleSchema)
|
|
103
|
-
.handler(async ({ data }) => {
|
|
98
|
+
.handler(async ({ data, context }) => {
|
|
104
99
|
const prisma = await getPrisma()
|
|
105
|
-
const
|
|
106
|
-
const session = await requireAuth(request);
|
|
107
|
-
const userId = session.user.id;
|
|
100
|
+
const userId = context.user.id;
|
|
108
101
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
109
102
|
|
|
110
103
|
await prisma.workspace.update({
|
|
@@ -121,12 +114,12 @@ const createSchema = z.object({
|
|
|
121
114
|
});
|
|
122
115
|
|
|
123
116
|
export const createWorkspaceFn = createServerFn({ method: "POST" })
|
|
117
|
+
.middleware([authContextMiddleware])
|
|
124
118
|
.validator(createSchema)
|
|
125
|
-
.handler(async ({ data }) => {
|
|
119
|
+
.handler(async ({ data, context }) => {
|
|
126
120
|
const prisma = await getPrisma()
|
|
127
121
|
const request = getRequest();
|
|
128
|
-
const
|
|
129
|
-
const userId = session.user.id;
|
|
122
|
+
const userId = context.user.id;
|
|
130
123
|
|
|
131
124
|
await requireResource(request, "workspaces", 1);
|
|
132
125
|
|
|
@@ -160,12 +153,11 @@ export const createWorkspaceFn = createServerFn({ method: "POST" })
|
|
|
160
153
|
const detailSchema = z.object({ workspaceId: z.string() });
|
|
161
154
|
|
|
162
155
|
export const getWorkspaceDetailFn = createServerFn({ method: "GET" })
|
|
156
|
+
.middleware([authContextMiddleware])
|
|
163
157
|
.validator(detailSchema)
|
|
164
|
-
.handler(async ({ data }) => {
|
|
158
|
+
.handler(async ({ data, context }) => {
|
|
165
159
|
const prisma = await getPrisma()
|
|
166
|
-
const
|
|
167
|
-
const session = await requireAuth(request);
|
|
168
|
-
const userId = session.user.id;
|
|
160
|
+
const userId = context.user.id;
|
|
169
161
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
170
162
|
|
|
171
163
|
const workspace = await prisma.workspace.findUnique({
|
|
@@ -187,12 +179,11 @@ export const getWorkspaceDetailFn = createServerFn({ method: "GET" })
|
|
|
187
179
|
});
|
|
188
180
|
|
|
189
181
|
export const listWorkspaceProjectsFn = createServerFn({ method: "GET" })
|
|
182
|
+
.middleware([authContextMiddleware])
|
|
190
183
|
.validator(detailSchema)
|
|
191
|
-
.handler(async ({ data }) => {
|
|
184
|
+
.handler(async ({ data, context }) => {
|
|
192
185
|
const prisma = await getPrisma()
|
|
193
|
-
const
|
|
194
|
-
const session = await requireAuth(request);
|
|
195
|
-
const userId = session.user.id;
|
|
186
|
+
const userId = context.user.id;
|
|
196
187
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
197
188
|
|
|
198
189
|
return prisma.project.findMany({
|
|
@@ -222,12 +213,11 @@ const updateSchema = z.object({
|
|
|
222
213
|
});
|
|
223
214
|
|
|
224
215
|
export const updateWorkspaceFn = createServerFn({ method: "POST" })
|
|
216
|
+
.middleware([authContextMiddleware])
|
|
225
217
|
.validator(updateSchema)
|
|
226
|
-
.handler(async ({ data }) => {
|
|
218
|
+
.handler(async ({ data, context }) => {
|
|
227
219
|
const prisma = await getPrisma()
|
|
228
|
-
const
|
|
229
|
-
const session = await requireAuth(request);
|
|
230
|
-
const userId = session.user.id;
|
|
220
|
+
const userId = context.user.id;
|
|
231
221
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
232
222
|
|
|
233
223
|
const { workspaceId, ...rest } = data;
|
|
@@ -247,12 +237,11 @@ const deleteSchema = z.object({
|
|
|
247
237
|
});
|
|
248
238
|
|
|
249
239
|
export const deleteWorkspaceFn = createServerFn({ method: "POST" })
|
|
240
|
+
.middleware([authContextMiddleware])
|
|
250
241
|
.validator(deleteSchema)
|
|
251
|
-
.handler(async ({ data }) => {
|
|
242
|
+
.handler(async ({ data, context }) => {
|
|
252
243
|
const prisma = await getPrisma()
|
|
253
|
-
const
|
|
254
|
-
const session = await requireAuth(request);
|
|
255
|
-
const userId = session.user.id;
|
|
244
|
+
const userId = context.user.id;
|
|
256
245
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
257
246
|
|
|
258
247
|
const projectCount = await prisma.project.count({
|
|
@@ -351,12 +340,11 @@ const workspaceActivitiesSchema = z.object({
|
|
|
351
340
|
});
|
|
352
341
|
|
|
353
342
|
export const listWorkspaceActivitiesFn = createServerFn({ method: "GET" })
|
|
343
|
+
.middleware([authContextMiddleware])
|
|
354
344
|
.validator(workspaceActivitiesSchema)
|
|
355
|
-
.handler(async ({ data }) => {
|
|
345
|
+
.handler(async ({ data, context }) => {
|
|
356
346
|
const prisma = await getPrisma()
|
|
357
|
-
const
|
|
358
|
-
const session = await requireAuth(request);
|
|
359
|
-
const userId = session.user.id;
|
|
347
|
+
const userId = context.user.id;
|
|
360
348
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
361
349
|
|
|
362
350
|
const projects = await prisma.project.findMany({
|
|
@@ -393,12 +381,11 @@ const workspaceActivityDataSchema = z.object({
|
|
|
393
381
|
});
|
|
394
382
|
|
|
395
383
|
export const getWorkspaceActivityDataFn = createServerFn({ method: "GET" })
|
|
384
|
+
.middleware([authContextMiddleware])
|
|
396
385
|
.validator(workspaceActivityDataSchema)
|
|
397
|
-
.handler(async ({ data }) => {
|
|
386
|
+
.handler(async ({ data, context }) => {
|
|
398
387
|
const prisma = await getPrisma()
|
|
399
|
-
const
|
|
400
|
-
const session = await requireAuth(request);
|
|
401
|
-
const userId = session.user.id;
|
|
388
|
+
const userId = context.user.id;
|
|
402
389
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
403
390
|
|
|
404
391
|
const projects = await prisma.project.findMany({
|
|
@@ -453,12 +440,11 @@ const workspaceMemberSchema = z.object({
|
|
|
453
440
|
});
|
|
454
441
|
|
|
455
442
|
export const listWorkspaceMembersFn = createServerFn({ method: "GET" })
|
|
443
|
+
.middleware([authContextMiddleware])
|
|
456
444
|
.validator(workspaceMemberSchema)
|
|
457
|
-
.handler(async ({ data }) => {
|
|
445
|
+
.handler(async ({ data, context }) => {
|
|
458
446
|
const prisma = await getPrisma()
|
|
459
|
-
const
|
|
460
|
-
const session = await requireAuth(request);
|
|
461
|
-
const userId = session.user.id;
|
|
447
|
+
const userId = context.user.id;
|
|
462
448
|
await requireWorkspaceOwner(data.workspaceId, userId);
|
|
463
449
|
|
|
464
450
|
const [members, owner] = await Promise.all([
|
|
@@ -505,12 +491,11 @@ const addWorkspaceMemberSchema = z.object({
|
|
|
505
491
|
});
|
|
506
492
|
|
|
507
493
|
export const addWorkspaceMemberFn = createServerFn({ method: "POST" })
|
|
494
|
+
.middleware([authContextMiddleware])
|
|
508
495
|
.validator(addWorkspaceMemberSchema)
|
|
509
|
-
.handler(async ({ data }) => {
|
|
496
|
+
.handler(async ({ data, context }) => {
|
|
510
497
|
const prisma = await getPrisma()
|
|
511
|
-
const
|
|
512
|
-
const session = await requireAuth(request);
|
|
513
|
-
const currentUserId = session.user.id;
|
|
498
|
+
const currentUserId = context.user.id;
|
|
514
499
|
await requireWorkspaceOwner(data.workspaceId, currentUserId);
|
|
515
500
|
|
|
516
501
|
const workspace = await prisma.workspace.findUnique({
|
|
@@ -552,12 +537,11 @@ const removeWorkspaceMemberSchema = z.object({
|
|
|
552
537
|
});
|
|
553
538
|
|
|
554
539
|
export const removeWorkspaceMemberFn = createServerFn({ method: "POST" })
|
|
540
|
+
.middleware([authContextMiddleware])
|
|
555
541
|
.validator(removeWorkspaceMemberSchema)
|
|
556
|
-
.handler(async ({ data }) => {
|
|
542
|
+
.handler(async ({ data, context }) => {
|
|
557
543
|
const prisma = await getPrisma()
|
|
558
|
-
const
|
|
559
|
-
const session = await requireAuth(request);
|
|
560
|
-
const currentUserId = session.user.id;
|
|
544
|
+
const currentUserId = context.user.id;
|
|
561
545
|
await requireWorkspaceOwner(data.workspaceId, currentUserId);
|
|
562
546
|
|
|
563
547
|
if (data.userId === (await prisma.workspace.findUnique({
|
|
@@ -16,23 +16,21 @@
|
|
|
16
16
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
18
|
import { createServerFn } from '@tanstack/react-start'
|
|
19
|
-
import { getRequest } from '@tanstack/react-start/server'
|
|
20
19
|
import { z } from 'zod'
|
|
21
|
-
import {
|
|
20
|
+
import { authContextMiddleware } from '@/server/middlewares/auth-context'
|
|
22
21
|
|
|
23
22
|
const wsSchema = z.object({
|
|
24
23
|
ids: z.array(z.string()).default([]),
|
|
25
24
|
})
|
|
26
25
|
|
|
27
26
|
export const wsStreamFn = createServerFn({ method: 'GET' })
|
|
27
|
+
.middleware([authContextMiddleware])
|
|
28
28
|
.validator(wsSchema)
|
|
29
|
-
.handler(async ({ data }) => {
|
|
30
|
-
const request = getRequest()
|
|
31
|
-
const session = await requireAuth(request)
|
|
29
|
+
.handler(async ({ data, context }) => {
|
|
32
30
|
if (!data.ids.length) throw new Error('Missing ids parameter')
|
|
33
31
|
return {
|
|
34
32
|
message: 'SSE stream endpoint',
|
|
35
|
-
userId:
|
|
33
|
+
userId: context.user.id,
|
|
36
34
|
entityIds: data.ids,
|
|
37
35
|
}
|
|
38
36
|
})
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* serverFn 公开端点白名单(TanStack 优化计划任务 7,口径⑥ 配套)。
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ 准入纪律:新增条目必须附一行理由注释(信任锚是什么、为什么无法挂
|
|
9
|
+
* authContextMiddleware),PR 审查重点看这里。删除条目无需理由。
|
|
10
|
+
*
|
|
11
|
+
* 定位约束:本文件必须位于 `src/server/` 层、serverFns 树外——purity 脚本
|
|
12
|
+
* 口径②禁止 serverFns 树内出现不含 createServerFn 的纯 helper 模块。
|
|
13
|
+
*
|
|
14
|
+
* 消费方式:scripts/check-serverfn-purity.mjs 口径⑥按文本解析本文件导出的
|
|
15
|
+
* `SERVERFN_PUBLIC_ALLOWLIST` 数组(函数名精确匹配),命中者豁免
|
|
16
|
+
* 「每个 createServerFn 链必须含 .middleware(」检查。运行时零引用
|
|
17
|
+
* (脚本读文件文本,不 import),故本文件不得 import 任何模块。
|
|
18
|
+
*/
|
|
19
|
+
export const SERVERFN_PUBLIC_ALLOWLIST = [
|
|
20
|
+
// ── 会话端点自身(挂 requireAuth 会死循环)──
|
|
21
|
+
// 「我是谁」端点:未登录返回 null/guest,登录态检测依赖其可匿名调用
|
|
22
|
+
'getSessionFn',
|
|
23
|
+
// 桌面端 remote-auth token 换取:信任锚是 token 本身 + 桌面部署判定 + 限流
|
|
24
|
+
'exchangeRemoteTokenFn',
|
|
25
|
+
// 清除桌面端 remote-auth 持久化状态(登出语义,无会话也可调用)
|
|
26
|
+
'logoutRemoteFn',
|
|
27
|
+
|
|
28
|
+
// ── 登录/注册/初始化流程(鉴权前的入口)──
|
|
29
|
+
// 登录页读取可用 OAuth provider 列表(未登录场景)
|
|
30
|
+
'getAuthProviders',
|
|
31
|
+
// 注册(鉴权前入口)
|
|
32
|
+
'registerFn',
|
|
33
|
+
// 登录页读取注册开关配置(未登录场景)
|
|
34
|
+
'getRegistrationModeFn',
|
|
35
|
+
// 忘记密码(未登录流程)
|
|
36
|
+
'forgotPasswordFn',
|
|
37
|
+
// 重置密码 token 校验(未登录流程)
|
|
38
|
+
'validateResetTokenFn',
|
|
39
|
+
// 重置密码提交(未登录流程)
|
|
40
|
+
'resetPasswordFn',
|
|
41
|
+
// 邮箱验证确认:token 是信任锚,IP 限流防刷
|
|
42
|
+
'confirmEmailVerificationFn',
|
|
43
|
+
// 邮箱验证状态查询:handler 内 getCurrentSession 软鉴权,未登录返回
|
|
44
|
+
// { verified: null } 软契约(客户端 enabled:userId!==null 门控,仅登录态消费)
|
|
45
|
+
'getEmailVerifiedStatusFn',
|
|
46
|
+
// 邮箱验证提醒 nudge:handler 内 getCurrentSession 软鉴权,未登录返回
|
|
47
|
+
// { reminded: false } 软契约(客户端 session 门控 + catch 吞错,仅登录态消费)
|
|
48
|
+
'ensureVerifyReminderFn',
|
|
49
|
+
// 初始化向导:探测是否已有超管(系统初始化前,必然未登录)
|
|
50
|
+
'checkAdminExistsFn',
|
|
51
|
+
// 登录页 SSO 域名发现(未登录场景,domain 限流防探测)
|
|
52
|
+
'checkSsoDomainFn',
|
|
53
|
+
|
|
54
|
+
// ── token / 匿名信任锚端点 ──
|
|
55
|
+
// 匿名埋点:占位实现仅 console,IP 限流 + 单批上限防日志洪泛
|
|
56
|
+
'trackAnalyticsFn',
|
|
57
|
+
// 公开定价页套餐列表(营销页未登录可浏览)
|
|
58
|
+
'listPublicPlansFn',
|
|
59
|
+
// 公开应用市场目录(对比 listAnyHubAppsFn 有 requireAuth,市场浏览不需要)
|
|
60
|
+
'listMarketplaceAppsFn',
|
|
61
|
+
// BUG 公开收集页读取:token 是唯一信任锚(文件头注释明示免 requireAuth)
|
|
62
|
+
'getCollectPageFn',
|
|
63
|
+
// BUG 公开收集提交:同上,X-Bug-Key token 信任锚
|
|
64
|
+
'submitCollectedBugFn',
|
|
65
|
+
// 匿名 changelog 邮件订阅 + IP 限流
|
|
66
|
+
'subscribeChangelogFn',
|
|
67
|
+
// changelog 订阅确认:邮件 token 信任锚
|
|
68
|
+
'confirmChangelogSubscriptionFn',
|
|
69
|
+
// 邮件一键退订:HMAC 无状态 token 信任锚 + IP 限流防爆破
|
|
70
|
+
'unsubscribeByEmailTokenFn',
|
|
71
|
+
|
|
72
|
+
// ── 公开分享/公开页(分享链接语义,不强制登录)──
|
|
73
|
+
// 设计分享页读取(share 链接语义;有密码的分享由密码门在 handler 内校验)
|
|
74
|
+
'getDesignShareFn',
|
|
75
|
+
// 分享页密码校验:密码本身是信任锚(未登录场景)
|
|
76
|
+
'verifySharePasswordFn',
|
|
77
|
+
// 分享页版本列表(分享链接语义)
|
|
78
|
+
'getShareVersionsFn',
|
|
79
|
+
// 分享页版本数据(分享链接语义)
|
|
80
|
+
'getShareVersionDataFn',
|
|
81
|
+
// 分享页评论读取:属主与通过门禁的分享访客(含未登录)可读,handler 内
|
|
82
|
+
// getCurrentSession 软鉴权(isOwner/email 掩码分支依赖可选 session)
|
|
83
|
+
'listCommentsFn',
|
|
84
|
+
// 设计详情/预览卡:未登录返回 { error: 'unauthorized' } 软响应而非抛错
|
|
85
|
+
// (客户端依赖软契约),handler 内 getCurrentSession 判定
|
|
86
|
+
'getDesignDetailFn',
|
|
87
|
+
'getDesignPreviewFn',
|
|
88
|
+
// GitHub 连接状态探测:未登录返回 { connected: false } 软响应(UI 状态卡
|
|
89
|
+
// 直接消费,未登录不抛 401),handler 内 getCurrentSession 判定
|
|
90
|
+
'getGithubConnectionFn',
|
|
91
|
+
// 版本分享读取:SEC-18 越权防护在 handler 内(须关联有效 ACTIVE share),
|
|
92
|
+
// 公开访问语义不变:不强制登录
|
|
93
|
+
'getVersionShareFn',
|
|
94
|
+
// 公开合规页:visibility=public 过滤在查询内
|
|
95
|
+
'getPublicComplianceFn',
|
|
96
|
+
// 公开法务页:visibility=public 过滤在查询内
|
|
97
|
+
'getPublicLegalFn',
|
|
98
|
+
// 分享页 presence ticket:share token 是信任锚,匿名访客发 guest 身份
|
|
99
|
+
// (有登录 session 则标 member);密码态由 verifyShareGatePassword 在
|
|
100
|
+
// handler 内复验 + IP 频控(checkAuthRateLimit)防滥用
|
|
101
|
+
'createSharePresenceTicketFn',
|
|
102
|
+
|
|
103
|
+
// ── UI 状态(无用户数据)──
|
|
104
|
+
// 只读 sidebar_state UI cookie,无用户数据,SSR 首屏未登录即调用
|
|
105
|
+
'getSidebarStateFn',
|
|
106
|
+
// 账户设置页初始化读取:handler 内 getCurrentSession 软鉴权,未登录返回
|
|
107
|
+
// { error: 'unauthorized' } 软契约(客户端按 error 字段分支,不抛 401)
|
|
108
|
+
'getAccountTeamFn',
|
|
109
|
+
|
|
110
|
+
// ── 团队邀请 token 流程(team.ts,任务 6 迁移后保留公开)──
|
|
111
|
+
// 邀请接受页按 token 查询邀请信息(token 是信任锚)
|
|
112
|
+
'getTeamInvitationByTokenFn',
|
|
113
|
+
// 邀请流程邮箱注册探测:绑定有效邀请 token + IP 限流(审计 A5x-5)
|
|
114
|
+
'checkInviteEmailRegisteredFn',
|
|
115
|
+
// 邀请申请提交(token 流程,未登录场景)
|
|
116
|
+
'applyTeamInvitationFn',
|
|
117
|
+
] as const
|
|
@@ -21,7 +21,6 @@ import type { AvatarConfig } from "@allbluecn/kernel";
|
|
|
21
21
|
import type { StoryState, StoryPriority } from "@/shared/story/constants";
|
|
22
22
|
import type { StoryDetail } from "@/shared/story/types";
|
|
23
23
|
import type {
|
|
24
|
-
UserBrief,
|
|
25
24
|
ReactionGroup,
|
|
26
25
|
ActivityItem,
|
|
27
26
|
} from "@/shared/story/types";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
3
|
+
import type { PrismaClient } from '@allbluecn/database'
|
|
4
|
+
|
|
5
|
+
import { resolveSyncScopes } from '../scopes'
|
|
6
|
+
|
|
7
|
+
// prisma 为参数注入(非模块单例),直接传 mock,无需 vi.mock('@allbluecn/database')
|
|
8
|
+
type PrismaMock = {
|
|
9
|
+
workspace: { findMany: ReturnType<typeof vi.fn> }
|
|
10
|
+
workspaceMember: { findMany: ReturnType<typeof vi.fn> }
|
|
11
|
+
projectMember: { findMany: ReturnType<typeof vi.fn> }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function makePrismaMock(): PrismaMock {
|
|
15
|
+
return {
|
|
16
|
+
workspace: { findMany: vi.fn() },
|
|
17
|
+
workspaceMember: { findMany: vi.fn() },
|
|
18
|
+
projectMember: { findMany: vi.fn() },
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 逐字钉死 guest userId 契约(与 desktop-guest.GUEST_USER_ID 同值)
|
|
23
|
+
const GUEST = 'local-guest'
|
|
24
|
+
|
|
25
|
+
describe('resolveSyncScopes', () => {
|
|
26
|
+
let prismaMock: PrismaMock
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
prismaMock = makePrismaMock()
|
|
30
|
+
// 默认空结果:守卫缺失时 guest 路径仍可走完聚合并返回 user:<id>,RED 为纯断言失败
|
|
31
|
+
prismaMock.workspace.findMany.mockResolvedValue([])
|
|
32
|
+
prismaMock.workspaceMember.findMany.mockResolvedValue([])
|
|
33
|
+
prismaMock.projectMember.findMany.mockResolvedValue([])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('guest 会话返回空 scope,且三个归属查询零调用(guest 数据永不上云)', async () => {
|
|
37
|
+
const scopes = await resolveSyncScopes(prismaMock as unknown as PrismaClient, GUEST)
|
|
38
|
+
expect(scopes).toEqual([])
|
|
39
|
+
expect(prismaMock.workspace.findMany).not.toHaveBeenCalled()
|
|
40
|
+
expect(prismaMock.workspaceMember.findMany).not.toHaveBeenCalled()
|
|
41
|
+
expect(prismaMock.projectMember.findMany).not.toHaveBeenCalled()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('非 guest 用户正常解析:三查询被调,聚出含 user:<id> 的键集', async () => {
|
|
45
|
+
prismaMock.workspace.findMany.mockResolvedValue([{ id: 'ws-owned' }])
|
|
46
|
+
prismaMock.workspaceMember.findMany.mockResolvedValue([{ workspaceId: 'ws-joined' }])
|
|
47
|
+
prismaMock.projectMember.findMany.mockResolvedValue([{ projectId: 'p1' }])
|
|
48
|
+
|
|
49
|
+
const scopes = await resolveSyncScopes(prismaMock as unknown as PrismaClient, 'u1')
|
|
50
|
+
expect(scopes).toEqual(expect.arrayContaining(['user:u1', 'ws-owned', 'ws-joined', 'p1']))
|
|
51
|
+
expect(prismaMock.workspace.findMany).toHaveBeenCalledWith({
|
|
52
|
+
where: { ownerId: 'u1' },
|
|
53
|
+
select: { id: true },
|
|
54
|
+
})
|
|
55
|
+
expect(prismaMock.workspaceMember.findMany).toHaveBeenCalledWith({
|
|
56
|
+
where: { userId: 'u1' },
|
|
57
|
+
select: { workspaceId: true },
|
|
58
|
+
})
|
|
59
|
+
expect(prismaMock.projectMember.findMany).toHaveBeenCalledWith({
|
|
60
|
+
where: { userId: 'u1' },
|
|
61
|
+
select: { projectId: true },
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -7,12 +7,19 @@
|
|
|
7
7
|
// (防越权枚举)。sync_change_log.scope 的键空间与此一一对应。
|
|
8
8
|
import type { PrismaClient } from "@allbluecn/database";
|
|
9
9
|
|
|
10
|
+
import { GUEST_USER_ID } from "../desktop-guest";
|
|
11
|
+
|
|
10
12
|
export type SyncScopes = { workspaces: string[]; projects: string[]; self: string };
|
|
11
13
|
|
|
12
14
|
export async function resolveSyncScopes(
|
|
13
15
|
prisma: PrismaClient,
|
|
14
16
|
userId: string,
|
|
15
17
|
): Promise<string[]> {
|
|
18
|
+
// guest 数据永不上云(安全红线):guest 会话返回空 scope,pull/push/snapshot
|
|
19
|
+
// 对空键集双双空转,本地变更永不写出设备——与桌面端引擎「无云会话不
|
|
20
|
+
// trigger」构成双向防御。
|
|
21
|
+
if (userId === GUEST_USER_ID) return [];
|
|
22
|
+
|
|
16
23
|
const [ownedWorkspaces, joinedWorkspaces, joinedProjects] = await Promise.all([
|
|
17
24
|
prisma.workspace.findMany({ where: { ownerId: userId }, select: { id: true } }),
|
|
18
25
|
prisma.workspaceMember.findMany({ where: { userId }, select: { workspaceId: true } }),
|
|
@@ -124,27 +124,59 @@ vi.mock("../run-webhook", () => ({
|
|
|
124
124
|
}));
|
|
125
125
|
// serverFn 测试桩(照 bug-crud.test.ts 惯例):确认闸门 serverFn 走真实 zod 校验
|
|
126
126
|
vi.mock("@tanstack/react-start", () => ({
|
|
127
|
-
createServerFn: () => {
|
|
128
|
-
const api: {
|
|
129
|
-
_validator?: { parse: (d: unknown) => unknown };
|
|
130
|
-
validator(schema: { parse: (d: unknown) => unknown }): unknown;
|
|
131
|
-
handler(fn: (args: { data: unknown }) => unknown): (args: { data: unknown }) => unknown;
|
|
132
|
-
} = {
|
|
127
|
+
createServerFn: (config: any) => {
|
|
128
|
+
const api: any = {
|
|
133
129
|
_validator: undefined,
|
|
134
|
-
|
|
130
|
+
_middlewares: [] as any[],
|
|
131
|
+
middleware(mws: any[]) {
|
|
132
|
+
this._middlewares.push(...mws);
|
|
133
|
+
return this;
|
|
134
|
+
},
|
|
135
|
+
validator(schema: any) {
|
|
135
136
|
this._validator = schema;
|
|
136
137
|
return this;
|
|
137
138
|
},
|
|
138
|
-
handler(fn) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
handler(fn: Function) {
|
|
140
|
+
const wrapped = async (args: any) => {
|
|
141
|
+
let data = args?.data;
|
|
142
|
+
if (this._validator && data !== undefined) {
|
|
143
|
+
data = this._validator.parse ? this._validator.parse(data) : data;
|
|
144
|
+
}
|
|
145
|
+
// 迁移后经 .middleware([authContextMiddleware]) 注入 context.user:
|
|
146
|
+
// mock 依序执行 middleware 的 server 段(复现框架 executeMiddleware 的
|
|
147
|
+
// context 合并语义),真实鉴权链由被 mock 的 auth-helpers/getRequest 承接
|
|
148
|
+
let context: any = {};
|
|
149
|
+
for (const mw of this._middlewares) {
|
|
150
|
+
const serverFn = mw?.options?.server;
|
|
151
|
+
if (!serverFn) continue;
|
|
152
|
+
const result = await serverFn({
|
|
153
|
+
data,
|
|
154
|
+
context,
|
|
155
|
+
method: 'POST',
|
|
156
|
+
serverFnMeta: {},
|
|
157
|
+
signal: new AbortController().signal,
|
|
158
|
+
next: async (inner: any) => ({ context: { ...context, ...(inner?.context ?? {}) } }),
|
|
159
|
+
});
|
|
160
|
+
context = result.context;
|
|
161
|
+
}
|
|
162
|
+
return fn({ data, context });
|
|
143
163
|
};
|
|
164
|
+
return wrapped;
|
|
144
165
|
},
|
|
145
166
|
};
|
|
146
167
|
return api;
|
|
147
168
|
},
|
|
169
|
+
// auth-context.ts 依赖 createMiddleware({ type: 'function' }).server(fn):
|
|
170
|
+
// mock 产出与真实 middleware 同构的 { options: { server } } 形状,
|
|
171
|
+
// 供上方 handler 包装器执行 server 段注入 context.user
|
|
172
|
+
createMiddleware: (opts: any) => {
|
|
173
|
+
const mw: any = { options: { type: opts?.type } };
|
|
174
|
+
mw.server = (fn: Function) => {
|
|
175
|
+
mw.options.server = fn;
|
|
176
|
+
return mw;
|
|
177
|
+
};
|
|
178
|
+
return mw;
|
|
179
|
+
},
|
|
148
180
|
}));
|
|
149
181
|
vi.mock("@tanstack/react-start/server", () => ({ getRequest: () => ({}) }));
|
|
150
182
|
vi.mock("@/server/auth-helpers", () => ({
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"latency": {
|
|
3
|
-
"aad": 0.048410276139197045,
|
|
4
|
-
"critical": 1.96,
|
|
5
|
-
"df": 1059,
|
|
6
|
-
"mad": 0.022145999999793275,
|
|
7
|
-
"max": 3.373666999999841,
|
|
8
|
-
"mean": 0.94407134433964,
|
|
9
|
-
"min": 0.8770409999997355,
|
|
10
|
-
"moe": 0.007457128456580703,
|
|
11
|
-
"p50": 0.9219379999999546,
|
|
12
|
-
"p75": 0.9482297500001096,
|
|
13
|
-
"p99": 1.549765560000042,
|
|
14
|
-
"p995": 1.6288096400004497,
|
|
15
|
-
"p999": 1.8190369999991707,
|
|
16
|
-
"rme": 0.7898903511150234,
|
|
17
|
-
"samplesCount": 1060,
|
|
18
|
-
"sd": 0.12387066970076242,
|
|
19
|
-
"sem": 0.0038046573758064813,
|
|
20
|
-
"variance": 0.015343942812115383
|
|
21
|
-
},
|
|
22
|
-
"throughput": {
|
|
23
|
-
"aad": 43.792207103583756,
|
|
24
|
-
"critical": 1.96,
|
|
25
|
-
"df": 1059,
|
|
26
|
-
"mad": 25.941182125708224,
|
|
27
|
-
"max": 1140.1975506279657,
|
|
28
|
-
"mean": 1068.8147818211185,
|
|
29
|
-
"min": 296.4133685986338,
|
|
30
|
-
"moe": 4.749020957923807,
|
|
31
|
-
"p50": 1084.6716379180502,
|
|
32
|
-
"p75": 1108.6600489500372,
|
|
33
|
-
"p99": 1137.598277984184,
|
|
34
|
-
"p995": 1138.8284369378687,
|
|
35
|
-
"p999": 1140.1930292151646,
|
|
36
|
-
"rme": 0.4443259055448416,
|
|
37
|
-
"samplesCount": 1060,
|
|
38
|
-
"sd": 78.88618385832574,
|
|
39
|
-
"sem": 2.422969876491738,
|
|
40
|
-
"variance": 6223.030003729573
|
|
41
|
-
},
|
|
42
|
-
"period": 0.9440713443396405,
|
|
43
|
-
"totalTime": 1000.7156250000189
|
|
44
|
-
}
|
package/src/__typeprobe__.d.ts
DELETED