@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,12 +16,10 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
22
  import { Prisma } from '@allbluecn/database'
23
- import { getServerSeam } from '@allbluecn/kernel'
24
- import { sessionUserId } from '@/server/design/access'
25
23
 
26
24
  const listSchema = z.object({
27
25
  take: z.number().int().min(1).max(100).default(20),
@@ -29,12 +27,11 @@ const listSchema = z.object({
29
27
  })
30
28
 
31
29
  export const listDesignsFn = createServerFn({ method: 'GET' })
30
+ .middleware([authContextMiddleware])
32
31
  .validator(listSchema)
33
- .handler(async ({ data }) => {
32
+ .handler(async ({ data, context }) => {
34
33
  const prisma = await getPrisma()
35
- const request = getRequest()
36
- const session = await getServerSeam().requireAuth(request)
37
- const userId = sessionUserId(session)
34
+ const userId = context.user.id
38
35
  return prisma.design.findMany({
39
36
  where: { userId, isDeleted: false },
40
37
  orderBy: { createdAt: 'desc' },
@@ -59,11 +56,10 @@ const createSchema = z.object({
59
56
  })
60
57
 
61
58
  export const createDesignFn = createServerFn({ method: 'POST' })
59
+ .middleware([authContextMiddleware])
62
60
  .validator(createSchema)
63
- .handler(async ({ data }) => {
61
+ .handler(async ({ data, context }) => {
64
62
  const prisma = await getPrisma()
65
- const request = getRequest()
66
- const session = await getServerSeam().requireAuth(request)
67
63
  // 服务端同步建首页:否则首个 page 依赖左栏页面树挂载时自动创建,
68
64
  // 左栏折叠(localStorage.designLeftPanelOpen 持久化)时首页永不创建,
69
65
  // activePageId 恒 null,保存链路静默跳过,编辑内容全丢。
@@ -74,7 +70,7 @@ export const createDesignFn = createServerFn({ method: 'POST' })
74
70
  icon: data.icon,
75
71
  name: data.name,
76
72
  description: data.description,
77
- userId: sessionUserId(session),
73
+ userId: context.user.id,
78
74
  pages: {
79
75
  create: {
80
76
  name: data.homeName ?? '首页',
@@ -103,15 +99,14 @@ const updateSchema = z.object({
103
99
  })
104
100
 
105
101
  export const updateDesignFn = createServerFn({ method: 'POST' })
102
+ .middleware([authContextMiddleware])
106
103
  .validator(updateSchema)
107
- .handler(async ({ data }) => {
104
+ .handler(async ({ data, context }) => {
108
105
  const prisma = await getPrisma()
109
- const request = getRequest()
110
- const session = await getServerSeam().requireAuth(request)
111
106
  // DB-03:属主校验合并进写入(updateMany 计数判定),1 次查询替代 2 次
112
107
  const { id: _id, ...rest } = data
113
108
  const res = await prisma.design.updateMany({
114
- where: { id: data.id, userId: sessionUserId(session), isDeleted: false },
109
+ where: { id: data.id, userId: context.user.id, isDeleted: false },
115
110
  data: rest,
116
111
  })
117
112
  if (res.count === 0) throw new Error('未找到或无权限')
@@ -119,14 +114,13 @@ export const updateDesignFn = createServerFn({ method: 'POST' })
119
114
  })
120
115
 
121
116
  export const deleteDesignFn = createServerFn({ method: 'POST' })
117
+ .middleware([authContextMiddleware])
122
118
  .validator(z.object({ id: z.string() }))
123
- .handler(async ({ data }) => {
119
+ .handler(async ({ data, context }) => {
124
120
  const prisma = await getPrisma()
125
- const request = getRequest()
126
- const session = await getServerSeam().requireAuth(request)
127
121
  // DB-03:属主校验合并进写入;where 不含 isDeleted 与原 findFirst 口径一致(重复软删幂等刷新 deletedAt)
128
122
  const res = await prisma.design.updateMany({
129
- where: { id: data.id, userId: sessionUserId(session) },
123
+ where: { id: data.id, userId: context.user.id },
130
124
  data: { isDeleted: true, deletedAt: new Date() },
131
125
  })
132
126
  if (res.count === 0) throw new Error('未找到或无权限')
@@ -16,11 +16,10 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
- import { getServerSeam } from '@allbluecn/kernel'
23
- import { assertPageOwner, assertPageVersionOwner, sessionUserId } from '@/server/design/access'
22
+ import { assertPageOwner, assertPageVersionOwner } from '@/server/design/access'
24
23
  import { toNullableJsonInput } from '@/server/lib/prisma-json'
25
24
 
26
25
  const VERSION_NOTES_MAX = 500
@@ -28,14 +27,14 @@ const VERSION_NOTES_MAX = 500
28
27
  // 页面版本(快照)全部经 page.design.userId 归属校验:读写一律仅属主。
29
28
 
30
29
  export const listDesignPageVersionsFn = createServerFn({ method: 'GET' })
30
+ .middleware([authContextMiddleware])
31
31
  .validator(z.object({
32
32
  pageId: z.string(),
33
33
  limit: z.number().int().min(1).optional(),
34
34
  }))
35
- .handler(async ({ data }) => {
35
+ .handler(async ({ data, context }) => {
36
36
  const prisma = await getPrisma()
37
- const request = getRequest()
38
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
37
+ const userId = context.user.id
39
38
  await assertPageOwner(data.pageId, userId)
40
39
 
41
40
  return prisma.pageVersion.findMany({
@@ -47,11 +46,11 @@ export const listDesignPageVersionsFn = createServerFn({ method: 'GET' })
47
46
  })
48
47
 
49
48
  export const getDesignPageVersionFn = createServerFn({ method: 'GET' })
49
+ .middleware([authContextMiddleware])
50
50
  .validator(z.object({ pageVersionId: z.string() }))
51
- .handler(async ({ data }) => {
51
+ .handler(async ({ data, context }) => {
52
52
  const prisma = await getPrisma()
53
- const request = getRequest()
54
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
53
+ const userId = context.user.id
55
54
  await assertPageVersionOwner(data.pageVersionId, userId)
56
55
 
57
56
  const pageVersion = await prisma.pageVersion.findUnique({
@@ -64,6 +63,7 @@ export const getDesignPageVersionFn = createServerFn({ method: 'GET' })
64
63
  })
65
64
 
66
65
  export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
66
+ .middleware([authContextMiddleware])
67
67
  .validator(z.object({
68
68
  pageId: z.string(),
69
69
  notes: z.string().optional(),
@@ -71,10 +71,9 @@ export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
71
71
  content: z.unknown().optional(),
72
72
  restoredFromVersion: z.number().int().optional(),
73
73
  }))
74
- .handler(async ({ data }) => {
74
+ .handler(async ({ data, context }) => {
75
75
  const prisma = await getPrisma()
76
- const request = getRequest()
77
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
76
+ const userId = context.user.id
78
77
  await assertPageOwner(data.pageId, userId)
79
78
 
80
79
  if (data.notes && data.notes.length > VERSION_NOTES_MAX) {
@@ -117,16 +116,16 @@ export const createDesignPageVersionFn = createServerFn({ method: 'POST' })
117
116
  })
118
117
 
119
118
  export const updateDesignPageVersionFn = createServerFn({ method: 'POST' })
119
+ .middleware([authContextMiddleware])
120
120
  .validator(z.object({
121
121
  pageVersionId: z.string(),
122
122
  notes: z.string().optional(),
123
123
  canvas: z.unknown().optional(),
124
124
  content: z.unknown().optional(),
125
125
  }))
126
- .handler(async ({ data }) => {
126
+ .handler(async ({ data, context }) => {
127
127
  const prisma = await getPrisma()
128
- const request = getRequest()
129
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
128
+ const userId = context.user.id
130
129
  await assertPageVersionOwner(data.pageVersionId, userId)
131
130
 
132
131
  if (data.notes && data.notes.length > VERSION_NOTES_MAX) {
@@ -144,11 +143,11 @@ export const updateDesignPageVersionFn = createServerFn({ method: 'POST' })
144
143
  })
145
144
 
146
145
  export const deleteDesignPageVersionFn = createServerFn({ method: 'POST' })
146
+ .middleware([authContextMiddleware])
147
147
  .validator(z.object({ pageVersionId: z.string() }))
148
- .handler(async ({ data }) => {
148
+ .handler(async ({ data, context }) => {
149
149
  const prisma = await getPrisma()
150
- const request = getRequest()
151
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
150
+ const userId = context.user.id
152
151
  await assertPageVersionOwner(data.pageVersionId, userId)
153
152
 
154
153
  await prisma.pageVersion.delete({
@@ -16,24 +16,23 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
22
  import { Prisma } from '@allbluecn/database'
23
- import { getServerSeam } from '@allbluecn/kernel'
24
23
  import { buildRoomName } from '@allbluecn/collab-core/rooms'
25
24
  import { withCollabGuard } from '@/server/collab/write-guard'
26
- import { assertDesignOwner, assertPageOwner, sessionUserId } from '@/server/design/access'
25
+ import { assertDesignOwner, assertPageOwner } from '@/server/design/access'
27
26
 
28
27
  export const listDesignPagesFn = createServerFn({ method: 'GET' })
28
+ .middleware([authContextMiddleware])
29
29
  .validator(z.object({
30
30
  designId: z.string(),
31
31
  take: z.number().int().min(1).max(200).default(50),
32
32
  }))
33
- .handler(async ({ data }) => {
33
+ .handler(async ({ data, context }) => {
34
34
  const prisma = await getPrisma()
35
- const request = getRequest()
36
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
35
+ const userId = context.user.id
37
36
  await assertDesignOwner(data.designId, userId)
38
37
  return prisma.designPage.findMany({
39
38
  where: { designId: data.designId },
@@ -44,16 +43,16 @@ export const listDesignPagesFn = createServerFn({ method: 'GET' })
44
43
  })
45
44
 
46
45
  export const createDesignPageFn = createServerFn({ method: 'POST' })
46
+ .middleware([authContextMiddleware])
47
47
  .validator(z.object({
48
48
  designId: z.string(),
49
49
  name: z.string().optional(),
50
50
  type: z.string(),
51
51
  parentId: z.string().nullable().optional(),
52
52
  }))
53
- .handler(async ({ data }) => {
53
+ .handler(async ({ data, context }) => {
54
54
  const prisma = await getPrisma()
55
- const request = getRequest()
56
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
55
+ const userId = context.user.id
57
56
  await assertDesignOwner(data.designId, userId)
58
57
  const maxOrder = await prisma.designPage.aggregate({
59
58
  where: { designId: data.designId, parentId: data.parentId ?? null },
@@ -87,6 +86,7 @@ export const createDesignPageFn = createServerFn({ method: 'POST' })
87
86
  })
88
87
 
89
88
  export const updateDesignPageFn = createServerFn({ method: 'POST' })
89
+ .middleware([authContextMiddleware])
90
90
  .validator(z.object({
91
91
  pageId: z.string(),
92
92
  name: z.string().optional(),
@@ -95,10 +95,9 @@ export const updateDesignPageFn = createServerFn({ method: 'POST' })
95
95
  canvas: z.any().optional(),
96
96
  content: z.any().optional(),
97
97
  }))
98
- .handler(async ({ data }) => {
98
+ .handler(async ({ data, context }) => {
99
99
  const prisma = await getPrisma()
100
- const request = getRequest()
101
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
100
+ const userId = context.user.id
102
101
  // §5.3 写入门卫(任务 29):Y 属主面 = canvas(整场景 replace 语义)+
103
102
  // content(文档 fragment 面)。快照存在 → 转发 collab 内部通道(活跃判定
104
103
  // 在 collab 侧);无快照 pass-through、不可达 TTL 降级 → 照旧直写(非协同
@@ -168,11 +167,11 @@ export const updateDesignPageFn = createServerFn({ method: 'POST' })
168
167
  })
169
168
 
170
169
  export const deleteDesignPageFn = createServerFn({ method: 'POST' })
170
+ .middleware([authContextMiddleware])
171
171
  .validator(z.object({ pageId: z.string() }))
172
- .handler(async ({ data }) => {
172
+ .handler(async ({ data, context }) => {
173
173
  const prisma = await getPrisma()
174
- const request = getRequest()
175
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
174
+ const userId = context.user.id
176
175
  await assertPageOwner(data.pageId, userId)
177
176
  await prisma.$transaction(async (tx) => {
178
177
  const descendants = await tx.$queryRaw<Array<{ id: string }>>`
@@ -197,11 +196,11 @@ export const deleteDesignPageFn = createServerFn({ method: 'POST' })
197
196
  })
198
197
 
199
198
  export const getDesignPageFn = createServerFn({ method: 'GET' })
199
+ .middleware([authContextMiddleware])
200
200
  .validator(z.object({ pageId: z.string() }))
201
- .handler(async ({ data }) => {
201
+ .handler(async ({ data, context }) => {
202
202
  const prisma = await getPrisma()
203
- const request = getRequest()
204
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
203
+ const userId = context.user.id
205
204
  // DB-03:属主校验(经 design.userId 关系过滤)与读取合并为单查询
206
205
  const page = await prisma.designPage.findFirst({
207
206
  where: { id: data.pageId, design: { userId } },
@@ -16,11 +16,10 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
- import { getServerSeam } from '@allbluecn/kernel'
23
- import { assertDesignReadable, sessionUserId } from '@/server/design/access'
22
+ import { assertDesignReadable } from '@/server/design/access'
24
23
 
25
24
  const upsertReviewSchema = z.object({
26
25
  designId: z.string(),
@@ -30,11 +29,11 @@ const upsertReviewSchema = z.object({
30
29
  })
31
30
 
32
31
  export const upsertReviewFn = createServerFn({ method: 'POST' })
32
+ .middleware([authContextMiddleware])
33
33
  .validator(upsertReviewSchema)
34
- .handler(async ({ data }) => {
34
+ .handler(async ({ data, context }) => {
35
35
  const prisma = await getPrisma()
36
- const request = getRequest()
37
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
36
+ const userId = context.user.id
38
37
  // 审批由分享页评审面板发起(ShareReviewPanel):属主与通过门禁的分享访客(需登录)皆可评审,
39
38
  // 不能收成属主专用;versionId 必须属于同一 design,否则可借他人 versionId 污染审批记录
40
39
  await assertDesignReadable(data.designId, userId)
@@ -83,11 +82,11 @@ const getReviewSchema = z.object({
83
82
  })
84
83
 
85
84
  export const getReviewFn = createServerFn({ method: 'GET' })
85
+ .middleware([authContextMiddleware])
86
86
  .validator(getReviewSchema)
87
- .handler(async ({ data }) => {
87
+ .handler(async ({ data, context }) => {
88
88
  const prisma = await getPrisma()
89
- const request = getRequest()
90
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
89
+ const userId = context.user.id
91
90
  await assertDesignReadable(data.designId, userId)
92
91
 
93
92
  const review = await prisma.review.findFirst({
@@ -16,25 +16,22 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
22
  import type { Prisma } from '@allbluecn/database'
23
- import { getServerSeam } from '@allbluecn/kernel'
24
23
  import { notifyClients } from '@/lib/share-events'
25
24
  import { verifyDesignOwner } from '@allbluecn/database/lib/share-utils'
26
- import { sessionUserId } from '@/server/design/access'
27
25
  import { generateSharePassword, hashSharePassword } from '@/server/design/share-generate'
28
26
 
29
27
  export const setDesignSharePasswordFn = createServerFn({ method: 'POST' })
28
+ .middleware([authContextMiddleware])
30
29
  .validator(z.object({ designId: z.string() }))
31
- .handler(async ({ data }) => {
30
+ .handler(async ({ data, context }) => {
32
31
  const prisma = await getPrisma()
33
- const request = getRequest()
34
- const session = await getServerSeam().requireAuth(request)
35
32
  const { designId } = data
36
33
 
37
- if (!(await verifyDesignOwner(designId, sessionUserId(session)))) {
34
+ if (!(await verifyDesignOwner(designId, context.user.id))) {
38
35
  throw new Error("无权限")
39
36
  }
40
37
 
@@ -65,14 +62,13 @@ export const setDesignSharePasswordFn = createServerFn({ method: 'POST' })
65
62
  // 关闭密码仅置 hasPassword=false、password 列保留旧值(重开沿用旧密码)——
66
63
  // 有意设计:shareGatePassed 以 hasPassword 为权威开关(见 @/server/design/share-access)
67
64
  export const toggleDesignSharePasswordFn = createServerFn({ method: 'POST' })
65
+ .middleware([authContextMiddleware])
68
66
  .validator(z.object({ designId: z.string(), enabled: z.boolean() }))
69
- .handler(async ({ data }) => {
67
+ .handler(async ({ data, context }) => {
70
68
  const prisma = await getPrisma()
71
- const request = getRequest()
72
- const session = await getServerSeam().requireAuth(request)
73
69
  const { designId, enabled } = data
74
70
 
75
- if (!(await verifyDesignOwner(designId, sessionUserId(session)))) {
71
+ if (!(await verifyDesignOwner(designId, context.user.id))) {
76
72
  throw new Error("无权限")
77
73
  }
78
74
 
@@ -110,11 +106,10 @@ export const toggleDesignSharePasswordFn = createServerFn({ method: 'POST' })
110
106
  })
111
107
 
112
108
  export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
109
+ .middleware([authContextMiddleware])
113
110
  .validator(z.object({ shareId: z.string() }))
114
- .handler(async ({ data }) => {
111
+ .handler(async ({ data, context }) => {
115
112
  const prisma = await getPrisma()
116
- const request = getRequest()
117
- const session = await getServerSeam().requireAuth(request)
118
113
  const { shareId } = data
119
114
 
120
115
  const share = await prisma.share.findUnique({
@@ -126,7 +121,7 @@ export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
126
121
  throw new Error("Share not found")
127
122
  }
128
123
  // IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
129
- if (!(await verifyDesignOwner(share.designId, sessionUserId(session)))) {
124
+ if (!(await verifyDesignOwner(share.designId, context.user.id))) {
130
125
  throw new Error("无权限")
131
126
  }
132
127
 
@@ -156,11 +151,10 @@ export const setDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
156
151
  })
157
152
 
158
153
  export const toggleDesignSingleSharePasswordFn = createServerFn({ method: 'POST' })
154
+ .middleware([authContextMiddleware])
159
155
  .validator(z.object({ shareId: z.string(), enabled: z.boolean() }))
160
- .handler(async ({ data }) => {
156
+ .handler(async ({ data, context }) => {
161
157
  const prisma = await getPrisma()
162
- const request = getRequest()
163
- const session = await getServerSeam().requireAuth(request)
164
158
  const { shareId, enabled } = data
165
159
 
166
160
  const share = await prisma.share.findUnique({
@@ -172,7 +166,7 @@ export const toggleDesignSingleSharePasswordFn = createServerFn({ method: 'POST'
172
166
  throw new Error("Share not found")
173
167
  }
174
168
  // IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
175
- if (!(await verifyDesignOwner(share.designId, sessionUserId(session)))) {
169
+ if (!(await verifyDesignOwner(share.designId, context.user.id))) {
176
170
  throw new Error("无权限")
177
171
  }
178
172
 
@@ -16,24 +16,21 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
22
  import type { Prisma } from '@allbluecn/database'
23
- import { getServerSeam } from '@allbluecn/kernel'
24
23
  import { notifyClients } from '@/lib/share-events'
25
24
  import { verifyDesignOwner } from '@allbluecn/database/lib/share-utils'
26
- import { sessionUserId } from '@/server/design/access'
27
25
  import { EXPIRY_DAYS, generateSharePassword, generateShareToken, hashSharePassword } from '@/server/design/share-generate'
28
26
 
29
27
  export const listDesignSharesFn = createServerFn({ method: 'GET' })
28
+ .middleware([authContextMiddleware])
30
29
  .validator(z.object({ designId: z.string() }))
31
- .handler(async ({ data }) => {
30
+ .handler(async ({ data, context }) => {
32
31
  const prisma = await getPrisma()
33
- const request = getRequest()
34
- const session = await getServerSeam().requireAuth(request)
35
32
 
36
- if (!(await verifyDesignOwner(data.designId, sessionUserId(session)))) {
33
+ if (!(await verifyDesignOwner(data.designId, context.user.id))) {
37
34
  throw new Error("无权限")
38
35
  }
39
36
 
@@ -51,6 +48,7 @@ export const listDesignSharesFn = createServerFn({ method: 'GET' })
51
48
  })
52
49
 
53
50
  export const createDesignShareFn = createServerFn({ method: 'POST' })
51
+ .middleware([authContextMiddleware])
54
52
  .validator(z.object({
55
53
  designId: z.string(),
56
54
  enabled: z.boolean().optional(),
@@ -58,13 +56,11 @@ export const createDesignShareFn = createServerFn({ method: 'POST' })
58
56
  versionIds: z.array(z.string()).optional(),
59
57
  expiryDays: z.string().optional(),
60
58
  }))
61
- .handler(async ({ data }) => {
59
+ .handler(async ({ data, context }) => {
62
60
  const prisma = await getPrisma()
63
- const request = getRequest()
64
- const session = await getServerSeam().requireAuth(request)
65
61
  const { designId, enabled, password, versionIds, expiryDays } = data
66
62
 
67
- if (!(await verifyDesignOwner(designId, sessionUserId(session)))) {
63
+ if (!(await verifyDesignOwner(designId, context.user.id))) {
68
64
  throw new Error("无权限")
69
65
  }
70
66
 
@@ -147,18 +143,17 @@ export const createDesignShareFn = createServerFn({ method: 'POST' })
147
143
  })
148
144
 
149
145
  export const listDesignSingleSharesFn = createServerFn({ method: 'GET' })
146
+ .middleware([authContextMiddleware])
150
147
  .validator(z.object({
151
148
  designId: z.string(),
152
149
  page: z.number().int().min(1).default(1),
153
150
  pageSize: z.number().int().min(1).max(200).default(50),
154
151
  }))
155
- .handler(async ({ data }) => {
152
+ .handler(async ({ data, context }) => {
156
153
  const prisma = await getPrisma()
157
- const request = getRequest()
158
- const session = await getServerSeam().requireAuth(request)
159
154
  const { designId, page, pageSize } = data
160
155
 
161
- if (!(await verifyDesignOwner(designId, sessionUserId(session)))) {
156
+ if (!(await verifyDesignOwner(designId, context.user.id))) {
162
157
  throw new Error("无权限")
163
158
  }
164
159
 
@@ -199,19 +194,18 @@ export const listDesignSingleSharesFn = createServerFn({ method: 'GET' })
199
194
  })
200
195
 
201
196
  export const createDesignSingleShareFn = createServerFn({ method: 'POST' })
197
+ .middleware([authContextMiddleware])
202
198
  .validator(z.object({
203
199
  designId: z.string(),
204
200
  versionId: z.string(),
205
201
  password: z.string().max(128).optional().nullable(),
206
202
  expiryDays: z.string().optional(),
207
203
  }))
208
- .handler(async ({ data }) => {
204
+ .handler(async ({ data, context }) => {
209
205
  const prisma = await getPrisma()
210
- const request = getRequest()
211
- const session = await getServerSeam().requireAuth(request)
212
206
  const { designId, versionId, password, expiryDays } = data
213
207
 
214
- if (!(await verifyDesignOwner(designId, sessionUserId(session)))) {
208
+ if (!(await verifyDesignOwner(designId, context.user.id))) {
215
209
  throw new Error("无权限")
216
210
  }
217
211
 
@@ -254,11 +248,10 @@ export const createDesignSingleShareFn = createServerFn({ method: 'POST' })
254
248
  })
255
249
 
256
250
  export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
251
+ .middleware([authContextMiddleware])
257
252
  .validator(z.object({ shareId: z.string() }))
258
- .handler(async ({ data }) => {
253
+ .handler(async ({ data, context }) => {
259
254
  const prisma = await getPrisma()
260
- const request = getRequest()
261
- const session = await getServerSeam().requireAuth(request)
262
255
  const share = await prisma.share.findUnique({
263
256
  where: { id: data.shareId },
264
257
  })
@@ -266,7 +259,7 @@ export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
266
259
  throw new Error("Share not found")
267
260
  }
268
261
  // IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
269
- if (!(await verifyDesignOwner(share.designId, sessionUserId(session)))) {
262
+ if (!(await verifyDesignOwner(share.designId, context.user.id))) {
270
263
  throw new Error("无权限")
271
264
  }
272
265
  // 密码哈希化后不回传(见 getDesignShareFn 注)
@@ -274,15 +267,14 @@ export const getDesignSingleShareFn = createServerFn({ method: 'GET' })
274
267
  })
275
268
 
276
269
  export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
270
+ .middleware([authContextMiddleware])
277
271
  .validator(z.object({
278
272
  shareId: z.string(),
279
273
  enabled: z.boolean().optional(),
280
274
  expiryDays: z.string().optional(),
281
275
  }))
282
- .handler(async ({ data }) => {
276
+ .handler(async ({ data, context }) => {
283
277
  const prisma = await getPrisma()
284
- const request = getRequest()
285
- const session = await getServerSeam().requireAuth(request)
286
278
  const { shareId, enabled, expiryDays } = data
287
279
 
288
280
  const share = await prisma.share.findUnique({
@@ -294,7 +286,7 @@ export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
294
286
  throw new Error("Share not found")
295
287
  }
296
288
  // IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
297
- if (!(await verifyDesignOwner(share.designId, sessionUserId(session)))) {
289
+ if (!(await verifyDesignOwner(share.designId, context.user.id))) {
298
290
  throw new Error("无权限")
299
291
  }
300
292
 
@@ -340,11 +332,10 @@ export const updateDesignSingleShareFn = createServerFn({ method: 'POST' })
340
332
  })
341
333
 
342
334
  export const deleteDesignSingleShareFn = createServerFn({ method: 'POST' })
335
+ .middleware([authContextMiddleware])
343
336
  .validator(z.object({ shareId: z.string() }))
344
- .handler(async ({ data }) => {
337
+ .handler(async ({ data, context }) => {
345
338
  const prisma = await getPrisma()
346
- const request = getRequest()
347
- const session = await getServerSeam().requireAuth(request)
348
339
  const { shareId } = data
349
340
 
350
341
  const share = await prisma.share.findUnique({
@@ -356,7 +347,7 @@ export const deleteDesignSingleShareFn = createServerFn({ method: 'POST' })
356
347
  throw new Error("Share not found")
357
348
  }
358
349
  // IDOR 封堵:share 行本身不携带属主,经关联 design 校验当前用户
359
- if (!(await verifyDesignOwner(share.designId, sessionUserId(session)))) {
350
+ if (!(await verifyDesignOwner(share.designId, context.user.id))) {
360
351
  throw new Error("无权限")
361
352
  }
362
353
 
@@ -16,22 +16,21 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
- import { getRequest } from '@tanstack/react-start/server'
19
+ import { authContextMiddleware } from '@/server/middlewares/auth-context'
20
20
  import { z } from 'zod'
21
21
  import { getPrisma } from '@allbluecn/database/get-prisma'
22
- import { getServerSeam } from '@allbluecn/kernel'
23
- import { assertDesignOwner, sessionUserId } from '@/server/design/access'
22
+ import { assertDesignOwner } from '@/server/design/access'
24
23
  import { sortSnapshotsByTree, type DesignPage } from '@/lib/design-tree-utils'
25
24
 
26
25
  export const listDesignVersionsFn = createServerFn({ method: 'GET' })
26
+ .middleware([authContextMiddleware])
27
27
  .validator(z.object({
28
28
  designId: z.string(),
29
29
  take: z.number().int().min(1).max(200).default(50),
30
30
  }))
31
- .handler(async ({ data }) => {
31
+ .handler(async ({ data, context }) => {
32
32
  const prisma = await getPrisma()
33
- const request = getRequest()
34
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
33
+ const userId = context.user.id
35
34
  await assertDesignOwner(data.designId, userId)
36
35
 
37
36
  const versions = await prisma.designVersion.findMany({
@@ -66,6 +65,7 @@ export const listDesignVersionsFn = createServerFn({ method: 'GET' })
66
65
  // 调用方(页面还原走 executeRestoreVersion → updateDesignPageFn + createDesignPageVersionFn),
67
66
  // 且允许以自传 JSON 覆盖任意 pageId 的 canvas/content(审计 2026-10-25 🔴),整段移除。
68
67
  export const createDesignVersionFn = createServerFn({ method: 'POST' })
68
+ .middleware([authContextMiddleware])
69
69
  .validator(z.object({
70
70
  designId: z.string(),
71
71
  major: z.number().int().min(0),
@@ -75,10 +75,9 @@ export const createDesignVersionFn = createServerFn({ method: 'POST' })
75
75
  pageIds: z.array(z.string()),
76
76
  selectedPageVersions: z.record(z.string(), z.number().int()).optional(),
77
77
  }))
78
- .handler(async ({ data }) => {
78
+ .handler(async ({ data, context }) => {
79
79
  const prisma = await getPrisma()
80
- const request = getRequest()
81
- const userId = sessionUserId(await getServerSeam().requireAuth(request))
80
+ const userId = context.user.id
82
81
  const { designId, major, minor, patch, notes, pageIds, selectedPageVersions } = data
83
82
  await assertDesignOwner(designId, userId)
84
83