@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
@@ -29,7 +29,7 @@ import { createServerFn } from "@tanstack/react-start";
29
29
  import { getRequest } from "@tanstack/react-start/server";
30
30
  import { z } from "zod";
31
31
  import type { Prisma } from "@allbluecn/database";
32
- import { requireAuth } from "@/server/auth-helpers";
32
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
33
33
  import { requireFeature } from "@/server/entitlements";
34
34
  import { checkAiRateLimit } from "@/server/lib/rate-limit";
35
35
  import { truncateWithMarker } from "@/server/lib/text-truncate";
@@ -246,13 +246,12 @@ const startGenerationInputSchema = z.object({
246
246
  });
247
247
 
248
248
  export const startGenerationFn = createServerFn({ method: "POST" })
249
+ .middleware([authContextMiddleware])
249
250
  .validator(startGenerationInputSchema)
250
- .handler(async ({ data }) => {
251
+ .handler(async ({ data, context }) => {
251
252
  // 计费门控(规格 §12):serverFn 第一行 requireFeature
252
253
  await requireFeature(getRequest(), "testGeneration");
253
- const request = getRequest();
254
- const session = await requireAuth(request);
255
- const userId = session.user.id;
254
+ const userId = context.user.id;
256
255
  await checkAiRateLimit(userId, "testGeneration");
257
256
 
258
257
  if (!(await hasAiKey(userId))) {
@@ -444,11 +443,10 @@ const adoptDraftsInputSchema = z.object({
444
443
  });
445
444
 
446
445
  export const adoptDraftsFn = createServerFn({ method: "POST" })
446
+ .middleware([authContextMiddleware])
447
447
  .validator(adoptDraftsInputSchema)
448
- .handler(async ({ data }) => {
449
- const request = getRequest();
450
- const session = await requireAuth(request);
451
- const userId = session.user.id;
448
+ .handler(async ({ data, context }) => {
449
+ const userId = context.user.id;
452
450
  const prisma = await getPrisma();
453
451
 
454
452
  const run = await prisma.testGenerationRun.findUnique({
@@ -534,11 +532,10 @@ const getGenerationInputSchema = z.object({
534
532
  });
535
533
 
536
534
  export const getGenerationFn = createServerFn({ method: "POST" })
535
+ .middleware([authContextMiddleware])
537
536
  .validator(getGenerationInputSchema)
538
- .handler(async ({ data }) => {
539
- const request = getRequest();
540
- const session = await requireAuth(request);
541
- const userId = session.user.id;
537
+ .handler(async ({ data, context }) => {
538
+ const userId = context.user.id;
542
539
  const prisma = await getPrisma();
543
540
 
544
541
  const run = await prisma.testGenerationRun.findUnique({
@@ -18,7 +18,7 @@
18
18
  // 测试计划 CRUD + 圈选关联 serverFn(照 testcase-crud / testcase-folders 写法惯例)。
19
19
  // 本文件只准导出 createServerFn 产物,select 常量、DTO cast、成员校验等辅助逻辑用
20
20
  // 文件内非导出成员(serverFn 纯净铁律)。
21
- // 权限口径与用例域一致:读走 requireAuth(detail 同 getTestCaseFn)/列表走
21
+ // 权限口径与用例域一致:读走 authContextMiddleware 鉴权(detail 同 getTestCaseFn)/列表走
22
22
  // resolveStoryScopeProjectId 防越权;写须项目有效成员(suspended 视同无权限)。
23
23
  // 圈选幂等:addCasesToPlanFn 先查已存在关联 + 载荷内去重,createMany 只收增量;
24
24
  // DB 层 test_plan_cases.@@unique([planId, caseId])(迁移 20261005090000)兜底并发重放。
@@ -27,10 +27,9 @@
27
27
  // deprecatedCount 计数供 UI 顶部提示,不做静默隐藏。
28
28
  import { getPrisma } from "@allbluecn/database/get-prisma";
29
29
  import { createServerFn } from "@tanstack/react-start";
30
- import { getRequest } from "@tanstack/react-start/server";
31
30
  import { z } from "zod";
32
31
  import type { Prisma } from "@allbluecn/database";
33
- import { requireAuth } from "@/server/auth-helpers";
32
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
34
33
  import { resolveStoryScopeProjectId } from "@/server/builtin-project";
35
34
  import { USER_BRIEF_SELECT, castUserBrief } from "@/server/story/user-brief";
36
35
  import {
@@ -139,12 +138,11 @@ const listPlansSchema = z.object({
139
138
  });
140
139
 
141
140
  export const listPlansFn = createServerFn({ method: "GET" })
141
+ .middleware([authContextMiddleware])
142
142
  .validator(listPlansSchema)
143
- .handler(async ({ data }) => {
143
+ .handler(async ({ data, context }) => {
144
144
  const prisma = await getPrisma();
145
- const request = getRequest();
146
- const session = await requireAuth(request);
147
- const userId = session.user.id;
145
+ const userId = context.user.id;
148
146
 
149
147
  // scope 解析:未传/无效/非成员 → 静默回退独立项目,防越权查询(同 listTestCasesFn)
150
148
  const projectId = await resolveStoryScopeProjectId(data.projectId, userId);
@@ -169,12 +167,11 @@ const createPlanSchema = z.object({
169
167
  });
170
168
 
171
169
  export const createPlanFn = createServerFn({ method: "POST" })
170
+ .middleware([authContextMiddleware])
172
171
  .validator(createPlanSchema)
173
- .handler(async ({ data }) => {
172
+ .handler(async ({ data, context }) => {
174
173
  const prisma = await getPrisma();
175
- const request = getRequest();
176
- const session = await requireAuth(request);
177
- const userId = session.user.id;
174
+ const userId = context.user.id;
178
175
 
179
176
  // 未传 projectId 时回退内置独立项目(与读侧 resolve 同口径);
180
177
  // resolve 内部已验成员资格,这里再过一次 assertProjectMembership 显式失败语义
@@ -237,13 +234,12 @@ function castPlanDetail(row: PlanDetailRow): TestPlanDetail {
237
234
  }
238
235
 
239
236
  export const getPlanFn = createServerFn({ method: "GET" })
237
+ .middleware([authContextMiddleware])
240
238
  .validator(idSchema)
241
- .handler(async ({ data }) => {
239
+ .handler(async ({ data, context }) => {
242
240
  const prisma = await getPrisma();
243
- const request = getRequest();
244
- const session = await requireAuth(request);
245
241
  // 读侧与写侧同口径:须为计划所属项目的有效成员(审计 2026-10-25 读路径缺口)
246
- await assertTestPlanProjectMember(data.id, session.user.id);
242
+ await assertTestPlanProjectMember(data.id, context.user.id);
247
243
  const row = await prisma.testPlan.findUnique({
248
244
  where: { id: data.id },
249
245
  select: PLAN_DETAIL_SELECT,
@@ -263,12 +259,11 @@ const updatePlanSchema = z.object({
263
259
  });
264
260
 
265
261
  export const updatePlanFn = createServerFn({ method: "POST" })
262
+ .middleware([authContextMiddleware])
266
263
  .validator(updatePlanSchema)
267
- .handler(async ({ data }) => {
264
+ .handler(async ({ data, context }) => {
268
265
  const prisma = await getPrisma();
269
- const request = getRequest();
270
- const session = await requireAuth(request);
271
- const userId = session.user.id;
266
+ const userId = context.user.id;
272
267
 
273
268
  const existing = await prisma.testPlan.findUnique({
274
269
  where: { id: data.id },
@@ -322,12 +317,11 @@ export const updatePlanFn = createServerFn({ method: "POST" })
322
317
  // ── 删除(planCases 级联清理;TestRun.planId SetNull——执行批次保留但脱离计划)──
323
318
 
324
319
  export const deletePlanFn = createServerFn({ method: "POST" })
320
+ .middleware([authContextMiddleware])
325
321
  .validator(idSchema)
326
- .handler(async ({ data }) => {
322
+ .handler(async ({ data, context }) => {
327
323
  const prisma = await getPrisma();
328
- const request = getRequest();
329
- const session = await requireAuth(request);
330
- const userId = session.user.id;
324
+ const userId = context.user.id;
331
325
 
332
326
  const existing = await prisma.testPlan.findUnique({
333
327
  where: { id: data.id },
@@ -362,12 +356,11 @@ const addCasesSchema = z.object({
362
356
  });
363
357
 
364
358
  export const addCasesToPlanFn = createServerFn({ method: "POST" })
359
+ .middleware([authContextMiddleware])
365
360
  .validator(addCasesSchema)
366
- .handler(async ({ data }) => {
361
+ .handler(async ({ data, context }) => {
367
362
  const prisma = await getPrisma();
368
- const request = getRequest();
369
- const session = await requireAuth(request);
370
- const userId = session.user.id;
363
+ const userId = context.user.id;
371
364
 
372
365
  const plan = await prisma.testPlan.findUnique({
373
366
  where: { id: data.planId },
@@ -422,12 +415,11 @@ const removeCaseSchema = z.object({
422
415
  });
423
416
 
424
417
  export const removeCaseFromPlanFn = createServerFn({ method: "POST" })
418
+ .middleware([authContextMiddleware])
425
419
  .validator(removeCaseSchema)
426
- .handler(async ({ data }) => {
420
+ .handler(async ({ data, context }) => {
427
421
  const prisma = await getPrisma();
428
- const request = getRequest();
429
- const session = await requireAuth(request);
430
- const userId = session.user.id;
422
+ const userId = context.user.id;
431
423
 
432
424
  const plan = await prisma.testPlan.findUnique({
433
425
  where: { id: data.planId },
@@ -33,9 +33,8 @@
33
33
  // (编译期擦除,bug-repro.ts ReproRunItem 同先例)。
34
34
  import { getPrisma } from "@allbluecn/database/get-prisma";
35
35
  import { createServerFn } from "@tanstack/react-start";
36
- import { getRequest } from "@tanstack/react-start/server";
37
36
  import { z } from "zod";
38
- import { requireAuth } from "@/server/auth-helpers";
37
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
39
38
  import { assertBugProjectMember } from "@/server/bug/bug-permissions";
40
39
  import { createRunFn } from "./runs";
41
40
  import type { RunExecutorType } from "./constants";
@@ -57,12 +56,11 @@ function regressionRunName(title: string): string {
57
56
  // ── 发起回归(一键创建回归批次)──
58
57
 
59
58
  export const regressBugFn = createServerFn({ method: "POST" })
59
+ .middleware([authContextMiddleware])
60
60
  .validator(bugIdSchema)
61
- .handler(async ({ data }) => {
61
+ .handler(async ({ data, context }) => {
62
62
  const prisma = await getPrisma();
63
- const request = getRequest();
64
- const session = await requireAuth(request);
65
- const userId = session.user.id;
63
+ const userId = context.user.id;
66
64
 
67
65
  const bug = await prisma.bug.findUnique({
68
66
  where: { id: data.bugId },
@@ -102,12 +100,11 @@ export const regressBugFn = createServerFn({ method: "POST" })
102
100
  // ── 回归徽标状态(Bug 详情挂载时查询)──
103
101
 
104
102
  export const getBugRegressionStatusFn = createServerFn({ method: "GET" })
103
+ .middleware([authContextMiddleware])
105
104
  .validator(bugIdSchema)
106
- .handler(async ({ data }) => {
105
+ .handler(async ({ data, context }) => {
107
106
  const prisma = await getPrisma();
108
- const request = getRequest();
109
- const session = await requireAuth(request);
110
- const userId = session.user.id;
107
+ const userId = context.user.id;
111
108
 
112
109
  const projectId = await assertBugProjectMember(data.bugId, userId);
113
110
 
@@ -31,10 +31,9 @@
31
31
  // 本文件只准导出 createServerFn 产物(serverFn 纯净铁律),守卫/合并均为文件内私有。
32
32
  import { getPrisma } from "@allbluecn/database/get-prisma";
33
33
  import { createServerFn } from "@tanstack/react-start";
34
- import { getRequest } from "@tanstack/react-start/server";
35
34
  import { z } from "zod";
36
35
  import type { Prisma } from "@allbluecn/database";
37
- import { requireAuth } from "@/server/auth-helpers";
36
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
38
37
  import {
39
38
  RUN_CASE_TERMINAL_STATUSES,
40
39
  finalizeRunIfComplete,
@@ -121,12 +120,11 @@ const reportStepSchema = z.object({
121
120
  });
122
121
 
123
122
  export const reportStepFn = createServerFn({ method: "POST" })
123
+ .middleware([authContextMiddleware])
124
124
  .validator(reportStepSchema)
125
- .handler(async ({ data }) => {
125
+ .handler(async ({ data, context }) => {
126
126
  const prisma = await getPrisma();
127
- const request = getRequest();
128
- const session = await requireAuth(request);
129
- const userId = session.user.id;
127
+ const userId = context.user.id;
130
128
 
131
129
  const { row } = await loadReportContext(data.runCaseId, userId);
132
130
  if (!snapshotOrders(row.caseSnapshot).has(data.order)) {
@@ -170,12 +168,11 @@ const reportResultSchema = z.object({
170
168
  });
171
169
 
172
170
  export const reportResultFn = createServerFn({ method: "POST" })
171
+ .middleware([authContextMiddleware])
173
172
  .validator(reportResultSchema)
174
- .handler(async ({ data }) => {
173
+ .handler(async ({ data, context }) => {
175
174
  const prisma = await getPrisma();
176
- const request = getRequest();
177
- const session = await requireAuth(request);
178
- const userId = session.user.id;
175
+ const userId = context.user.id;
179
176
 
180
177
  const { row, run } = await loadReportContext(data.runCaseId, userId);
181
178
  const now = new Date();
@@ -242,12 +239,11 @@ const addEvidenceSchema = z.object({
242
239
  });
243
240
 
244
241
  export const addEvidenceFn = createServerFn({ method: "POST" })
242
+ .middleware([authContextMiddleware])
245
243
  .validator(addEvidenceSchema)
246
- .handler(async ({ data }) => {
244
+ .handler(async ({ data, context }) => {
247
245
  const prisma = await getPrisma();
248
- const request = getRequest();
249
- const session = await requireAuth(request);
250
- const userId = session.user.id;
246
+ const userId = context.user.id;
251
247
 
252
248
  const { row } = await loadReportContext(data.runCaseId, userId);
253
249
  if (!snapshotOrders(row.caseSnapshot).has(data.order)) {
@@ -311,12 +307,11 @@ const RUN_CASE_EXECUTION_SELECT = {
311
307
  const idSchema = z.object({ id: z.string().min(1) });
312
308
 
313
309
  export const getRunCaseFn = createServerFn({ method: "GET" })
310
+ .middleware([authContextMiddleware])
314
311
  .validator(idSchema)
315
- .handler(async ({ data }) => {
312
+ .handler(async ({ data, context }) => {
316
313
  const prisma = await getPrisma();
317
- const request = getRequest();
318
- const session = await requireAuth(request);
319
- await assertRunCaseProjectMember(data.id, session.user.id);
314
+ await assertRunCaseProjectMember(data.id, context.user.id);
320
315
 
321
316
  const row = await prisma.testRunCase.findUnique({
322
317
  where: { id: data.id },
@@ -31,10 +31,9 @@
31
31
  // 本文件只准导出 createServerFn 产物(serverFn 纯净铁律),select/cast/校验均为文件内私有。
32
32
  import { getPrisma } from "@allbluecn/database/get-prisma";
33
33
  import { createServerFn } from "@tanstack/react-start";
34
- import { getRequest } from "@tanstack/react-start/server";
35
34
  import { z } from "zod";
36
35
  import type { Prisma } from "@allbluecn/database";
37
- import { requireAuth } from "@/server/auth-helpers";
36
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
38
37
  import { resolveStoryScopeProjectId } from "@/server/builtin-project";
39
38
  import { buildCaseSnapshot } from "@/server/testcase/snapshot";
40
39
  import { USER_BRIEF_SELECT, castUserBrief } from "@/server/story/user-brief";
@@ -201,12 +200,11 @@ const createRunSchema = z
201
200
  });
202
201
 
203
202
  export const createRunFn = createServerFn({ method: "POST" })
203
+ .middleware([authContextMiddleware])
204
204
  .validator(createRunSchema)
205
- .handler(async ({ data }) => {
205
+ .handler(async ({ data, context }) => {
206
206
  const prisma = await getPrisma();
207
- const request = getRequest();
208
- const session = await requireAuth(request);
209
- const userId = session.user.id;
207
+ const userId = context.user.id;
210
208
 
211
209
  // 审计 A3x-2 跨批收口:targetEnv 为 http(s) 时直用为 e2e 浏览器导航目标,
212
210
  // 服务端浏览器访问用户可控 URL 须经 fetch-guard(私网放行仅 desktop / 显式 env,同 browser-policy)
@@ -377,12 +375,11 @@ export const createRunFn = createServerFn({ method: "POST" })
377
375
  const idSchema = z.object({ id: z.string().min(1) });
378
376
 
379
377
  export const abortRunFn = createServerFn({ method: "POST" })
378
+ .middleware([authContextMiddleware])
380
379
  .validator(idSchema)
381
- .handler(async ({ data }) => {
380
+ .handler(async ({ data, context }) => {
382
381
  const prisma = await getPrisma();
383
- const request = getRequest();
384
- const session = await requireAuth(request);
385
- const userId = session.user.id;
382
+ const userId = context.user.id;
386
383
 
387
384
  const existing = await prisma.testRun.findUnique({
388
385
  where: { id: data.id },
@@ -415,12 +412,11 @@ export const abortRunFn = createServerFn({ method: "POST" })
415
412
  // ── 详情(含执行矩阵行;渲染数据源是 caseSnapshot——审查重点 1 的读取面)──
416
413
 
417
414
  export const getRunFn = createServerFn({ method: "GET" })
415
+ .middleware([authContextMiddleware])
418
416
  .validator(idSchema)
419
- .handler(async ({ data }) => {
417
+ .handler(async ({ data, context }) => {
420
418
  const prisma = await getPrisma();
421
- const request = getRequest();
422
- const session = await requireAuth(request);
423
- await assertTestRunProjectMember(data.id, session.user.id);
419
+ await assertTestRunProjectMember(data.id, context.user.id);
424
420
  const row = await prisma.testRun.findUnique({
425
421
  where: { id: data.id },
426
422
  select: RUN_DETAIL_SELECT,
@@ -442,12 +438,11 @@ const listRunsSchema = z.object({
442
438
  });
443
439
 
444
440
  export const listRunsFn = createServerFn({ method: "GET" })
441
+ .middleware([authContextMiddleware])
445
442
  .validator(listRunsSchema)
446
- .handler(async ({ data }) => {
443
+ .handler(async ({ data, context }) => {
447
444
  const prisma = await getPrisma();
448
- const request = getRequest();
449
- const session = await requireAuth(request);
450
- const userId = session.user.id;
445
+ const userId = context.user.id;
451
446
 
452
447
  // scope 解析:未传/无效/非成员 → 静默回退独立项目,防越权查询(同 listPlansFn)
453
448
  const projectId = await resolveStoryScopeProjectId(data.projectId, userId);
@@ -38,9 +38,8 @@
38
38
  // 本文件只准导出 createServerFn 产物(serverFn 纯净铁律),成员校验/cast 文件内私有。
39
39
  import { getPrisma } from "@allbluecn/database/get-prisma";
40
40
  import { createServerFn } from "@tanstack/react-start";
41
- import { getRequest } from "@tanstack/react-start/server";
42
41
  import { z } from "zod";
43
- import { requireAuth } from "@/server/auth-helpers";
42
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
44
43
  import { resolveStoryScopeProjectId } from "@/server/builtin-project";
45
44
  // 同目录模块统一相对路径单条 import(审计 🟢:拆成绝对自引 + 相对两条易漂移)
46
45
  import { FAILURE_CATEGORY_VALUES, type RunCaseStatus } from "./constants";
@@ -56,18 +55,17 @@ const storyIdSchema = z.object({ storyId: z.string().min(1) });
56
55
  // ── 需求变更过期判定 ──
57
56
 
58
57
  export const getStoryStalenessFn = createServerFn({ method: "GET" })
58
+ .middleware([authContextMiddleware])
59
59
  .validator(storyIdSchema)
60
- .handler(async ({ data }) => {
60
+ .handler(async ({ data, context }) => {
61
61
  const prisma = await getPrisma();
62
- const request = getRequest();
63
- const session = await requireAuth(request);
64
62
 
65
63
  const story = await prisma.story.findUnique({
66
64
  where: { id: data.storyId },
67
65
  select: { id: true, projectId: true, updatedAt: true },
68
66
  });
69
67
  if (!story) throw new Error("需求不存在");
70
- await assertProjectMembership(story.projectId, session.user.id);
68
+ await assertProjectMembership(story.projectId, context.user.id);
71
69
 
72
70
  // 窄口径:需求「内容」(描述/标题)最后编辑时间 vs 最新关联用例创建时间。
73
71
  // 从 storyActivity 的 content_edited 时间锚推导(web 直写与 collab exporter
@@ -100,18 +98,17 @@ export const getStoryStalenessFn = createServerFn({ method: "GET" })
100
98
  // ── 生成批次采纳率统计 ──
101
99
 
102
100
  export const listGenerationStatsFn = createServerFn({ method: "GET" })
101
+ .middleware([authContextMiddleware])
103
102
  .validator(storyIdSchema)
104
- .handler(async ({ data }) => {
103
+ .handler(async ({ data, context }) => {
105
104
  const prisma = await getPrisma();
106
- const request = getRequest();
107
- const session = await requireAuth(request);
108
105
 
109
106
  const story = await prisma.story.findUnique({
110
107
  where: { id: data.storyId },
111
108
  select: { id: true, projectId: true },
112
109
  });
113
110
  if (!story) throw new Error("需求不存在");
114
- await assertProjectMembership(story.projectId, session.user.id);
111
+ await assertProjectMembership(story.projectId, context.user.id);
115
112
 
116
113
  const rows = await prisma.testGenerationRun.findMany({
117
114
  where: { storyId: data.storyId },
@@ -150,12 +147,11 @@ const TREND_DAYS = 30;
150
147
  const projectStatsSchema = z.object({ projectId: z.string().min(1).optional() });
151
148
 
152
149
  export const getProjectTestStatsFn = createServerFn({ method: "GET" })
150
+ .middleware([authContextMiddleware])
153
151
  .validator(projectStatsSchema)
154
- .handler(async ({ data }): Promise<ProjectTestStats> => {
152
+ .handler(async ({ data, context }): Promise<ProjectTestStats> => {
155
153
  const prisma = await getPrisma();
156
- const request = getRequest();
157
- const session = await requireAuth(request);
158
- const projectId = await resolveStoryScopeProjectId(data.projectId, session.user.id);
154
+ const projectId = await resolveStoryScopeProjectId(data.projectId, context.user.id);
159
155
 
160
156
  const since = new Date(Date.now() - TREND_DAYS * 24 * 60 * 60 * 1000);
161
157
  const [trendRows, genAgg, automationRows, flakyRows] = await Promise.all([
@@ -248,18 +244,17 @@ function castTriage(raw: unknown): RunFailureTriage | null {
248
244
  }
249
245
 
250
246
  export const listRunFailuresFn = createServerFn({ method: "GET" })
247
+ .middleware([authContextMiddleware])
251
248
  .validator(idSchema)
252
- .handler(async ({ data }) => {
249
+ .handler(async ({ data, context }) => {
253
250
  const prisma = await getPrisma();
254
- const request = getRequest();
255
- const session = await requireAuth(request);
256
251
 
257
252
  const run = await prisma.testRun.findUnique({
258
253
  where: { id: data.id },
259
254
  select: { id: true, projectId: true },
260
255
  });
261
256
  if (!run) throw new Error("执行批次不存在");
262
- await assertProjectMembership(run.projectId, session.user.id);
257
+ await assertProjectMembership(run.projectId, context.user.id);
263
258
 
264
259
  const rows = await prisma.testRunCase.findMany({
265
260
  where: { runId: run.id, status: { in: ["failed", "blocked"] } },
@@ -22,9 +22,8 @@
22
22
  // story 域 types 的单一事实源(activities.ts 先例)。
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 { assertTestCaseProjectMember } from "@/server/testcase/permissions";
29
28
  import { USER_BRIEF_SELECT, castUserBrief } from "@/server/story/user-brief";
30
29
  import type { TestCaseActivityItem } from "./types";
@@ -35,12 +34,11 @@ const listActivitiesSchema = z.object({
35
34
  });
36
35
 
37
36
  export const listTestCaseActivitiesFn = createServerFn({ method: "GET" })
37
+ .middleware([authContextMiddleware])
38
38
  .validator(listActivitiesSchema)
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
- await assertTestCaseProjectMember(data.caseId, session.user.id);
41
+ await assertTestCaseProjectMember(data.caseId, context.user.id);
44
42
 
45
43
  const rows = await prisma.projectActivity.findMany({
46
44
  where: { targetType: "testcase", targetId: data.caseId },
@@ -24,10 +24,9 @@
24
24
  // 未归档用例,归档是「回收站」语义不进板)。
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
28
  import type { Prisma } from "@allbluecn/database";
30
- import { requireAuth } from "@/server/auth-helpers";
29
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
31
30
  import { resolveStoryScopeProjectIds } from "@/server/builtin-project";
32
31
  import { buildListWhere } from "@/server/testcase/list-query";
33
32
  import { USER_BRIEF_SELECT, castUserBrief } from "@/server/story/user-brief";
@@ -134,12 +133,11 @@ const boardSchema = z.object({
134
133
  });
135
134
 
136
135
  export const listTestCaseBoardColumnsFn = createServerFn({ method: "GET" })
136
+ .middleware([authContextMiddleware])
137
137
  .validator(boardSchema)
138
- .handler(async ({ data }) => {
138
+ .handler(async ({ data, context }) => {
139
139
  const prisma = await getPrisma();
140
- const request = getRequest();
141
- const session = await requireAuth(request);
142
- const userId = session.user.id;
140
+ const userId = context.user.id;
143
141
 
144
142
  const projectIds = await resolveStoryScopeProjectIds(data.projectId, userId);
145
143
  const base = buildListWhere({
@@ -25,10 +25,9 @@
25
25
  // 实际变更才 +1;state/automation/assignee/folder/story 等元数据变更不 bump(规格 §3:快照只锁内容)。
26
26
  import { getPrisma } from "@allbluecn/database/get-prisma";
27
27
  import { createServerFn } from "@tanstack/react-start";
28
- import { getRequest } from "@tanstack/react-start/server";
29
28
  import { z } from "zod";
30
29
  import type { Prisma } from "@allbluecn/database";
31
- import { requireAuth } from "@/server/auth-helpers";
30
+ import { authContextMiddleware } from "@/server/middlewares/auth-context"
32
31
  import { resolveStoryScopeProjectIds } from "@/server/builtin-project";
33
32
  import { buildListWhere } from "@/server/testcase/list-query";
34
33
  import { validateAssignee } from "@/server/lib/validate-assignee";
@@ -158,12 +157,11 @@ const listSchema = z.object({
158
157
  });
159
158
 
160
159
  export const listTestCasesFn = createServerFn({ method: "GET" })
160
+ .middleware([authContextMiddleware])
161
161
  .validator(listSchema)
162
- .handler(async ({ data }) => {
162
+ .handler(async ({ data, context }) => {
163
163
  const prisma = await getPrisma();
164
- const request = getRequest();
165
- const session = await requireAuth(request);
166
- const userId = session.user.id;
164
+ const userId = context.user.id;
167
165
 
168
166
  // scope 解析(同 story/story-groups 与 bug 域):未传 → 成员关系全部项目聚合;
169
167
  // 单项目经鉴权(无效/非成员 → 静默回退独立项目),防越权查询
@@ -209,12 +207,11 @@ export const listTestCasesFn = createServerFn({ method: "GET" })
209
207
  const MAX_RETRIES = 5;
210
208
 
211
209
  export const createTestCaseFn = createServerFn({ method: "POST" })
210
+ .middleware([authContextMiddleware])
212
211
  .validator(CreateTestCaseInputSchema)
213
- .handler(async ({ data }) => {
212
+ .handler(async ({ data, context }) => {
214
213
  const prisma = await getPrisma();
215
- const request = getRequest();
216
- const session = await requireAuth(request);
217
- const userId = session.user.id;
214
+ const userId = context.user.id;
218
215
 
219
216
  await assertProjectMembership(data.projectId, userId);
220
217
  await assertFolderInProject(data.projectId, data.folderId);
@@ -324,12 +321,11 @@ const CASE_Y_UPDATE_KEYS = new Set([
324
321
  ]);
325
322
 
326
323
  export const updateTestCaseFn = createServerFn({ method: "POST" })
324
+ .middleware([authContextMiddleware])
327
325
  .validator(UpdateTestCaseInputSchema)
328
- .handler(async ({ data }) => {
326
+ .handler(async ({ data, context }) => {
329
327
  const prisma = await getPrisma();
330
- const request = getRequest();
331
- const session = await requireAuth(request);
332
- const userId = session.user.id;
328
+ const userId = context.user.id;
333
329
 
334
330
  // ── Yjs 多人协作 §5.3 写入门卫(任务 22;T21 教训:提至 $transaction
335
331
  // 之前——门卫转发含网络 I/O(TTL 内重试最坏 ≈4s),事务内等待会击穿
@@ -474,7 +470,7 @@ export const updateTestCaseFn = createServerFn({ method: "POST" })
474
470
  return castTestCase(updated);
475
471
  });
476
472
 
477
- // ── 详情(A12 详情页 loader):列表 select + 关联需求引用;读门槛 requireAuth(同 getStoryDetailFn)──
473
+ // ── 详情(A12 详情页 loader):列表 select + 关联需求引用;读门槛 authContextMiddleware(同 getStoryDetailFn)──
478
474
 
479
475
  const idSchema = z.object({ id: z.string().min(1) });
480
476
 
@@ -494,12 +490,11 @@ function castTestCaseDetail(row: TestCaseDetailRow): TestCaseDetail {
494
490
  }
495
491
 
496
492
  export const getTestCaseFn = createServerFn({ method: "GET" })
493
+ .middleware([authContextMiddleware])
497
494
  .validator(idSchema)
498
- .handler(async ({ data }) => {
495
+ .handler(async ({ data, context }) => {
499
496
  const prisma = await getPrisma();
500
- const request = getRequest();
501
- const session = await requireAuth(request);
502
- await assertTestCaseProjectMember(data.id, session.user.id);
497
+ await assertTestCaseProjectMember(data.id, context.user.id);
503
498
  const row = await prisma.testCase.findUnique({
504
499
  where: { id: data.id },
505
500
  select: TEST_CASE_DETAIL_SELECT,
@@ -511,12 +506,11 @@ export const getTestCaseFn = createServerFn({ method: "GET" })
511
506
  // ── 归档 / 删除 ──
512
507
 
513
508
  export const archiveTestCaseFn = createServerFn({ method: "POST" })
509
+ .middleware([authContextMiddleware])
514
510
  .validator(idSchema)
515
- .handler(async ({ data }) => {
511
+ .handler(async ({ data, context }) => {
516
512
  const prisma = await getPrisma();
517
- const request = getRequest();
518
- const session = await requireAuth(request);
519
- const userId = session.user.id;
513
+ const userId = context.user.id;
520
514
 
521
515
  const existing = await prisma.testCase.findUnique({
522
516
  where: { id: data.id },
@@ -545,12 +539,11 @@ export const archiveTestCaseFn = createServerFn({ method: "POST" })
545
539
  });
546
540
 
547
541
  export const deleteTestCaseFn = createServerFn({ method: "POST" })
542
+ .middleware([authContextMiddleware])
548
543
  .validator(idSchema)
549
- .handler(async ({ data }) => {
544
+ .handler(async ({ data, context }) => {
550
545
  const prisma = await getPrisma();
551
- const request = getRequest();
552
- const session = await requireAuth(request);
553
- const userId = session.user.id;
546
+ const userId = context.user.id;
554
547
 
555
548
  const existing = await prisma.testCase.findUnique({
556
549
  where: { id: data.id },