@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.
- package/dist/lib/share-utils.d.ts +2 -0
- package/dist/lib/share-utils.js +17 -0
- package/generated/browser.ts +10 -0
- package/generated/client.ts +10 -0
- package/generated/internal/class.ts +24 -4
- package/generated/internal/prismaNamespace.ts +188 -3
- package/generated/internal/prismaNamespaceBrowser.ts +37 -2
- package/generated/models/Iteration.ts +1878 -0
- package/generated/models/IterationAutoSchedule.ts +1485 -0
- package/generated/models/Project.ts +326 -0
- package/generated/models/Story.ts +393 -3
- package/generated/models/User.ts +618 -0
- package/generated/models.ts +2 -0
- package/generated-sqlite/browser.ts +15 -0
- package/generated-sqlite/client.ts +15 -0
- package/generated-sqlite/internal/class.ts +34 -4
- package/generated-sqlite/internal/prismaNamespace.ts +288 -2
- package/generated-sqlite/internal/prismaNamespaceBrowser.ts +62 -1
- package/generated-sqlite/models/Iteration.ts +1874 -0
- package/generated-sqlite/models/IterationAutoSchedule.ts +1483 -0
- package/generated-sqlite/models/Project.ts +484 -0
- package/generated-sqlite/models/Story.ts +3263 -0
- package/generated-sqlite/models/User.ts +2103 -107
- package/generated-sqlite/models.ts +3 -0
- package/index.ts +2 -2
- package/migrations/20260831203925_story_attachment_file_hash/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 +14 -5
- package/schema.prisma +47 -4
- 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/
|
|
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,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.18",
|
|
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,17 +15,21 @@
|
|
|
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",
|
|
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":
|
|
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
|
-
|
|
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
|
-
|
|
2127
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
2123
2128
|
|
|
2124
|
-
|
|
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
|
}
|
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")
|
|
@@ -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
|
-
|
|
120
|
-
|
|
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
|
+
}
|