@allbluecn/web-app 0.19.5 → 0.21.0

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 (235) hide show
  1. package/package.json +3 -3
  2. package/src/components/bug/__tests__/board-subgroups.test.tsx +1 -1
  3. package/src/components/bug/__tests__/board-view.test.tsx +1 -1
  4. package/src/components/bug/__tests__/comment-reactions.test.tsx +1 -1
  5. package/src/components/bug/__tests__/create-bug-dialog.test.tsx +2 -2
  6. package/src/components/bug/__tests__/filters-compat.test.tsx +1 -1
  7. package/src/components/bug/__tests__/fix-request-race.test.tsx +1 -1
  8. package/src/components/bug/__tests__/peek-modes.test.tsx +1 -1
  9. package/src/components/bug/__tests__/use-paged-bug-groups.test.tsx +1 -1
  10. package/src/components/bug/__tests__/view-type.test.tsx +1 -1
  11. package/src/components/bug/bug-list-view.tsx +2 -2
  12. package/src/components/bug/bug-toolbar.tsx +1 -1
  13. package/src/components/bug/create-bug-dialog.tsx +3 -3
  14. package/src/components/bug/detail/__tests__/activity-timeline.test.tsx +1 -1
  15. package/src/components/bug/detail/__tests__/bug-detail-collab.test.tsx +1 -1
  16. package/src/components/bug/detail/__tests__/repro-report-card.test.tsx +1 -1
  17. package/src/components/bug/detail/activity-tabs.tsx +34 -3
  18. package/src/components/bug/detail/activity-timeline.tsx +1 -1
  19. package/src/components/bug/detail/bug-detail-body.tsx +3 -3
  20. package/src/components/bug/detail/comment-input.tsx +1 -1
  21. package/src/components/bug/detail/comment-item.tsx +1 -1
  22. package/src/components/bug/detail/comment-reactions.tsx +1 -1
  23. package/src/components/bug/detail/comment-thread.tsx +1 -1
  24. package/src/components/bug/detail/props-section.tsx +2 -2
  25. package/src/components/bug/detail/repro-report-card.tsx +1 -1
  26. package/src/components/bug/detail/reproduce-steps-view.tsx +1 -1
  27. package/src/components/bug/display/use-paged-bug-groups.ts +2 -2
  28. package/src/components/bug/filters/field-configs.tsx +1 -1
  29. package/src/components/bug/inline-editors/assignee-editor.tsx +1 -1
  30. package/src/components/bug/peek-panel.tsx +2 -2
  31. package/src/components/bug/reproduce-steps-editor.tsx +1 -1
  32. package/src/components/bug/story-bugs-panel.tsx +10 -6
  33. package/src/components/bug/views/board-view.tsx +2 -2
  34. package/src/components/bug/views/bug-list/batch-toolbar.tsx +1 -1
  35. package/src/components/bug/views/bug-list/group.tsx +1 -1
  36. package/src/components/bug/views/bug-list/index.tsx +1 -1
  37. package/src/components/bug/views/bug-list/inline-bug-creator.tsx +1 -1
  38. package/src/components/bug/views/bug-list/row.tsx +2 -2
  39. package/src/components/bug/views/create-view-dialog.tsx +1 -1
  40. package/src/components/design/editor/versions/hooks/use-design-versions.ts +11 -4
  41. package/src/components/design/editor/versions/page-version-panel.tsx +30 -11
  42. package/src/components/harness/code/workspace-context.tsx +5 -1
  43. package/src/components/harness/code/workspace-picker.tsx +19 -6
  44. package/src/components/harness/composer/harness-composer.tsx +25 -3
  45. package/src/components/harness/composer/mention/mention-resolvers.ts +2 -0
  46. package/src/components/harness/composer/mention/mention-suggestion-menu.tsx +6 -3
  47. package/src/components/harness/composer/mention/use-mention-sources.ts +1 -1
  48. package/src/components/iteration/iteration-progress-bar.tsx +2 -2
  49. package/src/components/knowledge/public/legal-compliance-editor.tsx +1 -1
  50. package/src/components/layout/sidebar-03/nav-knowledge.tsx +1 -1
  51. package/src/components/layout/sidebar-03/nav-workspace.tsx +1 -1
  52. package/src/components/project/invite-member-dialog.tsx +2 -2
  53. package/src/components/project/project-member-manager.tsx +0 -3
  54. package/src/components/shared-kit/list-kit/kanban/__tests__/instance-key.test.ts +1 -1
  55. package/src/components/story/__tests__/constants.test.ts +1 -1
  56. package/src/components/story/__tests__/dependency-type-badge.test.ts +1 -1
  57. package/src/components/story/__tests__/peek-panel-patch-sync.test.tsx +1 -1
  58. package/src/components/story/__tests__/story-list-view-peek-sync.test.tsx +1 -1
  59. package/src/components/story/ai/story-ai-panel.tsx +1 -1
  60. package/src/components/story/ai/story-ai-preview-list.tsx +2 -2
  61. package/src/components/story/ai/use-story-ai-model.ts +17 -4
  62. package/src/components/story/columns.tsx +2 -2
  63. package/src/components/story/create-story-dialog.tsx +4 -4
  64. package/src/components/story/detail/__tests__/activity-timeline.test.tsx +1 -1
  65. package/src/components/story/detail/__tests__/associated-attachments-panel.test.tsx +1 -1
  66. package/src/components/story/detail/__tests__/story-collab.test.tsx +1 -1
  67. package/src/components/story/detail/activity-tabs.tsx +1 -1
  68. package/src/components/story/detail/activity-timeline.tsx +36 -17
  69. package/src/components/story/detail/comment-input.tsx +1 -1
  70. package/src/components/story/detail/comment-item.tsx +1 -1
  71. package/src/components/story/detail/comment-thread.tsx +1 -1
  72. package/src/components/story/detail/reaction-bar.tsx +1 -1
  73. package/src/components/story/detail/story-detail-body.tsx +4 -4
  74. package/src/components/story/detail/story-detail-toolbar/__tests__/attachment-cache.test.ts +83 -0
  75. package/src/components/story/detail/story-detail-toolbar/associated-attachments-panel.tsx +50 -9
  76. package/src/components/story/detail/story-detail-toolbar/children.tsx +3 -3
  77. package/src/components/story/detail/story-detail-toolbar/dependency-panel.tsx +9 -8
  78. package/src/components/story/detail/story-detail-toolbar/index.tsx +8 -8
  79. package/src/components/story/detail/story-detail-toolbar/related-test-cases.tsx +2 -2
  80. package/src/components/story/detail/story-properties.tsx +2 -2
  81. package/src/components/story/display/__tests__/flatten-story-groups.test.ts +1 -1
  82. package/src/components/story/display/__tests__/group-fields.test.ts +1 -1
  83. package/src/components/story/display/__tests__/group-resolver.test.ts +2 -2
  84. package/src/components/story/display/__tests__/order-resolver.test.ts +1 -1
  85. package/src/components/story/display/__tests__/use-grouped-stories.test.ts +1 -1
  86. package/src/components/story/display/__tests__/use-paged-story-groups.test.ts +1 -1
  87. package/src/components/story/display/flatten-story-groups.ts +1 -1
  88. package/src/components/story/display/group-fields.ts +2 -2
  89. package/src/components/story/display/group-resolver.tsx +4 -4
  90. package/src/components/story/display/order-resolver.ts +3 -3
  91. package/src/components/story/display/types.ts +5 -4
  92. package/src/components/story/display/use-grouped-stories.ts +5 -5
  93. package/src/components/story/display/use-paged-story-groups.ts +11 -4
  94. package/src/components/story/entity-overlay.ts +24 -0
  95. package/src/components/story/filters/field-configs.tsx +2 -2
  96. package/src/components/story/inline-editors/assignee-editor.tsx +1 -1
  97. package/src/components/story/inline-editors/dependency-type-select.tsx +1 -1
  98. package/src/components/story/inline-editors/parent-story-editor.tsx +2 -2
  99. package/src/components/story/inline-editors/priority-editor.tsx +2 -2
  100. package/src/components/story/inline-editors/state-editor.tsx +2 -2
  101. package/src/components/story/inline-editors/story-select-dialog.tsx +2 -2
  102. package/src/components/story/peek-panel.tsx +6 -5
  103. package/src/components/story/priority-icon.tsx +2 -2
  104. package/src/components/story/relations/__tests__/attachment-manage-dialog.test.tsx +1 -1
  105. package/src/components/story/relations/__tests__/design-select-dialog.test.tsx +1 -1
  106. package/src/components/story/relations/__tests__/knowledge-select-dialog.test.tsx +1 -1
  107. package/src/components/story/relations/__tests__/link-manage-dialog.test.tsx +1 -1
  108. package/src/components/story/relations/attachment-manage-dialog.tsx +4 -4
  109. package/src/components/story/relations/design-select-dialog.tsx +2 -2
  110. package/src/components/story/relations/knowledge-select-dialog.tsx +2 -2
  111. package/src/components/story/relations/link-manage-dialog.tsx +2 -2
  112. package/src/components/story/relations/story-ref-row.tsx +3 -3
  113. package/src/components/story/story-list-table.tsx +1 -1
  114. package/src/components/story/story-list-view.tsx +1 -1
  115. package/src/components/story/story-toolbar.tsx +1 -1
  116. package/src/components/story/transfer-story-popover.tsx +3 -2
  117. package/src/components/story/views/__tests__/calendar-view.test.tsx +1 -1
  118. package/src/components/story/views/__tests__/kanban-drop-subgroup.test.ts +1 -1
  119. package/src/components/story/views/__tests__/kanban-peek-sync.test.tsx +2 -2
  120. package/src/components/story/views/__tests__/kanban-view-membership-sync.test.tsx +1 -1
  121. package/src/components/story/views/__tests__/timeline-view.test.tsx +1 -1
  122. package/src/components/story/views/calendar/__tests__/mappers.test.ts +1 -1
  123. package/src/components/story/views/calendar/mappers.ts +1 -1
  124. package/src/components/story/views/calendar-view.tsx +1 -1
  125. package/src/components/story/views/create-view-dialog.tsx +1 -1
  126. package/src/components/story/views/kanban-view.tsx +2 -2
  127. package/src/components/story/views/story-list/batch-preview-dialog.tsx +2 -2
  128. package/src/components/story/views/story-list/batch-toolbar.tsx +3 -3
  129. package/src/components/story/views/story-list/group.tsx +18 -5
  130. package/src/components/story/views/story-list/index.tsx +4 -2
  131. package/src/components/story/views/story-list/inline-story-creator.tsx +2 -2
  132. package/src/components/story/views/story-list/row.tsx +2 -2
  133. package/src/components/story/views/story-list/use-flat-rows.ts +1 -1
  134. package/src/components/story/views/timeline/__tests__/mappers.test.ts +2 -2
  135. package/src/components/story/views/timeline/mappers.ts +2 -2
  136. package/src/components/story/views/timeline/use-date-commit.ts +1 -1
  137. package/src/components/story/views/timeline-view.tsx +2 -2
  138. package/src/components/testcase/__tests__/case-row.test.tsx +1 -1
  139. package/src/components/testcase/__tests__/create-dialog-scope.test.tsx +1 -1
  140. package/src/components/testcase/__tests__/display-options.test.tsx +1 -1
  141. package/src/components/testcase/__tests__/export-entry.test.tsx +1 -1
  142. package/src/components/testcase/__tests__/list-view.test.tsx +1 -1
  143. package/src/components/testcase/__tests__/step-editor.test.tsx +4 -2
  144. package/src/components/testcase/__tests__/toolbar.test.tsx +1 -1
  145. package/src/components/testcase/create-testcase-dialog.tsx +6 -5
  146. package/src/components/testcase/detail/case-detail-body.tsx +1 -1
  147. package/src/components/testcase/detail/properties.tsx +1 -1
  148. package/src/components/testcase/display/display-dropdown.tsx +2 -2
  149. package/src/components/testcase/display/use-testcase-display-options.ts +1 -1
  150. package/src/components/testcase/filters/field-configs.tsx +1 -1
  151. package/src/components/testcase/generation/draft-card.tsx +2 -2
  152. package/src/components/testcase/inline-editors/assignee-editor.tsx +1 -1
  153. package/src/components/testcase/list/case-row.tsx +1 -1
  154. package/src/components/testcase/list/grouped-list.tsx +1 -1
  155. package/src/components/testcase/list-view.tsx +2 -2
  156. package/src/components/testcase/runs/convert-bug-button.tsx +2 -2
  157. package/src/components/testcase/step-editor.tsx +13 -2
  158. package/src/components/testcase/testcase-toolbar.tsx +2 -2
  159. package/src/components/testcase/views/batch-toolbar.tsx +1 -1
  160. package/src/components/testcase/views/board-view.tsx +2 -2
  161. package/src/lib/changelog/sdk-versions.ts +2 -2
  162. package/src/lib/collections/knowledge/knowledge-bases-collection.ts +2 -1
  163. package/src/lib/collections/query-keys.ts +18 -0
  164. package/src/lib/collections/reference/users-brief-collection.ts +2 -1
  165. package/src/lib/collections/reference/workspaces-collection.ts +2 -1
  166. package/src/lib/story/__tests__/activity-grouper.test.ts +1 -1
  167. package/src/lib/story/activity-grouper.ts +1 -1
  168. package/src/paraglide/messages/_index.d.ts +2 -0
  169. package/src/paraglide/messages/_index.js +88269 -5642
  170. package/src/paraglide/messages/en.js +28255 -0
  171. package/src/paraglide/messages/story_group_loadfailed1.d.ts +17 -0
  172. package/src/paraglide/messages/story_group_loadfailed1.js +30 -0
  173. package/src/paraglide/messages/story_group_retry.d.ts +16 -0
  174. package/src/paraglide/messages/story_group_retry.js +29 -0
  175. package/src/paraglide/messages/zh.js +28253 -0
  176. package/src/routes/_nav/bugs/$bugId/route.lazy.tsx +2 -2
  177. package/src/routes/_nav/projects/$projectId/iterations/$iterationId/route.lazy.tsx +1 -1
  178. package/src/routes/_nav/route.tsx +1 -2
  179. package/src/routes/_nav/stories/$storyId/route.lazy.tsx +2 -2
  180. package/src/routes/_nav/stories/$storyId/route.tsx +1 -1
  181. package/src/routes/api/design/prototype/__tests__/route.test.ts +4 -1
  182. package/src/server/__tests__/task-executor.test.ts +7 -0
  183. package/src/server/ai-gateway/__tests__/ai-output-guard.test.ts +4 -4
  184. package/src/server/ai-gateway/__tests__/tools-authorization.test.ts +25 -0
  185. package/src/server/ai-gateway/tools/server.ts +24 -15
  186. package/src/server/knowledge/reindex-guard.ts +35 -0
  187. package/src/server/lib/__tests__/cron-auth.test.ts +1 -1
  188. package/src/server/serverFns/__tests__/legal-code-canonical.test.ts +169 -0
  189. package/src/server/serverFns/__tests__/story-tree.test.ts +0 -1
  190. package/src/server/serverFns/__tests__/story-types.test.ts +2 -1
  191. package/src/server/serverFns/__tests__/update-bug-guard.test.ts +1 -1
  192. package/src/server/serverFns/bug/__tests__/bug-comments.test.ts +95 -44
  193. package/src/server/serverFns/bug/__tests__/bug-crud.test.ts +46 -18
  194. package/src/server/serverFns/bug/__tests__/bug-groups.test.ts +1 -1
  195. package/src/server/serverFns/bug/bug-activities.ts +2 -2
  196. package/src/server/serverFns/bug/bug-comments.ts +44 -19
  197. package/src/server/serverFns/bug/bug-crud/detail-select.ts +1 -1
  198. package/src/server/serverFns/bug/bug-crud/detail.ts +2 -2
  199. package/src/server/serverFns/bug/bug-crud.ts +142 -110
  200. package/src/server/serverFns/bug/bug-group-query.ts +1 -1
  201. package/src/server/serverFns/bug/bug-groups.ts +2 -2
  202. package/src/server/serverFns/bug/bug-story-utils.ts +1 -1
  203. package/src/server/serverFns/chat/conversations.ts +27 -13
  204. package/src/server/serverFns/harness/github-workspace.ts +32 -25
  205. package/src/server/serverFns/harness/search-mention-candidates.ts +3 -1
  206. package/src/server/serverFns/iteration/iteration-crud.ts +1 -1
  207. package/src/server/serverFns/knowledge/public/legal/create.ts +3 -0
  208. package/src/server/serverFns/knowledge/public/legal/update.ts +8 -8
  209. package/src/server/serverFns/knowledge-index.ts +12 -5
  210. package/src/server/serverFns/project.ts +5 -11
  211. package/src/server/serverFns/story/__tests__/story-dependencies.test.ts +15 -4
  212. package/src/server/serverFns/story/__tests__/story-transfer.test.ts +20 -0
  213. package/src/server/serverFns/story/link-preview.ts +3 -2
  214. package/src/server/serverFns/story/story-children.ts +1 -1
  215. package/src/server/serverFns/story/story-comments.ts +1 -1
  216. package/src/server/serverFns/story/story-crud/bulk.ts +1 -1
  217. package/src/server/serverFns/story/story-crud.ts +1 -1
  218. package/src/server/serverFns/story/story-dependencies.ts +61 -69
  219. package/src/server/serverFns/story/story-groups.ts +1 -1
  220. package/src/server/serverFns/story/story-transfer.ts +8 -20
  221. package/src/server/serverFns/testcase/__tests__/automation.test.ts +21 -0
  222. package/src/server/serverFns/testcase/__tests__/testcase-groups.test.ts +1 -1
  223. package/src/server/serverFns/testcase/automation.ts +24 -1
  224. package/src/server/serverFns/testcase/testcase-board.ts +1 -1
  225. package/src/server/serverFns/testcase/testcase-crud.ts +1 -1
  226. package/src/server/serverFns/testcase/testcase-display-options.ts +1 -1
  227. package/src/server/serverFns/testcase/testcase-filter-views.ts +1 -1
  228. package/src/server/serverFns/testcase/types.ts +1 -1
  229. package/src/server/story/types.ts +7 -3
  230. package/src/shared/bug/__tests__/constants.test.ts +1 -1
  231. package/src/{components → shared}/bug/types.ts +4 -3
  232. package/src/{components → shared}/story/constants.ts +1 -1
  233. package/src/{components → shared}/story/types.ts +1 -7
  234. package/src/types/project.ts +1 -2
  235. /package/src/{components/testcase/display → shared/testcase}/field-configs.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allbluecn/web-app",
