@allbluecn/database 0.4.16 → 0.4.18

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 (33) hide show
  1. package/dist/lib/share-utils.d.ts +2 -0
  2. package/dist/lib/share-utils.js +17 -0
  3. package/generated/browser.ts +10 -0
  4. package/generated/client.ts +10 -0
  5. package/generated/internal/class.ts +24 -4
  6. package/generated/internal/prismaNamespace.ts +188 -3
  7. package/generated/internal/prismaNamespaceBrowser.ts +37 -2
  8. package/generated/models/Iteration.ts +1878 -0
  9. package/generated/models/IterationAutoSchedule.ts +1485 -0
  10. package/generated/models/Project.ts +326 -0
  11. package/generated/models/Story.ts +393 -3
  12. package/generated/models/User.ts +618 -0
  13. package/generated/models.ts +2 -0
  14. package/generated-sqlite/browser.ts +15 -0
  15. package/generated-sqlite/client.ts +15 -0
  16. package/generated-sqlite/internal/class.ts +34 -4
  17. package/generated-sqlite/internal/prismaNamespace.ts +288 -2
  18. package/generated-sqlite/internal/prismaNamespaceBrowser.ts +62 -1
  19. package/generated-sqlite/models/Iteration.ts +1874 -0
  20. package/generated-sqlite/models/IterationAutoSchedule.ts +1483 -0
  21. package/generated-sqlite/models/Project.ts +484 -0
  22. package/generated-sqlite/models/Story.ts +3263 -0
  23. package/generated-sqlite/models/User.ts +2103 -107
  24. package/generated-sqlite/models.ts +3 -0
  25. package/index.ts +2 -2
  26. package/migrations/20260831203925_story_attachment_file_hash/migration.sql +2 -0
  27. package/migrations/20260901020000_story_attachment_file_hash/migration.sql +2 -0
  28. package/migrations/20260901134601_iterations/migration.sql +52 -0
  29. package/migrations/20260902000000_story_identifier_per_project/migration.sql +37 -0
  30. package/migrations/20260902000100_story_identifier_counter_init/migration.sql +11 -0
  31. package/package.json +14 -5
  32. package/schema.prisma +47 -4
  33. package/schema.sqlite.prisma +89 -4
@@ -87,4 +87,7 @@ export type * from './models/ComplianceExport'
87
87
  export type * from './models/UserAgent'
88
88
  export type * from './models/UserSkill'
89
89
  export type * from './models/DeveloperLog'
90
+ export type * from './models/Story'
91
+ export type * from './models/Iteration'
92
+ export type * from './models/IterationAutoSchedule'
90
93
  export type * from './commonInputTypes'
package/index.ts CHANGED
@@ -18,7 +18,7 @@
18
18
  import { PrismaClient } from "./generated/client";
19
19
  import { PrismaPg } from "@prisma/adapter-pg";
20
20
  import { Prisma } from "./generated/client";
21
- import { registerPrismaSeam } from "@allbluecn/shared/server-seam";
21
+ import { registerPrismaSeam } from "@allbluecn/kernel";
22
22
 
