@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.
Files changed (500) hide show
  1. package/package.json +4 -14
  2. package/src/__tests__/integration/login-email-acceptance.test.ts +16 -0
  3. package/src/__tests__/story-view.test.ts +33 -1
  4. package/src/components/agents/__tests__/agent-bindings-tab.test.tsx +221 -0
  5. package/src/components/agents/__tests__/agents-page.test.tsx +284 -0
  6. package/src/components/agents/agent-bindings-tab.tsx +59 -45
  7. package/src/components/agents/agent-form-dialog.tsx +3 -3
  8. package/src/components/agents/agent-selector.tsx +2 -3
  9. package/src/components/agents/agents-page.tsx +66 -31
  10. package/src/components/agents/slash-skill-menu.tsx +2 -3
  11. package/src/components/auth/__tests__/session-guard.test.tsx +74 -0
  12. package/src/components/auth/session-guard.tsx +8 -0
  13. package/src/components/billing/login-prompt-dialog.tsx +1 -1
  14. package/src/components/billing/subscription-provider.tsx +2 -16
  15. package/src/components/bug/__tests__/peek-modes.test.tsx +8 -0
  16. package/src/components/bug/__tests__/subgroup-header.test.tsx +202 -40
  17. package/src/components/bug/peek-panel.tsx +5 -3
  18. package/src/components/bug/views/bug-list/group.tsx +12 -2
  19. package/src/components/bug/views/bug-list/index.tsx +94 -67
  20. package/src/components/command/command-palette.tsx +10 -9
  21. package/src/components/design/canvas/document/frame-custom-presets.ts +9 -1
  22. package/src/components/design/canvas/panels/toolbar.tsx +21 -22
  23. package/src/components/design/canvas/react/__tests__/canvas-context-load-echo.test.tsx +199 -0
  24. package/src/components/design/canvas/react/__tests__/hooks.test.tsx +17 -3
  25. package/src/components/design/canvas/react/canvas-context.tsx +47 -26
  26. package/src/components/design/canvas/react/hooks.ts +39 -34
  27. package/src/components/design/editor/layout/__tests__/collab-param-wiring.test.tsx +17 -0
  28. package/src/components/design/editor/layout/__tests__/context-menu.test.tsx +17 -1
  29. package/src/components/design/editor/layout/__tests__/no-page-save-toast.test.tsx +17 -0
  30. package/src/components/design/editor/layout/__tests__/persistence-restore.test.tsx +17 -1
  31. package/src/components/design/editor/layout/__tests__/ssr-localstorage-smoke.test.tsx +17 -1
  32. package/src/components/design/editor/layout/design-editor-layout.tsx +13 -2
  33. package/src/components/design/editor/layout/hooks/use-design-auto-save.ts +3 -19
  34. package/src/components/devtools/devtools-panel.tsx +56 -0
  35. package/src/components/forms/__tests__/create-app-form.test.tsx +131 -0
  36. package/src/components/forms/app-field-error.tsx +21 -1
  37. package/src/components/forms/app-field.tsx +8 -8
  38. package/src/components/forms/app-submit.tsx +12 -9
  39. package/src/components/forms/create-app-form.tsx +124 -0
  40. package/src/components/forms/index.ts +2 -3
  41. package/src/components/harness/__tests__/gallery-behavior.test.tsx +37 -1
  42. package/src/components/harness/__tests__/harness-workbench-first-send.test.tsx +4 -1
  43. package/src/components/harness/__tests__/message-actions.test.tsx +7 -6
  44. package/src/components/harness/__tests__/use-video-generation.test.tsx +165 -0
  45. package/src/components/harness/ai-chat-history/index.tsx +5 -3
  46. package/src/components/harness/gallery/gallery-card.tsx +57 -35
  47. package/src/components/harness/gallery/gallery-grid.tsx +32 -15
  48. package/src/components/harness/gallery/gallery-types.ts +19 -0
  49. package/src/components/harness/gallery/gallery-video-card.tsx +54 -0
  50. package/src/components/harness/gallery/types.ts +2 -0
  51. package/src/components/harness/gallery/use-video-generation.ts +95 -0
  52. package/src/components/harness/harness-workbench-page.tsx +2 -3
  53. package/src/components/harness/message-actions.tsx +5 -3
  54. package/src/components/hotkeys/shortcuts-panel.tsx +28 -13
  55. package/src/components/iteration/__tests__/burndown-chart.test.tsx +118 -0
  56. package/src/components/iteration/burndown-chart.tsx +54 -23
  57. package/src/components/knowledge/editor/__tests__/knowledge-doc-editor-collab.test.tsx +96 -0
  58. package/src/components/knowledge/editor/knowledge-doc-editor.tsx +56 -1
  59. package/src/components/knowledge/editor/mindmap-doc-editor.tsx +12 -0
  60. package/src/components/knowledge/editor/use-auto-save-channels.ts +3 -1
  61. package/src/components/layout/sidebar-03/__tests__/nav-workspace.test.tsx +0 -4
  62. package/src/components/layout/sidebar-03/nav-knowledge.tsx +11 -11
  63. package/src/components/layout/sidebar-03/nav-main.tsx +12 -15
  64. package/src/components/layout/sidebar-03/nav-notifications.tsx +5 -8
  65. package/src/components/layout/sidebar-03/nav-workspace.tsx +11 -9
  66. package/src/components/notifications/__tests__/settings-notifications.test.tsx +158 -0
  67. package/src/components/notifications/settings-notifications.tsx +37 -13
  68. package/src/components/notifications/team-notifications.tsx +10 -14
  69. package/src/components/settings/personal-team/account/__tests__/account-client.test.tsx +170 -0
  70. package/src/components/settings/personal-team/account/account-client.tsx +44 -7
  71. package/src/components/settings/personal-team/team/team-client.tsx +17 -19
  72. package/src/components/shared-kit/list-kit/__tests__/frozen-header.test.ts +210 -41
  73. package/src/components/shared-kit/list-kit/frozen-header.ts +134 -21
  74. package/src/components/shared-kit/list-kit/kanban/frozen-header.ts +20 -27
  75. package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +8 -0
  76. package/src/components/story/__tests__/story-list-table.test.tsx +214 -0
  77. package/src/components/story/columns.tsx +11 -2
  78. package/src/components/story/peek-panel.tsx +4 -2
  79. package/src/components/story/story-list-table.tsx +16 -1
  80. package/src/components/story/views/story-list/__tests__/frozen-headers.test.tsx +186 -0
  81. package/src/components/story/views/story-list/group.tsx +12 -1
  82. package/src/components/story/views/story-list/index.tsx +101 -68
  83. package/src/components/testcase/__tests__/case-row.test.tsx +134 -2
  84. package/src/components/testcase/__tests__/peek-panel.test.tsx +8 -0
  85. package/src/components/testcase/__tests__/step-editor.test.tsx +106 -0
  86. package/src/components/testcase/list/grouped-list.tsx +50 -22
  87. package/src/components/testcase/peek-panel.tsx +7 -4
  88. package/src/components/testcase/step-editor.tsx +196 -150
  89. package/src/components/tiptap/notion-like/editor-extensions.ts +0 -3
  90. package/src/components/tiptap/notion-like/notion-like-editor-header.tsx +1 -31
  91. package/src/components/tiptap/notion-like/notion-like-editor.tsx +32 -1
  92. package/src/components/workspace/__tests__/dialogs/create-workspace-dialog.test.tsx +2 -28
  93. package/src/components/workspace/__tests__/dialogs/edit-workspace-dialog.test.tsx +2 -28
  94. package/src/components/workspace/dialogs/create-workspace-dialog.tsx +45 -43
  95. package/src/components/workspace/dialogs/edit-workspace-dialog.tsx +38 -36
  96. package/src/design-engine/engine/engine-decor.ts +2 -0
  97. package/src/design-engine/engine/engine-path.ts +2 -0
  98. package/src/hooks/__tests__/use-unsaved-guard.test.tsx +180 -0
  99. package/src/hooks/use-notifications.ts +9 -16
  100. package/src/hooks/use-unsaved-guard.tsx +87 -0
  101. package/src/lib/__tests__/pacer.test.ts +33 -96
  102. package/src/lib/__tests__/query-defaults.test.ts +169 -0
  103. package/src/lib/__tests__/query-global-error.test.ts +256 -0
  104. package/src/lib/anyhub/anyhub-store.ts +2 -2
  105. package/src/lib/changelog/sdk-versions.ts +2 -10
  106. package/src/lib/collab/presence-store.ts +5 -5
  107. package/src/lib/collab/use-presence-list-refresh.ts +2 -2
  108. package/src/lib/collab/use-share-presence.ts +2 -2
  109. package/src/lib/collections/query-keys.ts +7 -2
  110. package/src/lib/commands/__tests__/command-palette-state.test.ts +12 -14
  111. package/src/lib/commands/__tests__/registry.test.ts +6 -3
  112. package/src/lib/commands/command-palette-state.ts +8 -31
  113. package/src/lib/hotkeys/__tests__/registry.test.ts +71 -18
  114. package/src/lib/hotkeys/registry.ts +188 -85
  115. package/src/lib/hotkeys/types.ts +1 -13
  116. package/src/lib/pacer.ts +1 -79
  117. package/src/lib/queries/README.md +67 -0
  118. package/src/lib/queries/__tests__/agents-queries.test.ts +101 -0
  119. package/src/lib/queries/__tests__/compliance-queries.test.ts +136 -0
  120. package/src/lib/queries/__tests__/notifications-queries.test.ts +175 -0
  121. package/src/lib/queries/__tests__/team-queries.test.ts +87 -0
  122. package/src/lib/queries/agents.ts +40 -0
  123. package/src/lib/queries/compliance.ts +69 -0
  124. package/src/lib/queries/notifications.ts +63 -0
  125. package/src/lib/queries/team.ts +39 -0
  126. package/src/lib/query-defaults.ts +8 -0
  127. package/src/lib/query-global-error.ts +128 -0
  128. package/src/lib/remote-auth-client.ts +16 -0
  129. package/src/paraglide/README.md +1 -1
  130. package/src/paraglide/messages/_index.d.ts +11 -0
  131. package/src/paraglide/messages/_index.js +5659 -88285
  132. package/src/paraglide/messages/common_error_generic.d.ts +16 -0
  133. package/src/paraglide/messages/common_error_generic.js +29 -0
  134. package/src/paraglide/messages/common_unsaved_body.d.ts +16 -0
  135. package/src/paraglide/messages/common_unsaved_body.js +29 -0
  136. package/src/paraglide/messages/common_unsaved_leave.d.ts +16 -0
  137. package/src/paraglide/messages/common_unsaved_leave.js +29 -0
  138. package/src/paraglide/messages/common_unsaved_stay.d.ts +16 -0
  139. package/src/paraglide/messages/common_unsaved_stay.js +29 -0
  140. package/src/paraglide/messages/common_unsaved_title.d.ts +16 -0
  141. package/src/paraglide/messages/common_unsaved_title.js +29 -0
  142. package/src/paraglide/messages/gallery_videofailed1.d.ts +17 -0
  143. package/src/paraglide/messages/gallery_videofailed1.js +30 -0
  144. package/src/paraglide/messages/gallery_videogenerating1.d.ts +17 -0
  145. package/src/paraglide/messages/gallery_videogenerating1.js +30 -0
  146. package/src/paraglide/messages/gallery_videomissingprompt2.d.ts +17 -0
  147. package/src/paraglide/messages/gallery_videomissingprompt2.js +30 -0
  148. package/src/paraglide/messages/gallery_videoprogress1.d.ts +19 -0
  149. package/src/paraglide/messages/gallery_videoprogress1.js +30 -0
  150. package/src/paraglide/messages/gallery_videostop1.d.ts +17 -0
  151. package/src/paraglide/messages/gallery_videostop1.js +30 -0
  152. package/src/paraglide/messages/story_table_resizecolumn1.d.ts +17 -0
  153. package/src/paraglide/messages/story_table_resizecolumn1.js +30 -0
  154. package/src/providers/index.tsx +5 -50
  155. package/src/routeTree.gen.ts +21 -0
  156. package/src/router.tsx +21 -8
  157. package/src/routes/__root.tsx +2 -1
  158. package/src/routes/__tests__/-edition-routing.test.tsx +6 -1
  159. package/src/routes/_login/forgot-password/route.lazy.tsx +7 -6
  160. package/src/routes/_login/login/route.lazy.tsx +10 -9
  161. package/src/routes/_login/register/route.lazy.tsx +19 -18
  162. package/src/routes/_login/reset-password/route.lazy.tsx +10 -9
  163. package/src/routes/_nav/knowledge/compliance/$id.lazy.tsx +9 -12
  164. package/src/routes/_nav/knowledge/compliance/index.lazy.tsx +16 -13
  165. package/src/routes/_nav/knowledge/laws/$id.lazy.tsx +1 -1
  166. package/src/routes/_nav/notifications/route.tsx +6 -16
  167. package/src/routes/_nav/settings/-settings-tabs.tsx +9 -12
  168. package/src/routes/api/generate/__tests__/media.test.ts +378 -0
  169. package/src/routes/api/generate/media.ts +179 -0
  170. package/src/server/__tests__/agent-client-graph.test.ts +0 -1
  171. package/src/server/__tests__/agent-crud.test.ts +37 -4
  172. package/src/server/__tests__/bug-groups-two-level.test.ts +34 -1
  173. package/src/server/__tests__/chat-conversations.test.ts +37 -4
  174. package/src/server/__tests__/chat-list-messages.test.ts +40 -7
  175. package/src/server/__tests__/csv-export.test.ts +36 -3
  176. package/src/server/__tests__/desktop-bootstrap.test.ts +189 -0
  177. package/src/server/__tests__/remote-auth.test.ts +72 -0
  178. package/src/server/__tests__/skill-crud.test.ts +37 -4
  179. package/src/server/__tests__/sso-domain.test.ts +1 -1
  180. package/src/server/__tests__/sso-rate-limit-singleton.test.ts +123 -0
  181. package/src/server/__tests__/task-serverfn-crud.test.ts +35 -2
  182. package/src/server/__tests__/task-serverfn-queries.test.ts +35 -2
  183. package/src/server/__tests__/testcase-board.test.ts +38 -5
  184. package/src/server/__tests__/testcase-bulk.test.ts +38 -5
  185. package/src/server/__tests__/testcase-list-scope.test.ts +38 -5
  186. package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +126 -2
  187. package/src/server/ai-gateway/__tests__/chat-stream-builder-code-mode.test.ts +4 -0
  188. package/src/server/ai-gateway/__tests__/chat-stream-builder-memory.test.ts +4 -0
  189. package/src/server/ai-gateway/__tests__/chat-stream-builder-sandbox.test.ts +4 -0
  190. package/src/server/ai-gateway/__tests__/chat-stream-builder-skills.test.ts +4 -0
  191. package/src/server/ai-gateway/__tests__/pgvector-memory-adapter.test.ts +30 -0
  192. package/src/server/ai-gateway/__tests__/pgvector-memory-conformance.test.ts +92 -0
  193. package/src/server/ai-gateway/__tests__/source-mode.test.ts +49 -8
  194. package/src/server/ai-gateway/ai-output-guard.ts +50 -2
  195. package/src/server/ai-gateway/chat-stream-builder.ts +3 -0
  196. package/src/server/ai-gateway/media/index.ts +36 -29
  197. package/src/server/ai-gateway/media/trim-input.ts +52 -0
  198. package/src/server/ai-gateway/memory/pgvector-adapter.ts +27 -13
  199. package/src/server/ai-gateway/sandbox/__tests__/harness-sandbox.test.ts +252 -41
  200. package/src/server/ai-gateway/sandbox/harness-sandbox.ts +6 -67
  201. package/src/server/ai-gateway/source-mode.ts +24 -8
  202. package/src/server/desktop-bootstrap.ts +74 -0
  203. package/src/server/lib/__tests__/rate-limit.test.ts +0 -1
  204. package/src/server/lib/rate-limit.ts +0 -2
  205. package/src/server/middlewares/__tests__/auth-context.test.ts +156 -0
  206. package/src/server/middlewares/auth-context.ts +62 -0
  207. package/src/server/remote-auth.ts +58 -31
  208. package/src/server/serverFns/__tests__/ai-hosted-models.test.ts +47 -15
  209. package/src/server/serverFns/__tests__/ai-source-mode.test.ts +45 -15
  210. package/src/server/serverFns/__tests__/billing.test.ts +37 -2
  211. package/src/server/serverFns/__tests__/collab-snapshot.test.ts +41 -14
  212. package/src/server/serverFns/__tests__/collab.test.ts +41 -14
  213. package/src/server/serverFns/__tests__/compliance.test.ts +33 -1
  214. package/src/server/serverFns/__tests__/email-verification.test.ts +35 -1
  215. package/src/server/serverFns/__tests__/knowledge-breadcrumb.test.ts +46 -6
  216. package/src/server/serverFns/__tests__/knowledge-delete.test.ts +42 -14
  217. package/src/server/serverFns/__tests__/knowledge-kb-projects.test.ts +46 -6
  218. package/src/server/serverFns/__tests__/knowledge-public-compliance.test.ts +36 -2
  219. package/src/server/serverFns/__tests__/knowledge-readable-kb.test.ts +42 -10
  220. package/src/server/serverFns/__tests__/knowledge-search.test.ts +45 -9
  221. package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +36 -2
  222. package/src/server/serverFns/__tests__/link-preview.test.ts +38 -4
  223. package/src/server/serverFns/__tests__/notifications-list.test.ts +36 -3
  224. package/src/server/serverFns/__tests__/ownership-merge.test.ts +38 -4
  225. package/src/server/serverFns/__tests__/project-delete-transaction.test.ts +39 -2
  226. package/src/server/serverFns/__tests__/project-kb.test.ts +34 -1
  227. package/src/server/serverFns/__tests__/project-member-idor.test.ts +34 -1
  228. package/src/server/serverFns/__tests__/project-team-assign.test.ts +34 -1
  229. package/src/server/serverFns/__tests__/read-write-merge.test.ts +38 -4
  230. package/src/server/serverFns/__tests__/story-comments.test.ts +38 -4
  231. package/src/server/serverFns/__tests__/story-crud-archive-detail.test.ts +38 -4
  232. package/src/server/serverFns/__tests__/story-crud-labels-users.test.ts +37 -3
  233. package/src/server/serverFns/__tests__/story-crud.test.ts +36 -3
  234. package/src/server/serverFns/__tests__/story-links.test.ts +38 -4
  235. package/src/server/serverFns/__tests__/story-reactions.test.ts +38 -4
  236. package/src/server/serverFns/__tests__/story-tree.test.ts +38 -4
  237. package/src/server/serverFns/__tests__/team-accept.test.ts +34 -1
  238. package/src/server/serverFns/__tests__/team-invitation.test.ts +34 -1
  239. package/src/server/serverFns/__tests__/team-join-request.test.ts +34 -1
  240. package/src/server/serverFns/__tests__/team-members.test.ts +34 -1
  241. package/src/server/serverFns/__tests__/team-ownership-merge.test.ts +34 -1
  242. package/src/server/serverFns/__tests__/update-bug-guard.test.ts +37 -3
  243. package/src/server/serverFns/__tests__/update-document-guard.test.ts +38 -4
  244. package/src/server/serverFns/__tests__/update-page-guard.test.ts +40 -4
  245. package/src/server/serverFns/__tests__/update-seats.test.ts +33 -1
  246. package/src/server/serverFns/__tests__/update-story-guard.test.ts +36 -3
  247. package/src/server/serverFns/__tests__/update-testcase-guard.test.ts +37 -3
  248. package/src/server/serverFns/__tests__/workspace-kb-idor.test.ts +36 -2
  249. package/src/server/serverFns/__tests__/workspace-kb.test.ts +36 -2
  250. package/src/server/serverFns/__tests__/workspace.test.ts +34 -1
  251. package/src/server/serverFns/activity.ts +10 -14
  252. package/src/server/serverFns/agents/agent-crud.ts +16 -15
  253. package/src/server/serverFns/agents/bindings.ts +12 -13
  254. package/src/server/serverFns/agents/skill-crud.ts +16 -15
  255. package/src/server/serverFns/ai/code-mode-readiness.ts +3 -4
  256. package/src/server/serverFns/ai/search-capability.ts +3 -4
  257. package/src/server/serverFns/anyhub/app.ts +10 -14
  258. package/src/server/serverFns/anyhub/index.ts +7 -10
  259. package/src/server/serverFns/anyhub/install.ts +4 -4
  260. package/src/server/serverFns/anyhub/permissions.ts +10 -14
  261. package/src/server/serverFns/anyhub/proxy.ts +4 -6
  262. package/src/server/serverFns/auth/email-verification.ts +4 -5
  263. package/src/server/serverFns/auth/session.ts +9 -0
  264. package/src/server/serverFns/billing.ts +18 -28
  265. package/src/server/serverFns/blob-upload.ts +6 -9
  266. package/src/server/serverFns/bug/__tests__/bug-access-tokens.test.ts +34 -1
  267. package/src/server/serverFns/bug/__tests__/bug-activities.test.ts +34 -1
  268. package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +34 -1
  269. package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +34 -1
  270. package/src/server/serverFns/bug/__tests__/bug-fix.test.ts +34 -1
  271. package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +34 -1
  272. package/src/server/serverFns/bug/__tests__/bug-reactions.test.ts +34 -1
  273. package/src/server/serverFns/bug/__tests__/bug-reorder.test.ts +39 -5
  274. package/src/server/serverFns/bug/__tests__/bug-repro.test.ts +34 -1
  275. package/src/server/serverFns/bug/__tests__/bug-story.test.ts +34 -1
  276. package/src/server/serverFns/bug/__tests__/bug-webhooks.test.ts +34 -1
  277. package/src/server/serverFns/bug/bug-access-tokens.ts +16 -22
  278. package/src/server/serverFns/bug/bug-activities.ts +4 -6
  279. package/src/server/serverFns/bug/bug-collect-tokens.ts +13 -18
  280. package/src/server/serverFns/bug/bug-comments.ts +13 -18
  281. package/src/server/serverFns/bug/bug-crud/detail.ts +10 -14
  282. package/src/server/serverFns/bug/bug-crud.ts +28 -38
  283. package/src/server/serverFns/bug/bug-display-options.ts +8 -11
  284. package/src/server/serverFns/bug/bug-export.ts +5 -7
  285. package/src/server/serverFns/bug/bug-fix.ts +10 -14
  286. package/src/server/serverFns/bug/bug-groups.ts +10 -14
  287. package/src/server/serverFns/bug/bug-reactions.ts +10 -14
  288. package/src/server/serverFns/bug/bug-reorder.ts +4 -6
  289. package/src/server/serverFns/bug/bug-repro.ts +8 -11
  290. package/src/server/serverFns/bug/bug-story-bulk.ts +13 -18
  291. package/src/server/serverFns/bug/bug-story.ts +10 -14
  292. package/src/server/serverFns/bug/bug-views.ts +12 -18
  293. package/src/server/serverFns/bug/bug-webhooks.ts +13 -18
  294. package/src/server/serverFns/bug/test-bug-confirm.ts +7 -10
  295. package/src/server/serverFns/changelog/__tests__/fetch.test.ts +40 -1
  296. package/src/server/serverFns/changelog/fetch.ts +4 -6
  297. package/src/server/serverFns/chat/conversations.ts +17 -28
  298. package/src/server/serverFns/chat/list-messages.ts +4 -7
  299. package/src/server/serverFns/collab-presence.ts +11 -13
  300. package/src/server/serverFns/collab-snapshot.ts +6 -7
  301. package/src/server/serverFns/collab.ts +7 -7
  302. package/src/server/serverFns/compliance.ts +8 -8
  303. package/src/server/serverFns/design/__tests__/comments.test.ts +54 -10
  304. package/src/server/serverFns/design/__tests__/designs.test.ts +39 -16
  305. package/src/server/serverFns/design/__tests__/page-versions.test.ts +52 -14
  306. package/src/server/serverFns/design/__tests__/shares-password.test.ts +44 -14
  307. package/src/server/serverFns/design/__tests__/shares.test.ts +44 -14
  308. package/src/server/serverFns/design/__tests__/versions.test.ts +44 -14
  309. package/src/server/serverFns/design/ai/__tests__/agent-conversations.test.ts +50 -21
  310. package/src/server/serverFns/design/ai/__tests__/providers.test.ts +42 -8
  311. package/src/server/serverFns/design/ai/agent-conversations.ts +19 -26
  312. package/src/server/serverFns/design/ai/fill-annotation.ts +5 -7
  313. package/src/server/serverFns/design/ai/generate-prototype.ts +5 -7
  314. package/src/server/serverFns/design/ai/hosted-models.ts +4 -5
  315. package/src/server/serverFns/design/ai/providers.ts +30 -39
  316. package/src/server/serverFns/design/ai/source-mode.ts +10 -12
  317. package/src/server/serverFns/design/comments.ts +14 -13
  318. package/src/server/serverFns/design/designs.ts +13 -19
  319. package/src/server/serverFns/design/page-versions.ts +17 -18
  320. package/src/server/serverFns/design/pages.ts +17 -18
  321. package/src/server/serverFns/design/reviews.ts +8 -9
  322. package/src/server/serverFns/design/shares-password.ts +13 -19
  323. package/src/server/serverFns/design/shares.ts +22 -31
  324. package/src/server/serverFns/design/versions.ts +8 -9
  325. package/src/server/serverFns/harness/__tests__/attach-prototype.spec.ts +52 -2
  326. package/src/server/serverFns/harness/__tests__/attach-to-kb.spec.ts +52 -2
  327. package/src/server/serverFns/harness/__tests__/attach-to-story-ssrf.spec.ts +52 -2
  328. package/src/server/serverFns/harness/__tests__/attach-to-story.spec.ts +52 -2
  329. package/src/server/serverFns/harness/__tests__/cancel-run.test.ts +40 -15
  330. package/src/server/serverFns/harness/__tests__/extract-attachment.spec.ts +52 -2
  331. package/src/server/serverFns/harness/__tests__/gallery.spec.ts +76 -12
  332. package/src/server/serverFns/harness/__tests__/github-workspace.spec.ts +38 -6
  333. package/src/server/serverFns/harness/__tests__/media-prototype.spec.ts +50 -6
  334. package/src/server/serverFns/harness/__tests__/media.spec.ts +55 -11
  335. package/src/server/serverFns/harness/__tests__/sandbox-policy.test.ts +41 -16
  336. package/src/server/serverFns/harness/__tests__/workspace-files.test.ts +41 -16
  337. package/src/server/serverFns/harness/attach-prototype.ts +4 -4
  338. package/src/server/serverFns/harness/attach-to-kb.ts +4 -4
  339. package/src/server/serverFns/harness/attach-to-story.ts +4 -4
  340. package/src/server/serverFns/harness/cancel-run.ts +4 -6
  341. package/src/server/serverFns/harness/extract-attachment.ts +3 -4
  342. package/src/server/serverFns/harness/gallery.ts +19 -23
  343. package/src/server/serverFns/harness/github-workspace.ts +14 -21
  344. package/src/server/serverFns/harness/media.ts +18 -117
  345. package/src/server/serverFns/harness/sandbox-policy.ts +11 -10
  346. package/src/server/serverFns/harness/search-mention-candidates.ts +4 -6
  347. package/src/server/serverFns/harness/workspace-files.ts +19 -26
  348. package/src/server/serverFns/iteration/__tests__/iteration-auto-schedule.test.ts +35 -3
  349. package/src/server/serverFns/iteration/__tests__/iteration-crud.test.ts +35 -3
  350. package/src/server/serverFns/iteration/__tests__/iteration-stories.test.ts +35 -3
  351. package/src/server/serverFns/iteration/__tests__/iteration-transfer.test.ts +35 -3
  352. package/src/server/serverFns/iteration/iteration-auto-schedule.ts +7 -10
  353. package/src/server/serverFns/iteration/iteration-burndown.ts +4 -6
  354. package/src/server/serverFns/iteration/iteration-crud.ts +26 -35
  355. package/src/server/serverFns/iteration/iteration-stories.ts +10 -14
  356. package/src/server/serverFns/iteration/iteration-transfer.ts +4 -6
  357. package/src/server/serverFns/knowledge/public/bookmarks/categories.ts +11 -15
  358. package/src/server/serverFns/knowledge/public/bookmarks/create.ts +4 -6
  359. package/src/server/serverFns/knowledge/public/bookmarks/delete.ts +5 -7
  360. package/src/server/serverFns/knowledge/public/bookmarks/detail.ts +4 -6
  361. package/src/server/serverFns/knowledge/public/bookmarks/favorite.ts +4 -6
  362. package/src/server/serverFns/knowledge/public/bookmarks/list.ts +4 -6
  363. package/src/server/serverFns/knowledge/public/bookmarks/refresh-favicon.ts +4 -6
  364. package/src/server/serverFns/knowledge/public/bookmarks/share.ts +4 -6
  365. package/src/server/serverFns/knowledge/public/bookmarks/sync-github.ts +5 -7
  366. package/src/server/serverFns/knowledge/public/bookmarks/unshare.ts +4 -6
  367. package/src/server/serverFns/knowledge/public/bookmarks/update.ts +6 -8
  368. package/src/server/serverFns/knowledge/public/compliance/create.ts +4 -6
  369. package/src/server/serverFns/knowledge/public/compliance/delete.ts +5 -7
  370. package/src/server/serverFns/knowledge/public/compliance/detail.ts +4 -6
  371. package/src/server/serverFns/knowledge/public/compliance/list.ts +4 -6
  372. package/src/server/serverFns/knowledge/public/compliance/share.ts +4 -6
  373. package/src/server/serverFns/knowledge/public/compliance/unshare.ts +4 -6
  374. package/src/server/serverFns/knowledge/public/compliance/update.ts +5 -7
  375. package/src/server/serverFns/knowledge/public/dictionary/create.ts +4 -6
  376. package/src/server/serverFns/knowledge/public/dictionary/delete.ts +5 -7
  377. package/src/server/serverFns/knowledge/public/dictionary/detail.ts +4 -6
  378. package/src/server/serverFns/knowledge/public/dictionary/list.ts +4 -6
  379. package/src/server/serverFns/knowledge/public/dictionary/share.ts +4 -6
  380. package/src/server/serverFns/knowledge/public/dictionary/unshare.ts +4 -6
  381. package/src/server/serverFns/knowledge/public/dictionary/update.ts +5 -7
  382. package/src/server/serverFns/knowledge/public/entity-tags.ts +4 -6
  383. package/src/server/serverFns/knowledge/public/favorite.ts +7 -10
  384. package/src/server/serverFns/knowledge/public/legal/create.ts +4 -6
  385. package/src/server/serverFns/knowledge/public/legal/delete.ts +5 -7
  386. package/src/server/serverFns/knowledge/public/legal/detail.ts +4 -6
  387. package/src/server/serverFns/knowledge/public/legal/list.ts +4 -6
  388. package/src/server/serverFns/knowledge/public/legal/share.ts +4 -6
  389. package/src/server/serverFns/knowledge/public/legal/unshare.ts +4 -6
  390. package/src/server/serverFns/knowledge/public/legal/update.ts +5 -7
  391. package/src/server/serverFns/knowledge-index.ts +12 -16
  392. package/src/server/serverFns/knowledge.ts +50 -67
  393. package/src/server/serverFns/notifications.ts +25 -34
  394. package/src/server/serverFns/plugins/harness-plugins.ts +16 -23
  395. package/src/server/serverFns/project/module-overview.ts +7 -10
  396. package/src/server/serverFns/project.ts +48 -68
  397. package/src/server/serverFns/references/create.ts +4 -6
  398. package/src/server/serverFns/references/resolve.ts +4 -6
  399. package/src/server/serverFns/references/search.ts +4 -6
  400. package/src/server/serverFns/share/design/[designId]/events.ts +4 -6
  401. package/src/server/serverFns/sso.ts +1 -1
  402. package/src/server/serverFns/story/__tests__/bulk.test.ts +34 -1
  403. package/src/server/serverFns/story/__tests__/story-assoc.test.ts +34 -1
  404. package/src/server/serverFns/story/__tests__/story-attachments.test.ts +34 -1
  405. package/src/server/serverFns/story/__tests__/story-crud-date-key.test.ts +42 -17
  406. package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +34 -1
  407. package/src/server/serverFns/story/__tests__/story-gantt-deps.test.ts +34 -1
  408. package/src/server/serverFns/story/__tests__/story-groups.test.ts +34 -1
  409. package/src/server/serverFns/story/__tests__/story-read-path-authz.test.ts +40 -4
  410. package/src/server/serverFns/story/__tests__/story-search.test.ts +34 -1
  411. package/src/server/serverFns/story/__tests__/story-transfer.test.ts +34 -1
  412. package/src/server/serverFns/story/link-preview.ts +5 -7
  413. package/src/server/serverFns/story/story-assoc.ts +28 -38
  414. package/src/server/serverFns/story/story-attachments.ts +7 -10
  415. package/src/server/serverFns/story/story-children.ts +4 -6
  416. package/src/server/serverFns/story/story-comments.ts +13 -18
  417. package/src/server/serverFns/story/story-crud/activities.ts +4 -6
  418. package/src/server/serverFns/story/story-crud/archive.ts +7 -10
  419. package/src/server/serverFns/story/story-crud/bulk.ts +10 -14
  420. package/src/server/serverFns/story/story-crud/detail.ts +7 -10
  421. package/src/server/serverFns/story/story-crud/label-suggest.ts +4 -6
  422. package/src/server/serverFns/story/story-crud/labels.ts +6 -9
  423. package/src/server/serverFns/story/story-crud/user-brief.ts +4 -6
  424. package/src/server/serverFns/story/story-crud.ts +13 -18
  425. package/src/server/serverFns/story/story-dependencies.ts +16 -22
  426. package/src/server/serverFns/story/story-groups.ts +10 -14
  427. package/src/server/serverFns/story/story-links.ts +13 -18
  428. package/src/server/serverFns/story/story-reactions.ts +13 -18
  429. package/src/server/serverFns/story/story-search.ts +7 -10
  430. package/src/server/serverFns/story/story-transfer.ts +10 -14
  431. package/src/server/serverFns/story/story-tree.ts +7 -10
  432. package/src/server/serverFns/story-display-options.ts +7 -8
  433. package/src/server/serverFns/story-view.ts +12 -18
  434. package/src/server/serverFns/tasks/task-crud.ts +13 -17
  435. package/src/server/serverFns/tasks/task-queries.ts +12 -18
  436. package/src/server/serverFns/team.ts +46 -66
  437. package/src/server/serverFns/testcase/__tests__/automation.test.ts +38 -5
  438. package/src/server/serverFns/testcase/__tests__/evidence-upload.test.ts +37 -3
  439. package/src/server/serverFns/testcase/__tests__/generation.test.ts +38 -5
  440. package/src/server/serverFns/testcase/__tests__/plans.test.ts +36 -3
  441. package/src/server/serverFns/testcase/__tests__/regression.test.ts +36 -3
  442. package/src/server/serverFns/testcase/__tests__/run-cases.test.ts +36 -3
  443. package/src/server/serverFns/testcase/__tests__/runs.test.ts +36 -3
  444. package/src/server/serverFns/testcase/__tests__/stats.test.ts +36 -3
  445. package/src/server/serverFns/testcase/__tests__/testcase-board.test.ts +39 -5
  446. package/src/server/serverFns/testcase/__tests__/testcase-crud.test.ts +36 -3
  447. package/src/server/serverFns/testcase/__tests__/testcase-folders.test.ts +36 -3
  448. package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +38 -5
  449. package/src/server/serverFns/testcase/automation.ts +13 -17
  450. package/src/server/serverFns/testcase/bulk.ts +10 -14
  451. package/src/server/serverFns/testcase/evidence-upload.ts +5 -7
  452. package/src/server/serverFns/testcase/generation.ts +10 -13
  453. package/src/server/serverFns/testcase/plans.ts +23 -31
  454. package/src/server/serverFns/testcase/regression.ts +7 -10
  455. package/src/server/serverFns/testcase/run-cases.ts +13 -18
  456. package/src/server/serverFns/testcase/runs.ts +13 -18
  457. package/src/server/serverFns/testcase/stats.ts +13 -18
  458. package/src/server/serverFns/testcase/testcase-activities.ts +4 -6
  459. package/src/server/serverFns/testcase/testcase-board.ts +4 -6
  460. package/src/server/serverFns/testcase/testcase-crud.ts +20 -27
  461. package/src/server/serverFns/testcase/testcase-display-options.ts +8 -11
  462. package/src/server/serverFns/testcase/testcase-export.ts +5 -7
  463. package/src/server/serverFns/testcase/testcase-filter-views.ts +12 -18
  464. package/src/server/serverFns/testcase/testcase-folders.ts +16 -22
  465. package/src/server/serverFns/testcase/testcase-groups.ts +4 -6
  466. package/src/server/serverFns/testcase/testcase-reorder.ts +4 -6
  467. package/src/server/serverFns/translation.ts +4 -6
  468. package/src/server/serverFns/user/avatar.ts +4 -6
  469. package/src/server/serverFns/user/settings.ts +4 -6
  470. package/src/server/serverFns/user/update-locale.ts +4 -6
  471. package/src/server/serverFns/workspace-kb.ts +26 -35
  472. package/src/server/serverFns/workspace.ts +43 -59
  473. package/src/server/serverFns/ws.ts +4 -6
  474. package/src/server/serverfn-public-allowlist.ts +117 -0
  475. package/src/server/story/types.ts +0 -1
  476. package/src/server/sync/__tests__/scopes.test.ts +64 -0
  477. package/src/server/sync/scopes.ts +7 -0
  478. package/src/server/testcase/__tests__/auto-bug.test.ts +44 -12
  479. package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
  480. package/src/__typeprobe__.d.ts +0 -4
  481. package/src/components/forms/app-form-dialog.tsx +0 -126
  482. package/src/components/forms/hooks/use-form-submit.ts +0 -57
  483. package/src/components/forms/types.ts +0 -34
  484. package/src/components/harness/code/workspace-picker.tsx +0 -239
  485. package/src/components/tiptap/extensions/local-file/insert-local-file.ts +0 -35
  486. package/src/components/tiptap/extensions/local-file/local-file-node.ts +0 -71
  487. package/src/devframe-docks/ai-chat-iframe.tsx +0 -29
  488. package/src/devframe-docks/session-iframe.tsx +0 -90
  489. package/src/lib/__tests__/desktop-detect.test.ts +0 -19
  490. package/src/lib/collections/index.ts +0 -22
  491. package/src/lib/collections/knowledge/index.ts +0 -18
  492. package/src/lib/collections/knowledge/knowledge-bases-collection.ts +0 -34
  493. package/src/lib/collections/reference/bookmark-categories-collection.ts +0 -31
  494. package/src/lib/collections/reference/labels-collection.ts +0 -31
  495. package/src/lib/collections/reference/projects-collection.ts +0 -31
  496. package/src/lib/collections/reference/users-brief-collection.ts +0 -35
  497. package/src/lib/collections/reference/workspaces-collection.ts +0 -34
  498. package/src/lib/desktop-detect.ts +0 -29
  499. package/src/paraglide/messages/en.js +0 -28260
  500. 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 { requireAuth } from "@/server/auth-helpers";
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 session = await requireAuth(request);
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 request = getRequest();
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 { requireAuth } from '@/server/auth-helpers'
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: session.user.id,
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
- validator(schema) {
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
- return async (args: { data: unknown }) => {
140
- const data =
141
- api._validator && args?.data !== undefined ? api._validator.parse(args.data) : args?.data;
142
- return fn({ data });
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
- }
@@ -1,4 +0,0 @@
1
- import type { IApp, ILeafer, IUI } from "leafer-editor"
2
- export type A = IApp
3
- export type B = ILeafer
4
- export type C = IUI