@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
@@ -16,7 +16,7 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  // AI 复现 serverFn 薄壳(任务 26,规格 §11):runBugReproFn(详情面板「AI 复现」
19
- // 按钮)→ requireAuth + 项目成员校验 → 委派 runBugReproCore(组装/超时/校验/
19
+ // 按钮)→ authContextMiddleware 鉴权 + 项目成员校验 → 委派 runBugReproCore(组装/超时/校验/
20
20
  // 落库全在 server/bug-report/repro-runner.ts);listReproRunsFn 供详情「AI 复现
21
21
  // 报告卡片」分区(§5.4 第 6 分区)读取历史 run。同步执行(典型 < 30s,UI 按钮
22
22
  // loading 态;内部 55s 超时置 failed 可重试)。
@@ -24,9 +24,8 @@
24
24
  // 同 bug-fix.ts 先例);运行器在独立模块。
25
25
  import { getPrisma } from "@allbluecn/database/get-prisma";
26
26
  import { createServerFn } from "@tanstack/react-start";
27
- import { getRequest } from "@tanstack/react-start/server";
28
27
  import { z } from "zod";
29
- import { requireAuth } from "@/server/auth-helpers";
28
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
30
29
  import {
31
30
  REPRO_REPORT_SCHEMA,
32
31
  runBugReproCore,
@@ -74,11 +73,10 @@ function castRun(run: ReproRunRow): ReproRunItem {
74
73
  }
75
74
 
76
75
  export const runBugReproFn = createServerFn({ method: "POST" })
76
+ .middleware([authContextMiddleware])
77
77
  .validator(z.object({ bugId: z.string() }))
78
- .handler(async ({ data }) => {
79
- const request = getRequest();
80
- const session = await requireAuth(request);
81
- const userId = session.user.id;
78
+ .handler(async ({ data, context }) => {
79
+ const userId = context.user.id;
82
80
 
83
81
  await assertBugProjectMember(data.bugId, userId);
84
82
 
@@ -86,12 +84,11 @@ export const runBugReproFn = createServerFn({ method: "POST" })
86
84
  });
87
85
 
88
86
  export const listReproRunsFn = createServerFn({ method: "GET" })
87
+ .middleware([authContextMiddleware])
89
88
  .validator(z.object({ bugId: z.string() }))
90
- .handler(async ({ data }) => {
89
+ .handler(async ({ data, context }) => {
91
90
  const prisma = await getPrisma();
92
- const request = getRequest();
93
- const session = await requireAuth(request);
94
- const userId = session.user.id;
91
+ const userId = context.user.id;
95
92
 
96
93
  await assertBugProjectMember(data.bugId, userId);
97
94
 
@@ -22,9 +22,8 @@
22
22
  // 本文件只准导出 createServerFn 产物(serverFn 纯净铁律)。
23
23
  import { getPrisma } from "@allbluecn/database/get-prisma";
24
24
  import { createServerFn } from "@tanstack/react-start";
25
- import { getRequest } from "@tanstack/react-start/server";
26
25
  import { z } from "zod";
27
- import { requireAuth } from "@/server/auth-helpers";
26
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
28
27
  import { getAccessibleProjectIds } from "@/server/bug/bug-permissions";
29
28
 
30
29
  const idListSchema = z.object({ bugIds: z.array(z.string()).min(1).max(500) });
@@ -35,12 +34,11 @@ const bulkLinkSchema = z.object({
35
34
  });
36
35
 
37
36
  export const bulkLinkBugsToStoryFn = createServerFn({ method: "POST" })
37
+ .middleware([authContextMiddleware])
38
38
  .validator(bulkLinkSchema)
39
- .handler(async ({ data }) => {
39
+ .handler(async ({ data, context }) => {
40
40
  const prisma = await getPrisma();
41
- const request = getRequest();
42
- const session = await requireAuth(request);
43
- const userId = session.user.id;
41
+ const userId = context.user.id;
44
42
  const visibleProjectIds = await getAccessibleProjectIds(userId);
45
43
 
46
44
  // story 归属校验(防跨项目挂载,testcase bulk 同口径)
@@ -90,12 +88,11 @@ export const bulkLinkBugsToStoryFn = createServerFn({ method: "POST" })
90
88
  });
91
89
 
92
90
  export const bulkUnlinkBugsFromStoryFn = createServerFn({ method: "POST" })
91
+ .middleware([authContextMiddleware])
93
92
  .validator(idListSchema)
94
- .handler(async ({ data }) => {
93
+ .handler(async ({ data, context }) => {
95
94
  const prisma = await getPrisma();
96
- const request = getRequest();
97
- const session = await requireAuth(request);
98
- const userId = session.user.id;
95
+ const userId = context.user.id;
99
96
  const visibleProjectIds = await getAccessibleProjectIds(userId);
100
97
 
101
98
  return prisma.$transaction(async (tx) => {
@@ -156,12 +153,11 @@ const listByStorySchema = z.object({
156
153
 
157
154
  /** 需求详情「关联 BUG」面板:按 storyId 反查(单值关联,量级有限,一次取全) */
158
155
  export const listBugsByStoryFn = createServerFn({ method: "GET" })
156
+ .middleware([authContextMiddleware])
159
157
  .validator(listByStorySchema)
160
- .handler(async ({ data }) => {
158
+ .handler(async ({ data, context }) => {
161
159
  const prisma = await getPrisma();
162
- const request = getRequest();
163
- const session = await requireAuth(request);
164
- const userId = session.user.id;
160
+ const userId = context.user.id;
165
161
 
166
162
  // story 可见性:非成员静默回退空(防越权探测 storyId)
167
163
  const story = await prisma.story.findUnique({
@@ -216,12 +212,11 @@ const listForSelectSchema = z.object({
216
212
  });
217
213
 
218
214
  export const listBugsForSelectFn = createServerFn({ method: "GET" })
215
+ .middleware([authContextMiddleware])
219
216
  .validator(listForSelectSchema)
220
- .handler(async ({ data }) => {
217
+ .handler(async ({ data, context }) => {
221
218
  const prisma = await getPrisma();
222
- const request = getRequest();
223
- const session = await requireAuth(request);
224
- const userId = session.user.id;
219
+ const userId = context.user.id;
225
220
  const projectId = await (async () => {
226
221
  // scope 解析同 listBugsFn:无效/非成员 → 回退独立项目
227
222
  const { resolveStoryScopeProjectId } = await import("@/server/builtin-project");
@@ -23,9 +23,8 @@
23
23
  // 描述序列化工具在 bug-story-utils.ts(serverFn 文件禁止非 createServerFn 导出)。
24
24
  import { getPrisma } from "@allbluecn/database/get-prisma";
25
25
  import { createServerFn } from "@tanstack/react-start";
26
- import { getRequest } from "@tanstack/react-start/server";
27
26
  import { z } from "zod";
28
- import { requireAuth } from "@/server/auth-helpers";
27
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
29
28
  import { assertBugProjectMember } from "@/server/bug/bug-permissions";
30
29
  import { buildConvertedDescription } from "./bug-story-utils";
31
30
  import { createStoryInternal } from "@/server/serverFns/story/story-crud/create-story-internal";
@@ -39,12 +38,11 @@ const linkSchema = z.object({
39
38
  });
40
39
 
41
40
  export const convertBugToStoryFn = createServerFn({ method: "POST" })
41
+ .middleware([authContextMiddleware])
42
42
  .validator(bugIdSchema)
43
- .handler(async ({ data }) => {
43
+ .handler(async ({ data, context }) => {
44
44
  const prisma = await getPrisma();
45
- const request = getRequest();
46
- const session = await requireAuth(request);
47
- const userId = session.user.id;
45
+ const userId = context.user.id;
48
46
 
49
47
  await assertBugProjectMember(data.bugId, userId);
50
48
 
@@ -97,12 +95,11 @@ export const convertBugToStoryFn = createServerFn({ method: "POST" })
97
95
  });
98
96
 
99
97
  export const linkBugToStoryFn = createServerFn({ method: "POST" })
98
+ .middleware([authContextMiddleware])
100
99
  .validator(linkSchema)
101
- .handler(async ({ data }) => {
100
+ .handler(async ({ data, context }) => {
102
101
  const prisma = await getPrisma();
103
- const request = getRequest();
104
- const session = await requireAuth(request);
105
- const userId = session.user.id;
102
+ const userId = context.user.id;
106
103
 
107
104
  const projectId = await assertBugProjectMember(data.bugId, userId);
108
105
 
@@ -135,12 +132,11 @@ export const linkBugToStoryFn = createServerFn({ method: "POST" })
135
132
  });
136
133
 
137
134
  export const unlinkBugFromStoryFn = createServerFn({ method: "POST" })
135
+ .middleware([authContextMiddleware])
138
136
  .validator(bugIdSchema)
139
- .handler(async ({ data }) => {
137
+ .handler(async ({ data, context }) => {
140
138
  const prisma = await getPrisma();
141
- const request = getRequest();
142
- const session = await requireAuth(request);
143
- const userId = session.user.id;
139
+ const userId = context.user.id;
144
140
 
145
141
  await assertBugProjectMember(data.bugId, userId);
146
142
 
@@ -20,9 +20,8 @@
20
20
  // 显示选项保留行(BUG_DISPLAY_OPTIONS_VIEW_NAME)对视图清单不可见、不可建/改/删。
21
21
  import { getPrisma } from "@allbluecn/database/get-prisma";
22
22
  import { createServerFn } from "@tanstack/react-start";
23
- import { getRequest } from "@tanstack/react-start/server";
24
23
  import { z } from "zod";
25
- import { requireAuth } from "@/server/auth-helpers";
24
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
26
25
  import { toJsonInput } from "@/server/lib/prisma-json";
27
26
  import {
28
27
  BUG_DISPLAY_OPTIONS_VIEW_NAME,
@@ -63,11 +62,9 @@ const VIEW_SELECT = {
63
62
 
64
63
  const NOT_RESERVED = { name: { not: BUG_DISPLAY_OPTIONS_VIEW_NAME } };
65
64
 
66
- export const listBugViewsFn = createServerFn({ method: "GET" }).handler(async () => {
65
+ export const listBugViewsFn = createServerFn({ method: "GET" }).middleware([authContextMiddleware]).handler(async ({ context }) => {
67
66
  const prisma = await getPrisma();
68
- const request = getRequest();
69
- const session = await requireAuth(request);
70
- const userId = session.user.id;
67
+ const userId = context.user.id;
71
68
  const rows = await prisma.bugFilterView.findMany({
72
69
  where: { userId, ...NOT_RESERVED },
73
70
  orderBy: { createdAt: "asc" },
@@ -100,15 +97,14 @@ const createSchema = z.object({
100
97
  });
101
98
 
102
99
  export const createBugViewFn = createServerFn({ method: "POST" })
100
+ .middleware([authContextMiddleware])
103
101
  .validator(createSchema)
104
- .handler(async ({ data }) => {
105
- const request = getRequest();
106
- const session = await requireAuth(request);
102
+ .handler(async ({ data, context }) => {
107
103
  if (data.name === BUG_DISPLAY_OPTIONS_VIEW_NAME) {
108
104
  throw new Error("该视图名称为系统保留,请换一个名称");
109
105
  }
110
106
  const prisma = await getPrisma();
111
- const userId = session.user.id;
107
+ const userId = context.user.id;
112
108
  assertDisplayOptionsSize(data.displayOptions);
113
109
  const row = await prisma.bugFilterView.create({
114
110
  data: {
@@ -132,15 +128,14 @@ const updateSchema = z.object({
132
128
  });
133
129
 
134
130
  export const updateBugViewFn = createServerFn({ method: "POST" })
131
+ .middleware([authContextMiddleware])
135
132
  .validator(updateSchema)
136
- .handler(async ({ data }) => {
137
- const request = getRequest();
138
- const session = await requireAuth(request);
133
+ .handler(async ({ data, context }) => {
139
134
  if (data.name === BUG_DISPLAY_OPTIONS_VIEW_NAME) {
140
135
  throw new Error("该视图名称为系统保留,请换一个名称");
141
136
  }
142
137
  const prisma = await getPrisma();
143
- const userId = session.user.id;
138
+ const userId = context.user.id;
144
139
  const { id, ...patch } = data;
145
140
  if (patch.displayOptions !== undefined) assertDisplayOptionsSize(patch.displayOptions);
146
141
  const updates: Record<string, unknown> = {};
@@ -160,12 +155,11 @@ export const updateBugViewFn = createServerFn({ method: "POST" })
160
155
  const deleteSchema = z.object({ id: z.string() });
161
156
 
162
157
  export const deleteBugViewFn = createServerFn({ method: "POST" })
158
+ .middleware([authContextMiddleware])
163
159
  .validator(deleteSchema)
164
- .handler(async ({ data }) => {
160
+ .handler(async ({ data, context }) => {
165
161
  const prisma = await getPrisma();
166
- const request = getRequest();
167
- const session = await requireAuth(request);
168
- const userId = session.user.id;
162
+ const userId = context.user.id;
169
163
  await prisma.bugFilterView.delete({
170
164
  where: { id: data.id, userId, ...NOT_RESERVED },
171
165
  });
@@ -23,9 +23,8 @@
23
23
  import { randomBytes } from "node:crypto";
24
24
  import { getPrisma } from "@allbluecn/database/get-prisma";
25
25
  import { createServerFn } from "@tanstack/react-start";
26
- import { getRequest } from "@tanstack/react-start/server";
27
26
  import { z } from "zod";
28
- import { requireAuth } from "@/server/auth-helpers";
27
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
29
28
  import { assertFetchableUrl } from "@/server/fetch-guard";
30
29
  import { BUG_WEBHOOK_EVENTS } from "@/shared/bug/constants";
31
30
  import { TEST_RUN_WEBHOOK_EVENTS } from "../testcase/constants";
@@ -59,12 +58,11 @@ interface BugWebhookListItem {
59
58
  }
60
59
 
61
60
  export const listBugWebhooksFn = createServerFn({ method: "GET" })
61
+ .middleware([authContextMiddleware])
62
62
  .validator(projectIdSchema)
63
- .handler(async ({ data }) => {
63
+ .handler(async ({ data, context }) => {
64
64
  const prisma = await getPrisma();
65
- const request = getRequest();
66
- const session = await requireAuth(request);
67
- const userId = session.user.id;
65
+ const userId = context.user.id;
68
66
  await assertProjectMembership(data.projectId, userId);
69
67
 
70
68
  const rows = await prisma.projectWebhook.findMany({
@@ -90,12 +88,11 @@ const createWebhookSchema = z.object({
90
88
  });
91
89
 
92
90
  export const createBugWebhookFn = createServerFn({ method: "POST" })
91
+ .middleware([authContextMiddleware])
93
92
  .validator(createWebhookSchema)
94
- .handler(async ({ data }) => {
93
+ .handler(async ({ data, context }) => {
95
94
  const prisma = await getPrisma();
96
- const request = getRequest();
97
- const session = await requireAuth(request);
98
- const userId = session.user.id;
95
+ const userId = context.user.id;
99
96
  await assertProjectMembership(data.projectId, userId);
100
97
 
101
98
  // SEC-07 注册时校验:成员即可注册 webhook,私网/回环目标会形成服务端盲
@@ -132,12 +129,11 @@ const deleteWebhookSchema = z.object({
132
129
  });
133
130
 
134
131
  export const deleteBugWebhookFn = createServerFn({ method: "POST" })
132
+ .middleware([authContextMiddleware])
135
133
  .validator(deleteWebhookSchema)
136
- .handler(async ({ data }) => {
134
+ .handler(async ({ data, context }) => {
137
135
  const prisma = await getPrisma();
138
- const request = getRequest();
139
- const session = await requireAuth(request);
140
- const userId = session.user.id;
136
+ const userId = context.user.id;
141
137
  await assertProjectMembership(data.projectId, userId);
142
138
 
143
139
  // findFirst 带 projectId 收敛:越权 webhookId 与不存在同话术
@@ -153,12 +149,11 @@ export const deleteBugWebhookFn = createServerFn({ method: "POST" })
153
149
  const toggleWebhookSchema = deleteWebhookSchema.extend({ enabled: z.boolean() });
154
150
 
155
151
  export const toggleBugWebhookFn = createServerFn({ method: "POST" })
152
+ .middleware([authContextMiddleware])
156
153
  .validator(toggleWebhookSchema)
157
- .handler(async ({ data }) => {
154
+ .handler(async ({ data, context }) => {
158
155
  const prisma = await getPrisma();
159
- const request = getRequest();
160
- const session = await requireAuth(request);
161
- const userId = session.user.id;
156
+ const userId = context.user.id;
162
157
  await assertProjectMembership(data.projectId, userId);
163
158
 
164
159
  const existing = await prisma.projectWebhook.findFirst({
@@ -23,9 +23,8 @@
23
23
  // createServerFn 外无普通导出(成员校验复用 bug-permissions)。
24
24
  import { getPrisma } from "@allbluecn/database/get-prisma";
25
25
  import { createServerFn } from "@tanstack/react-start";
26
- import { getRequest } from "@tanstack/react-start/server";
27
26
  import { z } from "zod";
28
- import { requireAuth } from "@/server/auth-helpers";
27
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
29
28
  import { assertProjectMembership } from "@/server/bug/bug-permissions";
30
29
 
31
30
  const runIdSchema = z.object({ runId: z.string().min(1) });
@@ -42,12 +41,11 @@ interface PendingTestBugItem {
42
41
 
43
42
  /** 本批次 AI 起草且仍待确认的 Bug 清单(确认/回写后即从清单消失) */
44
43
  export const listPendingTestRunBugsFn = createServerFn({ method: "GET" })
44
+ .middleware([authContextMiddleware])
45
45
  .validator(runIdSchema)
46
- .handler(async ({ data }): Promise<PendingTestBugItem[]> => {
46
+ .handler(async ({ data, context }): Promise<PendingTestBugItem[]> => {
47
47
  const prisma = await getPrisma();
48
- const request = getRequest();
49
- const session = await requireAuth(request);
50
- const userId = session.user.id;
48
+ const userId = context.user.id;
51
49
 
52
50
  const run = await prisma.testRun.findUnique({
53
51
  where: { id: data.runId },
@@ -80,12 +78,11 @@ const confirmSchema = z.object({ bugId: z.string().min(1) });
80
78
 
81
79
  /** 确认提交:pendingConfirm true→false(转正进入 BUG 常规列表),活动留痕 */
82
80
  export const confirmTestRunBugFn = createServerFn({ method: "POST" })
81
+ .middleware([authContextMiddleware])
83
82
  .validator(confirmSchema)
84
- .handler(async ({ data }) => {
83
+ .handler(async ({ data, context }) => {
85
84
  const prisma = await getPrisma();
86
- const request = getRequest();
87
- const session = await requireAuth(request);
88
- const userId = session.user.id;
85
+ const userId = context.user.id;
89
86
 
90
87
  const bug = await prisma.bug.findUnique({
91
88
  where: { id: data.bugId },
@@ -14,10 +14,49 @@ const mocks = vi.hoisted(() => ({
14
14
 
15
15
  vi.mock("@tanstack/react-start", () => ({
16
16
  createServerFn: () => ({
17
+ _middlewares: [] as unknown[],
18
+ middleware(mws: unknown[]) {
19
+ this._middlewares.push(...mws);
20
+ return this;
21
+ },
17
22
  handler(fn: Function) {
18
- return async (args?: { data?: unknown }) => fn({ data: args?.data });
23
+ const self = this;
24
+ return async (args?: { data?: unknown }) => {
25
+ // fetchChangelogFn 迁移后经 .middleware([authContextMiddleware]) 注入
26
+ // context.user:mock 依序执行 middleware 的 server 段(fetchChangelogFn
27
+ // 本体不消费 user,仅要求鉴权门卫先行),真实鉴权链由被 mock 的 auth-helpers 承接
28
+ let context: unknown = {};
29
+ for (const mw of self._middlewares) {
30
+ const serverFn = (mw as { options?: { server?: unknown } })?.options?.server;
31
+ if (typeof serverFn !== "function") continue;
32
+ const result = await (
33
+ serverFn as (p: unknown) => Promise<{ context?: unknown }>
34
+ )({
35
+ data: args?.data,
36
+ context,
37
+ method: "GET",
38
+ serverFnMeta: {},
39
+ signal: new AbortController().signal,
40
+ next: (inner: { context?: unknown } | undefined) =>
41
+ Promise.resolve({ context: { ...(context as object), ...(inner?.context ?? {}) } }),
42
+ });
43
+ context = result.context;
44
+ }
45
+ return fn({ data: args?.data, context });
46
+ };
19
47
  },
20
48
  }),
49
+ // auth-context.ts 依赖 createMiddleware({ type: 'function' }).server(fn):
50
+ // mock 产出与真实 middleware 同构的 { options: { server } } 形状,
51
+ // 供上方 handler 包装器执行 server 段注入 context.user
52
+ createMiddleware: (opts: any) => {
53
+ const mw: any = { options: { type: opts?.type } };
54
+ mw.server = (fn: Function) => {
55
+ mw.options.server = fn;
56
+ return mw;
57
+ };
58
+ return mw;
59
+ },
21
60
  }));
22
61
 
23
62
  vi.mock("@tanstack/react-start/server", () => ({
@@ -1,19 +1,17 @@
1
1
  import { getPrisma } from "@allbluecn/database/get-prisma"
2
2
  import { createServerFn } from '@tanstack/react-start'
3
- import { getRequest } from '@tanstack/react-start/server'
4
3
  import type { DeveloperLogEntry } from '@allbluecn/kernel'
5
- import { requireAuth } from '@/server/auth-helpers'
4
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
6
5
 
7
6
  // changelog 页位于 _nav(登录墙内),消费方仅 _nav/changelog/route.tsx loader;
8
- // serverFn 是独立 RPC 入口,未登录直调会被 _nav 布局拦在页面层——此处按
9
- // 「每个 handler 首行自查鉴权」约定补 requireAuth,封死匿名全表拉取面。
7
+ // serverFn 是独立 RPC 入口,未登录直调会被 _nav 布局拦在页面层——按
8
+ // authContextMiddleware 挂 per-fn 鉴权,封死匿名全表拉取面。
10
9
  // take 封顶防 developerLog 表增长后单次大返回(当前量级远低于上限,行为不变)。
11
10
  const CHANGELOG_MAX_ENTRIES = 500
12
11
 
13
12
  export const fetchChangelogFn = createServerFn({ method: 'GET' })
13
+ .middleware([authContextMiddleware])
14
14
  .handler(async () => {
15
- const request = getRequest()
16
- await requireAuth(request)
17
15
  const prisma = await getPrisma()
18
16
  const logs = await prisma.developerLog.findMany({
19
17
  where: { isDeleted: false },
@@ -18,9 +18,8 @@
18
18
  import { getPrisma } from "@allbluecn/database/get-prisma"
19
19
  import { Prisma } from "@allbluecn/database"
20
20
  import { createServerFn } from "@tanstack/react-start"
21
- import { getRequest } from "@tanstack/react-start/server"
21
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
22
22
  import { z } from "zod"
23
- import { getCurrentSession } from "@/lib/session"
24
23
 
25
24
  /** 可空 Json 列的 createMany 入参收窄:null → Prisma.JsonNull(Prisma 拒绝裸 null) */
26
25
  function jsonRef(v: Prisma.JsonValue | null): Prisma.InputJsonValue | Prisma.NullableJsonNullValueInput {
@@ -28,16 +27,14 @@ function jsonRef(v: Prisma.JsonValue | null): Prisma.InputJsonValue | Prisma.Nul
28
27
  }
29
28
 
30
29
  export const listConversationsFn = createServerFn({ method: "GET" })
31
- .handler(async () => {
30
+ .middleware([authContextMiddleware])
31
+ .handler(async ({ context }) => {
32
32
  const prisma = await getPrisma()
33
- const request = getRequest()
34
- const session = await getCurrentSession(request)
35
- if (!session?.user?.id) throw new Error("Unauthorized")
36
33
 
37
34
  const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000)
38
35
 
39
36
  const conversations = await prisma.chatThread.findMany({
40
- where: { userId: session.user.id },
37
+ where: { userId: context.user.id },
41
38
  orderBy: { updatedAt: "desc" },
42
39
  // DB-04/05:白名单 select + 防御性 take(侧栏只展示最近会话,截断最旧)
43
40
  take: 200,
@@ -75,12 +72,10 @@ const createConversationSchema = z.object({
75
72
  })
76
73
 
77
74
  export const createConversationFn = createServerFn({ method: "POST" })
75
+ .middleware([authContextMiddleware])
78
76
  .validator(createConversationSchema)
79
- .handler(async ({ data }) => {
77
+ .handler(async ({ data, context }) => {
80
78
  const prisma = await getPrisma()
81
- const request = getRequest()
82
- const session = await getCurrentSession(request)
83
- if (!session?.user?.id) throw new Error("Unauthorized")
84
79
 
85
80
  const agentId = data.agentId || null
86
81
 
@@ -88,7 +83,7 @@ export const createConversationFn = createServerFn({ method: "POST" })
88
83
  const agent = await prisma.userAgent.findFirst({
89
84
  where: {
90
85
  id: agentId,
91
- userId: session.user.id,
86
+ userId: context.user.id,
92
87
  isDeleted: false,
93
88
  },
94
89
  select: { id: true, userId: true, name: true, avatarEmoji: true },
@@ -97,7 +92,7 @@ export const createConversationFn = createServerFn({ method: "POST" })
97
92
  }
98
93
 
99
94
  const conversation = await prisma.chatThread.create({
100
- data: { userId: session.user.id, agentId },
95
+ data: { userId: context.user.id, agentId },
101
96
  include: { agent: { select: { name: true, avatarEmoji: true } } },
102
97
  })
103
98
 
@@ -120,19 +115,17 @@ const updateConversationSchema = z.object({
120
115
  })
121
116
 
122
117
  export const updateConversationFn = createServerFn({ method: "POST" })
118
+ .middleware([authContextMiddleware])
123
119
  .validator(updateConversationSchema)
124
- .handler(async ({ data }) => {
120
+ .handler(async ({ data, context }) => {
125
121
  const prisma = await getPrisma()
126
- const request = getRequest()
127
- const session = await getCurrentSession(request)
128
- if (!session?.user?.id) throw new Error("Unauthorized")
129
122
 
130
123
  const update: Record<string, unknown> = {}
131
124
  if (data.title !== undefined) update.title = data.title
132
125
  if (data.isArchived !== undefined) update.isArchived = data.isArchived
133
126
 
134
127
  await prisma.chatThread.update({
135
- where: { id: data.id, userId: session.user.id },
128
+ where: { id: data.id, userId: context.user.id },
136
129
  data: update,
137
130
  })
138
131
 
@@ -144,15 +137,13 @@ const deleteConversationSchema = z.object({
144
137
  })
145
138
 
146
139
  export const deleteConversationFn = createServerFn({ method: "POST" })
140
+ .middleware([authContextMiddleware])
147
141
  .validator(deleteConversationSchema)
148
- .handler(async ({ data }) => {
142
+ .handler(async ({ data, context }) => {
149
143
  const prisma = await getPrisma()
150
- const request = getRequest()
151
- const session = await getCurrentSession(request)
152
- if (!session?.user?.id) throw new Error("Unauthorized")
153
144
 
154
145
  await prisma.chatThread.delete({
155
- where: { id: data.id, userId: session.user.id },
146
+ where: { id: data.id, userId: context.user.id },
156
147
  })
157
148
 
158
149
  return { success: true }
@@ -167,13 +158,11 @@ const FORK_MSG_BATCH_SIZE = 500;
167
158
  const FORK_MSG_WARN_THRESHOLD = 2000;
168
159
 
169
160
  export const forkConversationFn = createServerFn({ method: "POST" })
161
+ .middleware([authContextMiddleware])
170
162
  .validator(forkConversationSchema)
171
- .handler(async ({ data }) => {
163
+ .handler(async ({ data, context }) => {
172
164
  const prisma = await getPrisma()
173
- const request = getRequest()
174
- const session = await getCurrentSession(request)
175
- if (!session?.user?.id) throw new Error("Unauthorized")
176
- const userId = session.user.id
165
+ const userId = context.user.id
177
166
 
178
167
  const source = await prisma.chatThread.findFirst({
179
168
  where: { id: data.threadId, userId },
@@ -17,11 +17,11 @@
17
17
 
18
18
  import { getPrisma } from "@allbluecn/database/get-prisma"
19
19
  import { createServerFn } from "@tanstack/react-start"
20
- import { getRequest } from "@tanstack/react-start/server"
20
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
21
21
  import { z } from "zod"
22
- import { getCurrentSession } from "@/lib/session"
23
22
 
24
23
  export const listMessagesFn = createServerFn({ method: "GET" })
24
+ .middleware([authContextMiddleware])
25
25
  .validator(
26
26
  z.object({
27
27
  threadId: z.string().min(1),
@@ -33,15 +33,12 @@ export const listMessagesFn = createServerFn({ method: "GET" })
33
33
  limit: z.number().int().min(1).max(500).optional(),
34
34
  }),
35
35
  )
36
- .handler(async ({ data }) => {
36
+ .handler(async ({ data, context }) => {
37
37
  const prisma = await getPrisma()
38
- const request = getRequest()
39
- const session = await getCurrentSession(request)
40
- if (!session?.user?.id) throw new Error("Unauthorized")
41
38
 
42
39
  // SEC-17: 越权读防护——ChatThread 无成员表,仅属主可读消息
43
40
  const thread = await prisma.chatThread.findFirst({
44
- where: { id: data.threadId, userId: session.user.id },
41
+ where: { id: data.threadId, userId: context.user.id },
45
42
  select: { id: true },
46
43
  })
47
44
  if (!thread) throw new Error("thread not found")
@@ -29,12 +29,12 @@
29
29
  // createSharePresenceTicketFn、团队 presence=本文件)。
30
30
 
31
31
  import { createServerFn } from '@tanstack/react-start'
32
- import { getRequest } from '@tanstack/react-start/server'
32
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
33
33
  import { z } from 'zod'
34
34
  import { getPrisma } from '@allbluecn/database/get-prisma'
35
35
  import { buildRoomName } from '@allbluecn/collab-core/rooms'
36
36
  import { signTicket } from '@allbluecn/collab-core/ticket'
37
- import { requireAuth, ForbiddenError } from '@/server/auth-helpers'
37
+ import { ForbiddenError } from '@/server/auth-helpers';
38
38
  import { parseRoomName } from '@/server/collab-permissions'
39
39
  import { isUserInTeam, USER_BRIEF_SELECT } from '@/server/team-access'
40
40
  import {
@@ -44,15 +44,14 @@ import {
44
44
  } from '@/server/collab/ticket-utils'
45
45
 
46
46
  /**
47
- * 当前用户的团队 presence room 引导。未登录由 requireAuth 拒绝;
47
+ * 当前用户的团队 presence room 引导。未登录由 authContextMiddleware 拒绝;
48
48
  * 无团队成员行的账号按自属团队处理(与 listTeamMembersFn 的懒建 owner 行
49
49
  * 口径一致:presence 不触发行创建,ownerId 即自己)。
50
50
  */
51
- export const getPresenceRoomFn = createServerFn({ method: 'GET' }).handler(
52
- async () => {
53
- const request = getRequest()
54
- const session = await requireAuth(request)
55
- const userId = session.user.id
51
+ export const getPresenceRoomFn = createServerFn({ method: 'GET' })
52
+ .middleware([authContextMiddleware]).handler(
53
+ async ({ context }) => {
54
+ const userId = context.user.id
56
55
 
57
56
  const prisma = await getPrisma()
58
57
  const membership = await prisma.teamMembership.findUnique({
@@ -88,12 +87,11 @@ export const getPresenceRoomFn = createServerFn({ method: 'GET' }).handler(
88
87
  * 入口),授权 = isUserInTeam(room.ownerId, me)。
89
88
  */
90
89
  export const createPresenceTicketFn = createServerFn({ method: 'POST' })
90
+ .middleware([authContextMiddleware])
91
91
  .validator(z.object({ roomName: z.string().min(1) }))
92
- .handler(async ({ data }) => {
93
- const request = getRequest()
94
- const session = await requireAuth(request)
95
- const user = session.user!
96
- const userId = user.id!
92
+ .handler(async ({ data, context }) => {
93
+ const user = context.user
94
+ const userId = user.id
97
95
 
98
96
  const room = parseRoomName(data.roomName)
99
97
  if (!room || room.kind !== 'presence-team') {