3
- "version": "0.19.5",
3
+ "version": "0.21.0",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "files": [
@@ -60,8 +60,8 @@
60
60
  "dependencies": {
61
61
  "@ag-ui/core": "1.0.0",
62
62
  "@allbluecn/collab-core": "0.2.0",
63
- "@allbluecn/database": "0.9.5",
64
- "@allbluecn/kernel": "0.10.1",
63
+ "@allbluecn/database": "0.10.1",
64
+ "@allbluecn/kernel": "0.11.0",
65
65
  "@ariakit/react": "^0.4.28",
66
66
  "@auth/core": "^0.41.2",
67
67
  "@auth/prisma-adapter": "^2.11.2",
@@ -64,7 +64,7 @@ import {
64
64
  toGroupFieldPatch,
65
65
  } from "../views/board-view";
66
66
  import type { BugBoardViewProps } from "../views/board-view";
67
- import type { BugListItem } from "../types";
67
+ import type { BugListItem } from "@/shared/bug/types";
68
68
 
69
69
  afterEach(() => {
70
70
  cleanup();
@@ -58,7 +58,7 @@ import {
58
58
  toGroupFieldPatch,
59
59
  } from "../views/board-view";
60
60
  import type { BugBoardViewProps } from "../views/board-view";
61
- import type { BugListItem } from "../types";
61
+ import type { BugListItem } from "@/shared/bug/types";
62
62
  import { STATE_COLOR } from "@/shared/bug/constants";
63
63
 
64
64
  afterEach(() => {
@@ -27,7 +27,7 @@
27
27
  // 的 JSX 调用保证(本仓 tsc + 本测试共同锁住组件存在性)。
28
28
  import { afterEach, describe, expect, it, vi } from "vitest";
29
29
  import { act, cleanup, fireEvent, render, screen, within } from "@testing-library/react";
30
- import type { ReactionGroup } from "@/components/story/types";
30
+ import type { ReactionGroup } from "@/shared/story/types";
31
31
 
32
32
  // ---------------------------------------------------------------------------
33
33
  // mock(vi.mock 提升:真实 serverFn / toast / emoji-picker-react 均不参与)
@@ -55,8 +55,8 @@ vi.mock("@/components/tiptap/notion-like", () => ({
55
55
 
56
56
  import { CreateBugDialog } from "../create-bug-dialog";
57
57
  import { ReproduceStepsEditor } from "../reproduce-steps-editor";
58
- import type { ReproduceSteps } from "../types";
59
- import type { UserBrief } from "@/components/story/types";
58
+ import type { ReproduceSteps } from "@/shared/bug/types";
59
+ import type { UserBrief } from "@/shared/story/types";
60
60
 
61
61
  const USERS: UserBrief[] = [
62
62
  { id: "u1", username: "alice", email: "a@test.dev", avatarConfig: null, bgShape: null, bgColor: null },
@@ -26,7 +26,7 @@ import { describe, it, expect, afterEach } from "vitest";
26
26
  import { render, screen, cleanup } from "@testing-library/react";
27
27
  import { TooltipProvider } from "@/components/ui/tooltip";
28
28
  import { AppliedFilters, BugFilterToggle, type FilterCondition } from "../filters";
29
- import type { UserBrief } from "@/components/story/types";
29
+ import type { UserBrief } from "@/shared/story/types";
30
30
 
31
31
  const FIXTURE: FilterCondition[] = [
32
32
  { id: "bfc_1", property: "title", operator: "contains", value: "超时" },
@@ -102,7 +102,7 @@ vi.mock("@/components/tiptap/notion-like", () => ({
102
102
  import { BugDetailBody } from "../detail/bug-detail-body";
103
103
  import { BugPanelHeader } from "../bug-panel-header";
104
104
  import { BugBatchToolbar } from "../views/bug-list/batch-toolbar";
105
- import type { BugDetail } from "../types";
105
+ import type { BugDetail } from "@/shared/bug/types";
106
106
 
107
107
  const bugRow = (over: Partial<BugDetail> = {}): BugDetail => ({
108
108
  id: "bg-1",
@@ -104,7 +104,7 @@ vi.mock("@tanstack/react-virtual", async (importOriginal) => {
104
104
 
105
105
  import { BugPeekPanel } from "../peek-panel";
106
106
  import { BugListView } from "../bug-list-view";
107
- import type { BugDetail } from "../types";
107
+ import type { BugDetail } from "@/shared/bug/types";
108
108
  import { PEEK_DOCK_SLOT_ID } from "@/lib/peek-dock";
109
109
 
110
110
  const baseBug: BugDetail = {
@@ -17,7 +17,7 @@
17
17
 
18
18
  import { describe, it, expect, vi, beforeEach } from "vitest";
19
19
  import { renderHook, waitFor, act, render, screen, fireEvent, cleanup } from "@testing-library/react";
20
- import type { BugListItem } from "../types";
20
+ import type { BugListItem } from "@/shared/bug/types";
21
21
  import { DEFAULT_BUG_DISPLAY_OPTIONS } from "@/shared/bug/display-types";
22
22
  import type { PagedBugsArgs } from "../display/use-paged-bug-groups";
23
23
 
@@ -81,7 +81,7 @@ import { BugListView } from "../bug-list-view";
81
81
  import { isBugView } from "../views/view-types";
82
82
  import { BugListRow } from "../views/bug-list/row";
83
83
  import { BugBoardView } from "../views/board-view";
84
- import type { BugListItem } from "../types";
84
+ import type { BugListItem } from "@/shared/bug/types";
85
85
  import type { ReorderEntry } from "@/components/shared-kit/list-kit/kanban/drop-commit";
86
86
 
87
87
  afterEach(() => {
@@ -31,7 +31,7 @@ import {
31
31
  deleteBugViewFn,
32
32
  reorderBugsFn,
33
33
  } from "@/server/serverFns/bug";
34
- import type { UserBrief } from "@/components/story/types";
34
+ import type { UserBrief } from "@/shared/story/types";
35
35
  import { usePagedBugGroups, type PagedBugGroupNode } from "./display/use-paged-bug-groups";
36
36
  import { useBugDisplayOptions } from "./display/use-bug-display-options";
37
37
  import type { BugGroupKey } from "@/shared/bug/display-types";
@@ -42,7 +42,7 @@ import type { ReorderEntry } from "@/components/shared-kit/list-kit/kanban/drop-
42
42
  import { manualOrderSwitchPatch } from "@/components/shared-kit/list-kit/kanban/manual-order";
43
43
  // 纯函数跨层复用(bug-group-query 运行时零服务端依赖,use-paged-bug-groups 同款先例)
44
44
  import { BUG_STATE_GROUP_KEYS, BUG_SEVERITY_GROUP_KEYS } from "@/server/serverFns/bug/bug-group-query";
45
- import type { BugListItem } from "./types";
45
+ import type { BugListItem } from "@/shared/bug/types";
46
46
  import { CreateBugDialog } from "./create-bug-dialog";
47
47
  import { BugPeekPanel } from "./peek-panel";
48
48
  import { CreateViewDialog, type CreateViewDialogPayload } from "./views/create-view-dialog";
@@ -58,7 +58,7 @@ import { BugViewSwitcher } from "./views/view-switcher";
58
58
  import { ViewSelectorButton } from "./views/view-selector-button";
59
59
  import type { BugView, BugViewModel } from "./views/view-types";
60
60
  import type { BugDisplayOptions } from "@/shared/bug/display-types";
61
- import type { UserBrief } from "@/components/story/types";
61
+ import type { UserBrief } from "@/shared/story/types";
62
62
  import { m } from "@/paraglide/messages.js";
63
63
  import { getLocale } from "@/paraglide/runtime.js";
64
64
  import { useToolbarSearch } from "@/hooks/use-toolbar-search";
@@ -27,11 +27,11 @@ import { toast } from "@/components/ui/toast";
27
27
  import { createBugFn } from "@/server/serverFns/bug";
28
28
  import { ensureBuiltinProjectFn } from "@/server/serverFns/project";
29
29
  import type { BugState, BugSeverity, BugSource } from "@/shared/bug/constants";
30
- import type { UserBrief } from "@/components/story/types";
31
- import { serializeStoryDescription } from "@/components/story/types";
30
+ import type { UserBrief } from "@/shared/story/types";
31
+ import { serializeStoryDescription } from "@/shared/story/types";
32
32
  import { StateEditor, SeverityEditor, AssigneeEditor, LabelsEditor } from "./inline-editors";
33
33
  import { ReproduceStepsEditor } from "./reproduce-steps-editor";
34
- import type { BugListItem, ReproduceSteps } from "./types";
34
+ import type { BugListItem, ReproduceSteps } from "@/shared/bug/types";
35
35
  import { NotionDocEditor } from "@/components/tiptap/notion-like";
36
36
  import { errorMessage } from "@/lib/toast-error";
37
37
  import { m } from "@/paraglide/messages.js";
@@ -26,7 +26,7 @@ import { describe, it, expect, afterEach, vi } from "vitest";
26
26
  import { render, cleanup } from "@testing-library/react";
27
27
  import { m } from "@/paraglide/messages.js";
28
28
  import { ACTIVITY_LABEL, STATE_LABEL } from "@/shared/bug/constants";
29
- import type { BugActivityItem, BugCommentWithReplies } from "../../types";
29
+ import type { BugActivityItem, BugCommentWithReplies } from "@/shared/bug/types";
30
30
 
31
31
  vi.mock("@/server/serverFns/bug", () => ({
32
32
  listBugActivitiesFn: vi.fn().mockResolvedValue({ items: [], nextCursor: null }),
@@ -113,7 +113,7 @@ vi.mock("@/components/tiptap/notion-like", () => ({
113
113
  }));
114
114
 
115
115
  import { BugDetailBody } from "../bug-detail-body";
116
- import type { BugDetail } from "../../types";
116
+ import type { BugDetail } from "@/shared/bug/types";
117
117
 
118
118
  const U = "u-1";
119
119
 
@@ -46,7 +46,7 @@ vi.mock("@/components/knowledge/public/markdown-view", () => ({
46
46
 
47
47
  import { ReproReportCard } from "../repro-report-card";
48
48
  import type { ReproRunItem } from "@/server/serverFns/bug/bug-repro";
49
- import type { BugDetail } from "../../types";
49
+ import type { BugDetail } from "@/shared/bug/types";
50
50
 
51
51
  const T0 = new Date("2026-01-01T00:00:00Z");
52
52
 
@@ -23,8 +23,8 @@ import { LoaderCircle } from "lucide-react";
23
23
  import { Button } from "@/components/ui/button";
24
24
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
25
25
  import { listBugActivitiesFn, listCommentsFn } from "@/server/serverFns/bug";
26
- import { errorMessage } from "@/lib/toast-error";
27
- import type { BugActivityItem, BugCommentWithReplies } from "../types";
26
+ import { errorMessage, toastError } from "@/lib/toast-error";
27
+ import type { BugActivityItem, BugCommentWithReplies } from "@/shared/bug/types";
28
28
  import { ActivityTimeline } from "./activity-timeline";
29
29
  import { CommentThread } from "./comment-thread";
30
30
  import { m } from "@/paraglide/messages.js";
@@ -63,6 +63,9 @@ interface ActivityTabsProps {
63
63
  export function ActivityTabs({ bugId, refreshKey = 0 }: ActivityTabsProps) {
64
64
  const [activities, setActivities] = useState<BugActivityItem[] | null>(null);
65
65
  const [nextCursor, setNextCursor] = useState<string | null>(null);
66
+ // S39:评论根分页游标(对齐活动流 cursor 口径)
67
+ const [commentsCursor, setCommentsCursor] = useState<string | null>(null);
68
+ const [loadingMoreComments, setLoadingMoreComments] = useState(false);
66
69
  const [comments, setComments] = useState<BugCommentWithReplies[] | null>(null);
67
70
  const [error, setError] = useState<string | null>(null);
68
71
  const [loadingMore, setLoadingMore] = useState(false);
@@ -94,6 +97,7 @@ export function ActivityTabs({ bugId, refreshKey = 0 }: ActivityTabsProps) {
94
97
  setComments(null);
95
98
  setError(null);
96
99
  setNextCursor(null);
100
+ setCommentsCursor(null);
97
101
  Promise.all([
98
102
  listBugActivitiesFn({ data: { bugId, take: ACTIVITY_PAGE_SIZE } }),
99
103
  listCommentsFn({ data: { bugId } }),
@@ -102,7 +106,8 @@ export function ActivityTabs({ bugId, refreshKey = 0 }: ActivityTabsProps) {
102
106
  if (cancelled) return;
103
107
  setActivities(act.items);
104
108
  setNextCursor(act.nextCursor);
105
- setComments(cmts);
109
+ setComments(cmts.items);
110
+ setCommentsCursor(cmts.nextCursor);
106
111
  })
107
112
  .catch((e: unknown) => {
108
113
  if (!cancelled) setError(errorMessage(e, m.bug_detail_load_failed()));
@@ -124,6 +129,21 @@ export function ActivityTabs({ bugId, refreshKey = 0 }: ActivityTabsProps) {
124
129
  }
125
130
  };
126
131
 
132
+ // S39:根评论 keyset 分页续拉(页间不相交,直接拼接)
133
+ const handleLoadMoreComments = async () => {
134
+ if (!commentsCursor || loadingMoreComments) return;
135
+ setLoadingMoreComments(true);
136
+ try {
137
+ const res = await listCommentsFn({ data: { bugId, cursor: commentsCursor } });
138
+ setComments((prev) => (prev ? [...prev, ...res.items] : res.items));
139
+ setCommentsCursor(res.nextCursor);
140
+ } catch {
141
+ toastError(new Error(m.bug_list_loadMoreFailed()), m.bug_list_loadMoreFailed());
142
+ } finally {
143
+ setLoadingMoreComments(false);
144
+ }
145
+ };
146
+
127
147
  // 评论创建/删除后刷新活动流(服务端写 commented 活动或级联清树)
128
148
  const handleAppendComment = (created: BugCommentWithReplies) => {
129
149
  setComments((prev) => (prev ? insertComment(prev, created) : [created]));
@@ -184,6 +204,17 @@ export function ActivityTabs({ bugId, refreshKey = 0 }: ActivityTabsProps) {
184
204
  onRemoveComment={handleRemoveComment}
185
205
  />
186
206
  )}
207
+ {!error && commentsCursor && (
208
+ <Button
209
+ variant="outline"
210
+ size="sm"
211
+ className="mt-2 h-7 w-full text-xs"
212
+ onClick={() => void handleLoadMoreComments()}
213
+ disabled={loadingMoreComments}
214
+ >
215
+ {loadingMoreComments ? m.bug_list_loading() : m.bug_list_load_more()}
216
+ </Button>
217
+ )}
187
218
  </TabsContent>
188
219
  </Tabs>
189
220
  );
@@ -21,7 +21,7 @@
21
21
  import { ArrowRight, Bot, Dot, Sparkles } from "lucide-react";
22
22
  import { UserAvatar } from "@/components/shared-kit";
23
23
  import { ACTIVITY_LABEL, SEVERITY_LABEL, STATE_LABEL, type BugState, type BugSeverity } from "@/shared/bug/constants";
24
- import type { BugActivityItem } from "../types";
24
+ import type { BugActivityItem } from "@/shared/bug/types";
25
25
  import { m } from "@/paraglide/messages.js";
26
26
  import { formatTimestamp } from "@/lib/datetime";
27
27
 
@@ -37,9 +37,9 @@ import { toast } from "@/components/ui/toast";
37
37
  import { requestBugFixFn, updateBugFn } from "@/server/serverFns/bug";
38
38
  import { formatTimestamp } from "@/lib/datetime";
39
39
  import { SOURCE_LABEL } from "@/shared/bug/constants";
40
- import type { BugDetail, BugStoryBrief, ReproduceSteps } from "../types";
41
- import type { UserBrief } from "@/components/story/types";
42
- import { parseStoryDescription } from "@/components/story/types";
40
+ import type { BugDetail, BugStoryBrief, ReproduceSteps } from "@/shared/bug/types";
41
+ import type { UserBrief } from "@/shared/story/types";
42
+ import { parseStoryDescription } from "@/shared/story/types";
43
43
  import { buildRoomName } from "@allbluecn/collab-core/rooms";
44
44
  import { useSession } from "@/components/shared-kit/auth/auth-client";
45
45
  import { useCollabDoc } from "@/lib/collab/use-collab-doc";
@@ -23,7 +23,7 @@ import { Textarea } from "@/components/ui/textarea";
23
23
  import { createCommentFn } from "@/server/serverFns/bug";
24
24
  import { toast } from "@/components/ui/toast";
25
25
  import { errorMessage } from "@/lib/toast-error";
26
- import type { BugCommentWithReplies } from "../types";
26
+ import type { BugCommentWithReplies } from "@/shared/bug/types";
27
27
  import { m } from "@/paraglide/messages.js";
28
28
 
29
29
  interface CommentInputProps {
@@ -33,7 +33,7 @@ import {
33
33
  import { deleteCommentFn, updateCommentFn } from "@/server/serverFns/bug";
34
34
  import { toast } from "@/components/ui/toast";
35
35
  import { errorMessage } from "@/lib/toast-error";
36
- import type { BugCommentWithReplies } from "../types";
36
+ import type { BugCommentWithReplies } from "@/shared/bug/types";
37
37
  import { formatRelative } from "./activity-timeline";
38
38
  import { CommentInput } from "./comment-input";
39
39
  import { CommentReactions } from "./comment-reactions";
@@ -28,7 +28,7 @@ import { EmojiPicker } from "@/components/shared-kit/comments/emoji-picker";
28
28
  import { toast } from "@/components/ui/toast";
29
29
  import { toggleBugCommentReactionFn } from "@/server/serverFns/bug";
30
30
  import { errorMessage } from "@/lib/toast-error";
31
- import type { ReactionGroup } from "@/components/story/types";
31
+ import type { ReactionGroup } from "@/shared/story/types";
32
32
  import { m } from "@/paraglide/messages.js";
33
33
 
34
34
  /** hover 快捷回应(常用 3 个;完整选择走 picker) */
@@ -19,7 +19,7 @@
19
19
  // parentId 组装为多级回复树,本组件只负责渲染 + 回调透传,不再二次建树。
20
20
  import { CommentItem } from "./comment-item";
21
21
  import { CommentInput } from "./comment-input";
22
- import type { BugCommentWithReplies } from "../types";
22
+ import type { BugCommentWithReplies } from "@/shared/bug/types";
23
23
  import { m } from "@/paraglide/messages.js";
24
24
 
25
25
  interface CommentThreadProps {
@@ -26,8 +26,8 @@ import { updateBugFn, linkBugToStoryFn, unlinkBugFromStoryFn } from "@/server/se
26
26
  import { searchStoriesFn } from "@/server/serverFns/story";
27
27
  import { useDebouncedValue, SEARCH_DEBOUNCE_MS } from "@/lib/pacer";
28
28
  import type { BugState, BugSeverity } from "@/shared/bug/constants";
29
- import type { BugDetail, BugStoryBrief } from "../types";
30
- import type { UserBrief } from "@/components/story/types";
29
+ import type { BugDetail, BugStoryBrief } from "@/shared/bug/types";
30
+ import type { UserBrief } from "@/shared/story/types";
31
31
  import type { PropsSectionCollabProps } from "./bug-detail-body";
32
32
  import { StateEditor, SeverityEditor, AssigneeEditor, LabelsEditor } from "../inline-editors";
33
33
  import { m } from "@/paraglide/messages.js";
@@ -48,7 +48,7 @@ import { REPRO_VERDICT_COLOR, REPRO_VERDICT_LABEL, type BugReproVerdict } from "
48
48
  import { MarkdownView } from "@/components/knowledge/public/markdown-view";
49
49
  import { formatRelative } from "./activity-timeline";
50
50
  import { m } from "@/paraglide/messages.js";
51
- import type { BugDetail } from "../types";
51
+ import type { BugDetail } from "@/shared/bug/types";
52
52
  import { toastError, errorMessage } from "@/lib/toast-error";
53
53
 
54
54
  /** confidence 0-1 → 整数百分比(越界钳制,防脏数据渲染 -3% / 140%) */
@@ -18,7 +18,7 @@
18
18
  // 复现步骤只读视图(规格 §5.4 第 4 分区):结构化步骤列表 + 整体预期/实际对照。
19
19
  // SDK 上报无 reproduceSteps 字段时显示「待补充」引导(编辑器接入在后续任务)。
20
20
  import { ListOrdered } from "lucide-react";
21
- import type { ReproduceSteps } from "../types";
21
+ import type { ReproduceSteps } from "@/shared/bug/types";
22
22
  import { m } from "@/paraglide/messages.js";
23
23
 
24
24
  interface ReproduceStepsViewProps {
@@ -29,8 +29,8 @@ import {
29
29
  // 纯函数跨层复用(任务 4 复审核实运行时零服务端依赖):组内全序比较与 story 客户端
30
30
  // compareByOrder 同构,直接引用单一实现避免双份漂移。
31
31
  import { compareBugsByOrderKey } from "@/server/serverFns/bug/bug-group-query";
32
- import type { BugListItem } from "../types";
33
- import type { UserBrief } from "@/components/story/types";
32
+ import type { BugListItem } from "@/shared/bug/types";
33
+ import type { UserBrief } from "@/shared/story/types";
34
34
  import type { FilterCondition } from "../filters";
35
35
  import { serializeFilters } from "../filters";
36
36
  import { BUG_STATES, BUG_SEVERITIES, type BugState, type BugSeverity } from "@/shared/bug/constants";
@@ -70,7 +70,7 @@ import type {
70
70
  FilterFieldType,
71
71
  } from "@/components/shared-kit/list-kit/filters/types";
72
72
  import { cn } from "@/lib/utils";
73
- import type { UserBrief } from "@/components/story/types";
73
+ import type { UserBrief } from "@/shared/story/types";
74
74
 
75
75
  export { serializeFilters, deserializeFilters, OPERATOR_LABELS, generateConditionId } from "@/components/shared-kit/list-kit/filters";
76
76
  export type { FilterOperator, FilterFieldType };
@@ -20,7 +20,7 @@ import { CircleUser, Search, Check } from "lucide-react";
20
20
  import { Input } from "@/components/ui/input";
21
21
  import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
22
22
  import { UserAvatar } from "@/components/shared-kit";
23
- import type { UserBrief } from "@/components/story/types";
23
+ import type { UserBrief } from "@/shared/story/types";
24
24
  import { cn } from "@/lib/utils";
25
25
  import { InlineTrigger } from "./inline-trigger";
26
26
  import { m } from "@/paraglide/messages.js";
@@ -31,8 +31,8 @@ import { getBugDetailFn, getBugNeighborsFn } from "@/server/serverFns/bug";
31
31
  import { formatTimestamp } from "@/lib/datetime";
32
32
  import { errorMessage } from "@/lib/toast-error";
33
33
  import type { BugPatch } from "./display/use-paged-bug-groups";
34
- import type { BugDetail } from "./types";
35
- import type { UserBrief } from "@/components/story/types";
34
+ import type { BugDetail } from "@/shared/bug/types";
35
+ import type { UserBrief } from "@/shared/story/types";
36
36
  import { BugDetailBody } from "./detail/bug-detail-body";
37
37
  import { BugPanelHeader } from "./bug-panel-header";
38
38
  import type { PeekMode } from "@/components/shared-kit/peek/peek-mode";
@@ -19,7 +19,7 @@ import { Plus, Trash2 } from "lucide-react";
19
19
  import { Button } from "@/components/ui/button";
20
20
  import { Input } from "@/components/ui/input";
21
21
  import { Textarea } from "@/components/ui/textarea";
22
- import type { ReproduceSteps, ReproduceStep } from "./types";
22
+ import type { ReproduceSteps, ReproduceStep } from "@/shared/bug/types";
23
23
  import { m } from "@/paraglide/messages.js";
24
24
 
25
25
  interface ReproduceStepsEditorProps {
@@ -55,7 +55,8 @@ import {
55
55
  } from "@/components/bug/views/bug-list/group-select";
56
56
  import { BUG_STATES, BUG_SEVERITIES, BUG_STATE_RANK, type BugState, type BugSeverity } from "@/shared/bug/constants";
57
57
  import { UserAvatar } from "@/components/shared-kit";
58
- import type { UserBrief, StoryEntityOverlay } from "@/components/story/types";
58
+ import type { UserBrief } from "@/shared/story/types";
59
+ import type { StoryEntityOverlay } from "@/components/story/entity-overlay";
59
60
  import type { AvatarConfig } from "@allbluecn/kernel";
60
61
  import { BugSelectDialog } from "@/components/bug/select-bug-dialog";
61
62
  import { m } from "@/paraglide/messages.js";
@@ -476,8 +477,9 @@ export function StoryBugsPanel({
476
477
  if (ids.length === 0) return;
477
478
  setBusy(true);
478
479
  try {
479
- await bulkUpdateBugsFn({ data: { bugIds: ids, patch: { state } } });
480
- toast.success(m.bug_storyPanel_stateUpdated({ count: ids.length }));
480
+ const res = await bulkUpdateBugsFn({ data: { bugIds: ids, patch: { state } } });
481
+ toast.success(m.bug_storyPanel_stateUpdated({ count: res.updated }));
482
+ if (res.failed > 0) toast.error(m.bug_storyPanel_partialFailed({ count: res.failed }));
481
483
  setLocalRefresh((k) => k + 1);
482
484
  } catch (e) {
483
485
  toastError(e, m.bug_storyPanel_updateFailed());
@@ -491,8 +493,9 @@ export function StoryBugsPanel({
491
493
  if (ids.length === 0) return;
492
494
  setBusy(true);
493
495
  try {
494
- await bulkUpdateBugsFn({ data: { bugIds: ids, patch: { severity } } });
495
- toast.success(m.bug_storyPanel_severityUpdated({ count: ids.length }));
496
+ const res = await bulkUpdateBugsFn({ data: { bugIds: ids, patch: { severity } } });
497
+ toast.success(m.bug_storyPanel_severityUpdated({ count: res.updated }));
498
+ if (res.failed > 0) toast.error(m.bug_storyPanel_partialFailed({ count: res.failed }));
496
499
  setLocalRefresh((k) => k + 1);
497
500
  } catch (e) {
498
501
  toastError(e, m.bug_storyPanel_updateFailed());
@@ -506,8 +509,9 @@ export function StoryBugsPanel({
506
509
  if (ids.length === 0) return;
507
510
  setBusy(true);
508
511
  try {
509
- const res: { archived: number } = await bulkArchiveBugsFn({ data: { bugIds: ids } });
512
+ const res: { archived: number; failed: number } = await bulkArchiveBugsFn({ data: { bugIds: ids } });
510
513
  toast.success(m.bug_storyPanel_archived({ count: res.archived }));
514
+ if (res.failed > 0) toast.error(m.bug_storyPanel_partialFailed({ count: res.failed }));
511
515
  setLocalRefresh((k) => k + 1);
512
516
  clearSelection();
513
517
  } catch (e) {
@@ -50,8 +50,8 @@ import { memo, useCallback, useMemo } from "react";
50
50
  import { Card, CardContent } from "@/components/ui/card";
51
51
  import { UserAvatar } from "@/components/shared-kit";
52
52
  import { updateBugFn } from "@/server/serverFns/bug";
53
- import type { BugListItem } from "../types";
54
- import type { UserBrief } from "@/components/story/types";
53
+ import type { BugListItem } from "@/shared/bug/types";
54
+ import type { UserBrief } from "@/shared/story/types";
55
55
  import type { BugPatch } from "../display/use-paged-bug-groups";
56
56
  import type { BugDisplayProperty, BugGroupKey } from "@/shared/bug/display-types";
57
57
  import { BUG_GROUP_DISPLAY_ORDER } from "@/shared/bug/display-types";
@@ -34,7 +34,7 @@ import {
34
34
  AssigneeEditor,
35
35
  LabelsEditor,
36
36
  } from "../../inline-editors";
37
- import type { UserBrief } from "@/components/story/types";
37
+ import type { UserBrief } from "@/shared/story/types";
38
38
  import type { BugPatch } from "../../display/use-paged-bug-groups";
39
39
  import { m } from "@/paraglide/messages.js";
40
40
 
@@ -19,7 +19,7 @@ import { memo, useEffect } from "react";
19
19
  import { ChevronDown, ChevronRight, Plus, Loader2, ChevronsDown } from "lucide-react";
20
20
  import { Button } from "@/components/ui/button";
21
21
  import { Checkbox } from "@/components/ui/checkbox";
22
- import type { UserBrief } from "@/components/story/types";
22
+ import type { UserBrief } from "@/shared/story/types";
23
23
  import { BUG_STATES, BUG_SEVERITIES, type BugState, type BugSeverity } from "@/shared/bug/constants";
24
24
  import type { BugGroupKey } from "@/shared/bug/display-types";
25
25
  import type { BugGroupNode } from "../../display/use-paged-bug-groups";
@@ -23,7 +23,7 @@ import {
23
23
  bulkUpdateBugsFn,
24
24
  } from "@/server/serverFns/bug";
25
25
  import { toast } from "@/components/ui/toast";
26
- import type { UserBrief } from "@/components/story/types";
26
+ import type { UserBrief } from "@/shared/story/types";
27
27
  import type { BugDisplayOptions, BugDisplayProperty } from "@/shared/bug/display-types";
28
28
  import type { BugGroupNode, BugPatch, PagedBugGroupNode } from "../../display/use-paged-bug-groups";
29
29
  import { BugGroupHeader, BugGroupTailRow } from "./group";
@@ -21,7 +21,7 @@ import { createBugFn } from "@/server/serverFns/bug";
21
21
  import { toast } from "@/components/ui/toast";
22
22
  import { Input } from "@/components/ui/input";
23
23
  import { Button } from "@/components/ui/button";
24
- import type { UserBrief } from "@/components/story/types";
24
+ import type { UserBrief } from "@/shared/story/types";
25
25
  import type { BugState, BugSeverity } from "@/shared/bug/constants";
26
26
  import { StateEditor, SeverityEditor, AssigneeEditor, LabelsEditor } from "../../inline-editors";
27
27
  import { m } from "@/paraglide/messages.js";
@@ -22,10 +22,10 @@ import { Checkbox } from "@/components/ui/checkbox";
22
22
  import { Input } from "@/components/ui/input";
23
23
  import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
24
24
  import { updateBugFn } from "@/server/serverFns/bug";
25
- import type { BugListItem } from "../../types";
25
+ import type { BugListItem } from "@/shared/bug/types";
26
26
  import type { BugState, BugSeverity } from "@/shared/bug/constants";
27
27
  import { SOURCE_LABEL, SOURCE_COLOR } from "@/shared/bug/constants";
28
- import type { UserBrief } from "@/components/story/types";
28
+ import type { UserBrief } from "@/shared/story/types";
29
29
  import type { BugDisplayProperty } from "@/shared/bug/display-types";
30
30
  import type { BugPatch } from "../../display/use-paged-bug-groups";
31
31
  import { StateEditor, SeverityEditor, AssigneeEditor, DateEditor, LabelsEditor } from "../../inline-editors";
@@ -33,7 +33,7 @@ import { Button } from "@/components/ui/button";
33
33
  import { Input } from "@/components/ui/input";
34
34
  import { LucideIconPicker } from "@/components/shared-kit/icons/lucide-icon-picker";
35
35
  import { BugFilterRow, type FilterCondition } from "../filters";
36
- import type { UserBrief } from "@/components/story/types";
36
+ import type { UserBrief } from "@/shared/story/types";
37
37
  import { m } from "@/paraglide/messages.js";
38
38
 
39
39
  export interface CreateViewDialogPayload {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { m } from '@/paraglide/messages.js'
5
- import { type DesignVersionWithSemver as DesignVersion } from "@allbluecn/kernel";
5
+ import { type DesignVersionFull } from "@allbluecn/kernel";
6
6
  import { listDesignVersionsFn } from "@/server/serverFns/design/versions";
7
7
  import { compareDesignVersionDesc, nextVersionAfter } from "../lib/semver";
8
8
 
@@ -15,7 +15,7 @@ const toVersionNum = (major: string, minor: string, patch: string): number =>
15
15
  * PRD 设计版本列表(semver 三元组输入、发布历史加载、更新/过低判定)。
16
16
  */
17
17
  export function useDesignVersions(designId: string) {
18
- const [versions, setVersions] = useState<DesignVersion[]>([]);
18
+ const [versions, setVersions] = useState<DesignVersionFull[]>([]);
19
19
  const [versionsLoading, setVersionsLoading] = useState(true);
20
20
  const [versionsError, setVersionsError] = useState("");
21
21
  const [major, setMajor] = useState("0");
@@ -35,7 +35,14 @@ export function useDesignVersions(designId: string) {
35
35
  listDesignVersionsFn({ data: { designId } })
36
36
  .then((data) => {
37
37
  if (seq !== loadSeqRef.current) return;
38
- const mapped = data.map((v) => ({ ...v, createdAt: v.createdAt.toISOString(), updatedAt: v.updatedAt?.toISOString() ?? null }));
38
+ const mapped = data.map((v) => ({
39
+ ...v,
40
+ createdAt: v.createdAt.toISOString(),
41
+ updatedAt: v.updatedAt?.toISOString() ?? null,
42
+ // S32:pageVersions 为 prisma Json 列,结构化形状由写侧(design/versions.ts)
43
+ // 保证;此为 Json 序列化边界唯一收窄点
44
+ pageVersions: v.pageVersions as DesignVersionFull["pageVersions"],
45
+ }));
39
46
  setVersions(mapped);
40
47
  setVersionsLoading(false);
41
48
  if (mapped.length > 0) {
@@ -67,7 +74,7 @@ export function useDesignVersions(designId: string) {
67
74
  setVersionTooLow(highest > 0 && vNum < highest && !isExisting);
68
75
  }, [major, minor, patch, versions]);
69
76
 
70
- const upsertVersion = useCallback((version: DesignVersion) => {
77
+ const upsertVersion = useCallback((version: DesignVersionFull) => {
71
78
  setVersions((prev) => {
72
79
  const filtered = prev.filter((v) => v.id !== version.id);
73
80
  return [...filtered, version].sort(sortVersionsDesc);