23
23
  const globalForPrisma = globalThis as unknown as {
24
24
  prisma: PrismaClient | undefined;
@@ -65,7 +65,7 @@ export const prisma: PrismaClient = globalForPrisma.prisma ?? (await createPrism
65
65
  if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
66
66
 
67
67
  // 注册 PrismaSeam,供 shared 包注入式访问 prisma
68
- registerPrismaSeam(prisma as unknown as import("@allbluecn/shared/server-seam").PrismaSeam);
68
+ registerPrismaSeam(prisma as unknown as import("@allbluecn/kernel").PrismaSeam);
69
69
 
70
70
  export { Prisma };
71
71
  export type { PrismaClient } from "./generated/client";
@@ -0,0 +1,2 @@
1
+ -- 恢复丢失的迁移:story_attachments 新增 fileHash 列(内容去重)
2
+ ALTER TABLE "story_attachments" ADD COLUMN IF NOT EXISTS "fileHash" TEXT;
@@ -0,0 +1,2 @@
1
+ -- 恢复丢失的迁移:fileHash 索引(幂等,列已存在场景)
2
+ CREATE INDEX IF NOT EXISTS "story_attachments_fileHash_idx" ON "story_attachments"("fileHash");
@@ -0,0 +1,52 @@
1
+ -- AlterTable
2
+ ALTER TABLE "stories" ADD COLUMN "iterationId" TEXT;
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "iterations" (
6
+ "id" TEXT NOT NULL,
7
+ "projectId" TEXT NOT NULL,
8
+ "name" TEXT NOT NULL,
9
+ "description" TEXT,
10
+ "startDate" TIMESTAMP(3) NOT NULL,
11
+ "endDate" TIMESTAMP(3) NOT NULL,
12
+ "archived" BOOLEAN NOT NULL DEFAULT false,
13
+ "archivedAt" TIMESTAMP(3),
14
+ "createdById" TEXT NOT NULL,
15
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
16
+ "updatedAt" TIMESTAMP(3) NOT NULL,
17
+
18
+ CONSTRAINT "iterations_pkey" PRIMARY KEY ("id")
19
+ );
20
+
21
+ -- CreateTable
22
+ CREATE TABLE "iteration_auto_schedules" (
23
+ "projectId" TEXT NOT NULL,
24
+ "enabled" BOOLEAN NOT NULL DEFAULT false,
25
+ "title" TEXT NOT NULL DEFAULT '迭代',
26
+ "durationDays" INTEGER NOT NULL DEFAULT 14,
27
+ "cooldownDays" INTEGER NOT NULL DEFAULT 0,
28
+ "startsOn" TIMESTAMP(3) NOT NULL,
29
+ "futureCount" INTEGER NOT NULL DEFAULT 2,
30
+ "autoRollover" BOOLEAN NOT NULL DEFAULT false,
31
+ "lastSeq" INTEGER NOT NULL DEFAULT 0,
32
+
33
+ CONSTRAINT "iteration_auto_schedules_pkey" PRIMARY KEY ("projectId")
34
+ );
35
+
36
+ -- CreateIndex
37
+ CREATE INDEX "iterations_projectId_startDate_idx" ON "iterations"("projectId", "startDate");
38
+
39
+ -- CreateIndex
40
+ CREATE INDEX "iterations_archived_idx" ON "iterations"("archived");
41
+
42
+ -- AddForeignKey
43
+ ALTER TABLE "stories" ADD CONSTRAINT "stories_iterationId_fkey" FOREIGN KEY ("iterationId") REFERENCES "iterations"("id") ON DELETE SET NULL ON UPDATE CASCADE;
44
+
45
+ -- AddForeignKey
46
+ ALTER TABLE "iterations" ADD CONSTRAINT "iterations_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
47
+
48
+ -- AddForeignKey
49
+ ALTER TABLE "iterations" ADD CONSTRAINT "iterations_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
50
+
51
+ -- AddForeignKey
52
+ ALTER TABLE "iteration_auto_schedules" ADD CONSTRAINT "iteration_auto_schedules_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,37 @@
1
+ -- Story identifier 改为项目内唯一:独立需求(displayId='STORY')按用户独立计数,从 STORY-1 开始
2
+ -- 1. 删除全局唯一索引(历史上以裸 UNIQUE INDEX 形式创建,非约束)
3
+ DROP INDEX IF EXISTS "stories_identifier_key";
4
+
5
+ -- 2. 重编号独立需求:先把参与行改为临时名,避免批量重写期间瞬时同名冲突
6
+ WITH ranked AS (
7
+ SELECT s.id
8
+ FROM "stories" s
9
+ JOIN "projects" p ON p.id = s."projectId"
10
+ WHERE p."displayId" = 'STORY'
11
+ )
12
+ UPDATE "stories" s
13
+ SET "identifier" = 'TMP-' || s.id
14
+ FROM ranked r
15
+ WHERE s.id = r.id;
16
+
17
+ -- 3. 每个项目(即每个用户)按创建顺序重排为 STORY-1..N
18
+ WITH ranked AS (
19
+ SELECT s.id,
20
+ ROW_NUMBER() OVER (PARTITION BY s."projectId" ORDER BY s."createdAt", s.id) AS rn
21
+ FROM "stories" s
22
+ JOIN "projects" p ON p.id = s."projectId"
23
+ WHERE p."displayId" = 'STORY'
24
+ )
25
+ UPDATE "stories" s
26
+ SET "identifier" = 'STORY-' || r.rn,
27
+ "sequenceId" = r.rn
28
+ FROM ranked r
29
+ WHERE s.id = r.id;
30
+
31
+ -- 4. 重置计数器:清掉全局计数器与独立项目计数器(新逻辑将按 projectId 计数)
32
+ DELETE FROM "sequence_counters" WHERE scope = 'global';
33
+ DELETE FROM "sequence_counters"
34
+ WHERE scope IN (SELECT id FROM "projects" WHERE "displayId" = 'STORY');
35
+
36
+ -- 5. 新复合唯一约束(项目内 identifier 唯一)
37
+ ALTER TABLE "stories" ADD CONSTRAINT "stories_projectId_identifier_key" UNIQUE ("projectId", "identifier");
@@ -0,0 +1,11 @@
1
+ -- 补丁:初始化独立项目计数器为各项目现有 max(sequenceId),避免新需求编号与重编号后的已有需求冲突
2
+ INSERT INTO "sequence_counters" ("id", "scope", "seq")
3
+ SELECT md5(random()::text || s.scope), s.scope, s.seq
4
+ FROM (
5
+ SELECT p.id AS scope, COALESCE(MAX(st."sequenceId"), 0) AS seq
6
+ FROM "projects" p
7
+ LEFT JOIN "stories" st ON st."projectId" = p.id
8
+ WHERE p."displayId" = 'STORY'
9
+ GROUP BY p.id
10
+ ) s
11
+ ON CONFLICT ("scope") DO UPDATE SET "seq" = GREATEST("sequence_counters"."seq", EXCLUDED."seq");
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@allbluecn/database",
3
- "version": "0.4.16",
3
+ "version": "0.4.18",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "type": "module",
6
- "main": "./index.ts",
7
- "types": "./index.ts",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
8
  "dependencies": {
9
9
  "@prisma/adapter-better-sqlite3": "^7.9.0",
10
10
  "@prisma/adapter-pg": "7.8.0",
@@ -15,17 +15,21 @@
15
15
  "pg": "^8.22.0",
16
16
  "sqlite-vec": "^0.1.9",
17
17
  "bcryptjs": "^3.0.2",
18
- "@allbluecn/shared": "0.4.17"
18
+ "@allbluecn/kernel": "0.5.2"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/better-sqlite3": "^7.6.13",
22
+ "esbuild": "^0.25.0",
22
23
  "prisma": "^7.8.0",
23
24
  "tsx": "^4.22.0",
24
25
  "vitest": "^4.1.10"
25
26
  },
26
27
  "exports": {
27
28
  ".": "./index.ts",
28
- "./lib/share-utils": "./src/lib/share-utils.ts"
29
+ "./lib/share-utils": {
30
+ "types": "./dist/lib/share-utils.d.ts",
31
+ "default": "./dist/lib/share-utils.js"
32
+ }
29
33
  },
30
34
  "repository": {
31
35
  "type": "git",
@@ -36,6 +40,7 @@
36
40
  "url": "https://github.com/urmynami/AllBlue/issues"
37
41
  },
38
42
  "files": [
43
+ "dist",
39
44
  "src",
40
45
  "!src/**/*.test.*",
41
46
  "!src/**/__tests__/**",
@@ -49,7 +54,11 @@
49
54
  "desktop-init.d.ts",
50
55
  "index.ts"
51
56
  ],
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
52
60
  "scripts": {
61
+ "build": "node ./scripts/build-dist.mjs",
53
62
  "generate": "prisma generate",
54
63
  "migrate:dev": "prisma migrate dev",
55
64
  "migrate:deploy": "prisma migrate deploy",
package/schema.prisma CHANGED
@@ -83,7 +83,8 @@ model User {
83
83
  designProjects DesignProject[]
84
84
  storiesCreated Story[] @relation("storyCreator")
85
85
  storiesAssigned Story[] @relation("storyAssignee")
86
- storiesEdited Story[] @relation("storyEditor")
86
+ storiesEdited Story[] @relation("storyEditor")
87
+ iterationsCreated Iteration[] @relation("iterationCreator")
87
88
  labelsCreated Label[] @relation("labelCreator")
88
89
  storyActivities StoryActivity[] @relation("storyActivityUser")
89
90
  storyComments StoryComment[] @relation("storyCommentUser")
@@ -153,6 +154,8 @@ model Project {
153
154
  members ProjectMember[]
154
155
  activities ProjectActivity[]
155
156
  stories Story[]
157
+ iterations Iteration[]
158
+ iterationAutoSchedule IterationAutoSchedule?
156
159
  knowledgeBases ProjectKnowledgeBase[]
157
160
  createdAt DateTime @default(now())
158
161
  updatedAt DateTime @updatedAt
@@ -1416,8 +1419,10 @@ model Story {
1416
1419
  linkedPrds StoryPrdLink[] @relation("StoryPrdLinks")
1417
1420
  linkedDocs StoryDocLink[] @relation("StoryDocLinks")
1418
1421
  linkedExternalDocs StoryExternalLink[] @relation("StoryExternalLinks")
1422
+ iterationId String?
1423
+ iteration Iteration? @relation(fields: [iterationId], references: [id], onDelete: SetNull)
1419
1424
 
1420
- @@unique([identifier])
1425
+ @@unique([projectId, identifier])
1421
1426
  @@index([projectId, sequenceId])
1422
1427
  @@index([state])
1423
1428
  @@index([archived])
@@ -2119,7 +2124,45 @@ model NotificationPreference {
2119
2124
  dndEnabled Boolean @default(false)
2120
2125
  dndStart String @default("22:00")
2121
2126
  dndEnd String @default("08:00")
2122
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
2127
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
2123
2128
 
2124
- @@map("notification_preferences")
2129
+ @@map("notification_preferences")
2130
+ }
2131
+
2132
+ // 迭代(时间盒冲刺,状态由日期动态推导,不存状态字段)
2133
+ model Iteration {
2134
+ id String @id @default(cuid())
2135
+ projectId String
2136
+ project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
2137
+ name String
2138
+ description String? @db.Text
2139
+ startDate DateTime
2140
+ endDate DateTime
2141
+ archived Boolean @default(false)
2142
+ archivedAt DateTime?
2143
+ createdById String
2144
+ createdBy User @relation("iterationCreator", fields: [createdById], references: [id])
2145
+ createdAt DateTime @default(now())
2146
+ updatedAt DateTime @updatedAt
2147
+ stories Story[]
2148
+
2149
+ @@index([projectId, startDate])
2150
+ @@index([archived])
2151
+ @@map("iterations")
2152
+ }
2153
+
2154
+ // 迭代自动排期配置(一项目一行)
2155
+ model IterationAutoSchedule {
2156
+ projectId String @id
2157
+ project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
2158
+ enabled Boolean @default(false)
2159
+ title String @default("迭代")
2160
+ durationDays Int @default(14)
2161
+ cooldownDays Int @default(0)
2162
+ startsOn DateTime
2163
+ futureCount Int @default(2)
2164
+ autoRollover Boolean @default(false)
2165
+ lastSeq Int @default(0)
2166
+
2167
+ @@map("iteration_auto_schedules")
2125
2168
  }
@@ -86,8 +86,12 @@ model User {
86
86
  aiProviderConfigs AiProviderConfig[]
87
87
  agentConversations AgentConversation[]
88
88
  ownedProjects Project[] @relation("projectOwner")
89
- projectMemberships ProjectMember[]
90
- projectActivities ProjectActivity[]
89
+ projectMemberships ProjectMember[]
90
+ iterationsCreated Iteration[] @relation("iterationCreator")
91
+ storiesCreated Story[] @relation("storyCreator")
92
+ storiesAssigned Story[] @relation("storyAssignee")
93
+ storiesEdited Story[] @relation("storyEditor")
94
+ projectActivities ProjectActivity[]
91
95
  ownedWorkspaces Workspace[] @relation("workspaceOwner")
92
96
  workspaceMemberships TeamMembership[] @relation("teamOwner")
93
97
  teamJoined TeamMembership? @relation("teamMember")
@@ -116,8 +120,11 @@ model Project {
116
120
  workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: SetNull)
117
121
  members ProjectMember[]
118
122
  activities ProjectActivity[]
119
- knowledgeBases ProjectKnowledgeBase[]
120
- createdAt DateTime @default(now())
123
+ knowledgeBases ProjectKnowledgeBase[]
124
+ iterations Iteration[]
125
+ iterationAutoSchedule IterationAutoSchedule?
126
+ stories Story[]
127
+ createdAt DateTime @default(now())
121
128
  updatedAt DateTime @updatedAt
122
129
 
123
130
  @@unique([ownerId, displayId])
@@ -1640,3 +1647,81 @@ model DeveloperLog {
1640
1647
  @@index([year, date])
1641
1648
  @@map("developer_logs")
1642
1649
  }
1650
+
1651
+ // 需求(简化版,与 psql schema 对齐)
1652
+ model Story {
1653
+ id String @id @default(cuid())
1654
+ sequenceId Int
1655
+ boardOrder Int @default(0)
1656
+ identifier String
1657
+ projectId String
1658
+ project Project @relation(fields: [projectId], references: [id], onDelete: Restrict)
1659
+ name String
1660
+ description String?
1661
+ state String @default("backlog")
1662
+ priority String @default("none")
1663
+ archived Boolean @default(false)
1664
+ archivedAt DateTime?
1665
+ assigneeId String?
1666
+ assignee User? @relation("storyAssignee", fields: [assigneeId], references: [id], onDelete: SetNull)
1667
+ startDate DateTime?
1668
+ targetDate DateTime?
1669
+ createdById String
1670
+ createdBy User @relation("storyCreator", fields: [createdById], references: [id])
1671
+ updatedById String?
1672
+ updatedBy User? @relation("storyEditor", fields: [updatedById], references: [id], onDelete: SetNull)
1673
+ parentId String?
1674
+ parent Story? @relation("StoryHierarchy", fields: [parentId], references: [id], onDelete: SetNull)
1675
+ children Story[] @relation("StoryHierarchy")
1676
+ iterationId String?
1677
+ iteration Iteration? @relation(fields: [iterationId], references: [id], onDelete: SetNull)
1678
+ createdAt DateTime @default(now())
1679
+ updatedAt DateTime @updatedAt
1680
+
1681
+ @@unique([projectId, identifier])
1682
+ @@index([projectId, sequenceId])
1683
+ @@index([state])
1684
+ @@index([archived])
1685
+ @@index([archived, state, createdAt])
1686
+ @@index([assigneeId])
1687
+ @@index([createdById])
1688
+ @@map("stories")
1689
+ }
1690
+
1691
+ // 迭代(时间盒冲刺,状态由日期动态推导,不存状态字段)
1692
+ model Iteration {
1693
+ id String @id @default(cuid())
1694
+ projectId String
1695
+ project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
1696
+ name String
1697
+ description String?
1698
+ startDate DateTime
1699
+ endDate DateTime
1700
+ archived Boolean @default(false)
1701
+ archivedAt DateTime?
1702
+ createdById String
1703
+ createdBy User @relation("iterationCreator", fields: [createdById], references: [id])
1704
+ createdAt DateTime @default(now())
1705
+ updatedAt DateTime @updatedAt
1706
+ stories Story[]
1707
+
1708
+ @@index([projectId, startDate])
1709
+ @@index([archived])
1710
+ @@map("iterations")
1711
+ }
1712
+
1713
+ // 迭代自动排期配置(一项目一行)
1714
+ model IterationAutoSchedule {
1715
+ projectId String @id
1716
+ project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
1717
+ enabled Boolean @default(false)
1718
+ title String @default("迭代")
1719
+ durationDays Int @default(14)
1720
+ cooldownDays Int @default(0)
1721
+ startsOn DateTime
1722
+ futureCount Int @default(2)
1723
+ autoRollover Boolean @default(false)
1724
+ lastSeq Int @default(0)
1725
+
1726
+ @@map("iteration_auto_schedules")
1727
+ }