@allbluecn/database 0.4.15 → 0.4.17
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.
- package/generated/browser.ts +20 -0
- package/generated/client.ts +20 -0
- package/generated/commonInputTypes.ts +34 -0
- package/generated/internal/class.ts +44 -4
- package/generated/internal/prismaNamespace.ts +378 -3
- package/generated/internal/prismaNamespaceBrowser.ts +63 -2
- package/generated/models/Iteration.ts +1878 -0
- package/generated/models/IterationAutoSchedule.ts +1485 -0
- package/generated/models/KnowledgeBase.ts +138 -0
- package/generated/models/Project.ts +484 -0
- package/generated/models/ProjectKnowledgeBase.ts +1430 -0
- package/generated/models/Story.ts +663 -3
- package/generated/models/StoryAttachment.ts +110 -1
- package/generated/models/StoryExternalLink.ts +1352 -0
- package/generated/models/User.ts +618 -0
- package/generated/models.ts +4 -0
- package/generated-sqlite/browser.ts +20 -0
- package/generated-sqlite/client.ts +20 -0
- package/generated-sqlite/internal/class.ts +44 -4
- package/generated-sqlite/internal/prismaNamespace.ts +374 -2
- package/generated-sqlite/internal/prismaNamespaceBrowser.ts +73 -1
- package/generated-sqlite/models/Iteration.ts +1874 -0
- package/generated-sqlite/models/IterationAutoSchedule.ts +1483 -0
- package/generated-sqlite/models/KnowledgeBase.ts +138 -0
- package/generated-sqlite/models/Project.ts +634 -0
- package/generated-sqlite/models/ProjectKnowledgeBase.ts +1426 -0
- package/generated-sqlite/models/Story.ts +3263 -0
- package/generated-sqlite/models/User.ts +2103 -107
- package/generated-sqlite/models.ts +4 -0
- package/index.ts +2 -2
- package/migrations/20260831063744_project_knowledge_base/migration.sql +24 -0
- package/migrations/20260831123150_story_external_link/migration.sql +19 -0
- package/migrations/20260831151740_story_attachment_bytes/migration.sql +2 -0
- package/migrations/20260831203925_story_attachment_file_hash/migration.sql +2 -0
- package/migrations/20260901010000_story_attachment_description/migration.sql +2 -0
- package/migrations/20260901020000_story_attachment_file_hash/migration.sql +2 -0
- package/migrations/20260901134601_iterations/migration.sql +52 -0
- package/migrations/20260902000000_story_identifier_per_project/migration.sql +37 -0
- package/migrations/20260902000100_story_identifier_counter_init/migration.sql +11 -0
- package/package.json +12 -5
- package/schema.prisma +98 -17
- package/schema.sqlite.prisma +112 -9
|
@@ -27,6 +27,7 @@ export type * from './models/InvitationCode'
|
|
|
27
27
|
export type * from './models/InvitationUse'
|
|
28
28
|
export type * from './models/PasswordResetToken'
|
|
29
29
|
export type * from './models/KnowledgeBase'
|
|
30
|
+
export type * from './models/ProjectKnowledgeBase'
|
|
30
31
|
export type * from './models/KnowledgeDocument'
|
|
31
32
|
export type * from './models/PRD'
|
|
32
33
|
export type * from './models/AgentConversation'
|
|
@@ -86,4 +87,7 @@ export type * from './models/ComplianceExport'
|
|
|
86
87
|
export type * from './models/UserAgent'
|
|
87
88
|
export type * from './models/UserSkill'
|
|
88
89
|
export type * from './models/DeveloperLog'
|
|
90
|
+
export type * from './models/Story'
|
|
91
|
+
export type * from './models/Iteration'
|
|
92
|
+
export type * from './models/IterationAutoSchedule'
|
|
89
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/
|
|
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/
|
|
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,24 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "project_knowledge_bases" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"projectId" TEXT NOT NULL,
|
|
5
|
+
"kbId" TEXT NOT NULL,
|
|
6
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
7
|
+
|
|
8
|
+
CONSTRAINT "project_knowledge_bases_pkey" PRIMARY KEY ("id")
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
-- CreateIndex
|
|
12
|
+
CREATE INDEX "project_knowledge_bases_projectId_idx" ON "project_knowledge_bases"("projectId");
|
|
13
|
+
|
|
14
|
+
-- CreateIndex
|
|
15
|
+
CREATE INDEX "project_knowledge_bases_kbId_idx" ON "project_knowledge_bases"("kbId");
|
|
16
|
+
|
|
17
|
+
-- CreateIndex
|
|
18
|
+
CREATE UNIQUE INDEX "project_knowledge_bases_projectId_kbId_key" ON "project_knowledge_bases"("projectId", "kbId");
|
|
19
|
+
|
|
20
|
+
-- AddForeignKey
|
|
21
|
+
ALTER TABLE "project_knowledge_bases" ADD CONSTRAINT "project_knowledge_bases_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
22
|
+
|
|
23
|
+
-- AddForeignKey
|
|
24
|
+
ALTER TABLE "project_knowledge_bases" ADD CONSTRAINT "project_knowledge_bases_kbId_fkey" FOREIGN KEY ("kbId") REFERENCES "knowledge_bases"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "story_external_links" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"storyId" TEXT NOT NULL,
|
|
5
|
+
"group" TEXT NOT NULL,
|
|
6
|
+
"externalId" TEXT NOT NULL,
|
|
7
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
|
|
9
|
+
CONSTRAINT "story_external_links_pkey" PRIMARY KEY ("id")
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
-- CreateIndex
|
|
13
|
+
CREATE INDEX "story_external_links_storyId_idx" ON "story_external_links"("storyId");
|
|
14
|
+
|
|
15
|
+
-- CreateIndex
|
|
16
|
+
CREATE UNIQUE INDEX "story_external_links_storyId_group_externalId_key" ON "story_external_links"("storyId", "group", "externalId");
|
|
17
|
+
|
|
18
|
+
-- AddForeignKey
|
|
19
|
+
ALTER TABLE "story_external_links" ADD CONSTRAINT "story_external_links_storyId_fkey" FOREIGN KEY ("storyId") REFERENCES "stories"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -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.
|
|
3
|
+
"version": "0.4.17",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./index.
|
|
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,7 +15,7 @@
|
|
|
15
15
|
"pg": "^8.22.0",
|
|
16
16
|
"sqlite-vec": "^0.1.9",
|
|
17
17
|
"bcryptjs": "^3.0.2",
|
|
18
|
-
"@allbluecn/
|
|
18
|
+
"@allbluecn/kernel": "0.5.2"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"exports": {
|
|
27
27
|
".": "./index.ts",
|
|
28
|
-
"./lib/share-utils":
|
|
28
|
+
"./lib/share-utils": {
|
|
29
|
+
"types": "./dist/lib/share-utils.d.ts",
|
|
30
|
+
"default": "./dist/lib/share-utils.js"
|
|
31
|
+
}
|
|
29
32
|
},
|
|
30
33
|
"repository": {
|
|
31
34
|
"type": "git",
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
"url": "https://github.com/urmynami/AllBlue/issues"
|
|
37
40
|
},
|
|
38
41
|
"files": [
|
|
42
|
+
"dist",
|
|
39
43
|
"src",
|
|
40
44
|
"!src/**/*.test.*",
|
|
41
45
|
"!src/**/__tests__/**",
|
|
@@ -49,6 +53,9 @@
|
|
|
49
53
|
"desktop-init.d.ts",
|
|
50
54
|
"index.ts"
|
|
51
55
|
],
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
52
59
|
"scripts": {
|
|
53
60
|
"generate": "prisma generate",
|
|
54
61
|
"migrate:dev": "prisma migrate dev",
|
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
|
-
|
|
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")
|
|
@@ -152,8 +153,11 @@ model Project {
|
|
|
152
153
|
workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: SetNull)
|
|
153
154
|
members ProjectMember[]
|
|
154
155
|
activities ProjectActivity[]
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
stories Story[]
|
|
157
|
+
iterations Iteration[]
|
|
158
|
+
iterationAutoSchedule IterationAutoSchedule?
|
|
159
|
+
knowledgeBases ProjectKnowledgeBase[]
|
|
160
|
+
createdAt DateTime @default(now())
|
|
157
161
|
updatedAt DateTime @updatedAt
|
|
158
162
|
|
|
159
163
|
@@unique([ownerId, displayId])
|
|
@@ -479,11 +483,12 @@ model KnowledgeBase {
|
|
|
479
483
|
createdAt DateTime @default(now())
|
|
480
484
|
updatedAt DateTime @updatedAt
|
|
481
485
|
|
|
482
|
-
|
|
483
|
-
|
|
486
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
487
|
+
documents KnowledgeDocument[]
|
|
488
|
+
projectLinks ProjectKnowledgeBase[]
|
|
484
489
|
|
|
485
|
-
|
|
486
|
-
|
|
490
|
+
@@index([userId])
|
|
491
|
+
@@map("knowledge_bases")
|
|
487
492
|
}
|
|
488
493
|
|
|
489
494
|
model KnowledgeDocument {
|
|
@@ -1413,8 +1418,11 @@ model Story {
|
|
|
1413
1418
|
attachments StoryAttachment[]
|
|
1414
1419
|
linkedPrds StoryPrdLink[] @relation("StoryPrdLinks")
|
|
1415
1420
|
linkedDocs StoryDocLink[] @relation("StoryDocLinks")
|
|
1421
|
+
linkedExternalDocs StoryExternalLink[] @relation("StoryExternalLinks")
|
|
1422
|
+
iterationId String?
|
|
1423
|
+
iteration Iteration? @relation(fields: [iterationId], references: [id], onDelete: SetNull)
|
|
1416
1424
|
|
|
1417
|
-
@@unique([identifier])
|
|
1425
|
+
@@unique([projectId, identifier])
|
|
1418
1426
|
@@index([projectId, sequenceId])
|
|
1419
1427
|
@@index([state])
|
|
1420
1428
|
@@index([archived])
|
|
@@ -1538,6 +1546,22 @@ model StoryDependency {
|
|
|
1538
1546
|
@@map("story_dependencies")
|
|
1539
1547
|
}
|
|
1540
1548
|
|
|
1549
|
+
// 项目关联知识库(join 表;关联时仅允许 visibility=team,general 全局可见无需关联,private 跨用户不可读)
|
|
1550
|
+
model ProjectKnowledgeBase {
|
|
1551
|
+
id String @id @default(cuid())
|
|
1552
|
+
projectId String
|
|
1553
|
+
kbId String
|
|
1554
|
+
createdAt DateTime @default(now())
|
|
1555
|
+
|
|
1556
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
1557
|
+
kb KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
|
|
1558
|
+
|
|
1559
|
+
@@unique([projectId, kbId])
|
|
1560
|
+
@@index([projectId])
|
|
1561
|
+
@@index([kbId])
|
|
1562
|
+
@@map("project_knowledge_bases")
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1541
1565
|
model StoryLink {
|
|
1542
1566
|
id String @id @default(cuid())
|
|
1543
1567
|
storyId String
|
|
@@ -1554,17 +1578,21 @@ model StoryLink {
|
|
|
1554
1578
|
}
|
|
1555
1579
|
|
|
1556
1580
|
model StoryAttachment {
|
|
1557
|
-
id
|
|
1558
|
-
storyId
|
|
1559
|
-
fileName
|
|
1560
|
-
fileSize
|
|
1561
|
-
mimeType
|
|
1562
|
-
|
|
1563
|
-
|
|
1581
|
+
id String @id @default(cuid())
|
|
1582
|
+
storyId String
|
|
1583
|
+
fileName String
|
|
1584
|
+
fileSize BigInt
|
|
1585
|
+
mimeType String
|
|
1586
|
+
description String?
|
|
1587
|
+
storageUrl String
|
|
1588
|
+
bytes Bytes?
|
|
1589
|
+
fileHash String? @db.Text
|
|
1590
|
+
createdAt DateTime @default(now())
|
|
1564
1591
|
|
|
1565
1592
|
story Story @relation(fields: [storyId], references: [id], onDelete: Cascade)
|
|
1566
1593
|
|
|
1567
1594
|
@@index([storyId])
|
|
1595
|
+
@@index([fileHash])
|
|
1568
1596
|
@@map("story_attachments")
|
|
1569
1597
|
}
|
|
1570
1598
|
|
|
@@ -1598,6 +1626,21 @@ model StoryDocLink {
|
|
|
1598
1626
|
@@map("story_doc_links")
|
|
1599
1627
|
}
|
|
1600
1628
|
|
|
1629
|
+
// 通用知识库条目(法律法规/行业合规/词典词条/网站收藏)与需求的关联
|
|
1630
|
+
model StoryExternalLink {
|
|
1631
|
+
id String @id @default(cuid())
|
|
1632
|
+
storyId String
|
|
1633
|
+
group String
|
|
1634
|
+
externalId String
|
|
1635
|
+
createdAt DateTime @default(now())
|
|
1636
|
+
|
|
1637
|
+
story Story @relation("StoryExternalLinks", fields: [storyId], references: [id], onDelete: Cascade)
|
|
1638
|
+
|
|
1639
|
+
@@unique([storyId, group, externalId])
|
|
1640
|
+
@@index([storyId])
|
|
1641
|
+
@@map("story_external_links")
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1601
1644
|
enum DependencyType {
|
|
1602
1645
|
BLOCKS
|
|
1603
1646
|
STARTS_BEFORE
|
|
@@ -2081,7 +2124,45 @@ model NotificationPreference {
|
|
|
2081
2124
|
dndEnabled Boolean @default(false)
|
|
2082
2125
|
dndStart String @default("22:00")
|
|
2083
2126
|
dndEnd String @default("08:00")
|
|
2084
|
-
|
|
2127
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
2085
2128
|
|
|
2086
|
-
|
|
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")
|
|
2087
2168
|
}
|
package/schema.sqlite.prisma
CHANGED
|
@@ -86,8 +86,12 @@ model User {
|
|
|
86
86
|
aiProviderConfigs AiProviderConfig[]
|
|
87
87
|
agentConversations AgentConversation[]
|
|
88
88
|
ownedProjects Project[] @relation("projectOwner")
|
|
89
|
-
|
|
90
|
-
|
|
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")
|
|
@@ -114,9 +118,13 @@ model Project {
|
|
|
114
118
|
owner User @relation("projectOwner", fields: [ownerId], references: [id])
|
|
115
119
|
workspaceId String?
|
|
116
120
|
workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: SetNull)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
members ProjectMember[]
|
|
122
|
+
activities ProjectActivity[]
|
|
123
|
+
knowledgeBases ProjectKnowledgeBase[]
|
|
124
|
+
iterations Iteration[]
|
|
125
|
+
iterationAutoSchedule IterationAutoSchedule?
|
|
126
|
+
stories Story[]
|
|
127
|
+
createdAt DateTime @default(now())
|
|
120
128
|
updatedAt DateTime @updatedAt
|
|
121
129
|
|
|
122
130
|
@@unique([ownerId, displayId])
|
|
@@ -398,11 +406,28 @@ model KnowledgeBase {
|
|
|
398
406
|
createdAt DateTime @default(now())
|
|
399
407
|
updatedAt DateTime @updatedAt
|
|
400
408
|
|
|
401
|
-
|
|
402
|
-
|
|
409
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
410
|
+
documents KnowledgeDocument[]
|
|
411
|
+
projectLinks ProjectKnowledgeBase[]
|
|
403
412
|
|
|
404
|
-
|
|
405
|
-
|
|
413
|
+
@@index([userId])
|
|
414
|
+
@@map("knowledge_bases")
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// 项目关联知识库(join 表;关联时仅允许 visibility=team,general 全局可见无需关联,private 跨用户不可读)
|
|
418
|
+
model ProjectKnowledgeBase {
|
|
419
|
+
id String @id @default(cuid())
|
|
420
|
+
projectId String
|
|
421
|
+
kbId String
|
|
422
|
+
createdAt DateTime @default(now())
|
|
423
|
+
|
|
424
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
425
|
+
kb KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
|
|
426
|
+
|
|
427
|
+
@@unique([projectId, kbId])
|
|
428
|
+
@@index([projectId])
|
|
429
|
+
@@index([kbId])
|
|
430
|
+
@@map("project_knowledge_bases")
|
|
406
431
|
}
|
|
407
432
|
|
|
408
433
|
model KnowledgeDocument {
|
|
@@ -1622,3 +1647,81 @@ model DeveloperLog {
|
|
|
1622
1647
|
@@index([year, date])
|
|
1623
1648
|
@@map("developer_logs")
|
|
1624
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
|
+
}
|