Issue changes are recorded per field in the issue_change table, in the same transaction as the issue itself. The new history module exposes: - GET /api/issues/:issueId/history — change timeline grouped by save - GET /api/issues/stats/daily — created, status transitions and status snapshot per day, with time zone support The migration backfills history for existing issues. Setting a field to its current value no longer bumps updatedAt or emits issue.updated.
This commit is contained in:
1 parent
f44590b8ca
commit
cb29c7d2c4
26 files changed
+1026
-16
No files matched your search
@@ -26,6 +26,7 @@ model User {
|
||||
notificationMessages NotificationMessage[]
|
||||
comments Comment[]
|
||||
uploadedFiles File[]
|
||||
issueChanges IssueChange[]
|
||||
|
||||
@@unique([email])
|
||||
@@map("user")
|
||||
@@ -96,6 +97,7 @@ model Issue {
|
||||
dueDate DateTime? @db.Timestamptz(3)
|
||||
comments Comment[]
|
||||
attachments IssueAttachment[]
|
||||
changes IssueChange[]
|
||||
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @db.Timestamptz(3)
|
||||
|
||||
@@ -264,3 +266,29 @@ model CommentAttachment {
|
||||
@@index([fileId])
|
||||
@@map("comment_attachment")
|
||||
}
|
||||
|
||||
/// История изменений задачи — одна строка на изменённое поле.
|
||||
/// Строки одного сохранения задачи объединены общим changeId.
|
||||
/// field: created | title | content | status | priority | assignee | dueDate
|
||||
/// (валидируется в коде, см. ISSUE_CHANGE_FIELDS). Значения — строки:
|
||||
/// priority — число, dueDate — ISO-дата, assignee — id пользователя.
|
||||
/// При создании задачи пишутся две строки: created и status null -> OPEN,
|
||||
/// поэтому статус задачи на любой момент восстанавливается по строкам status.
|
||||
/// У задач, созданных до появления истории, строк нет — в статистику они не попадают.
|
||||
model IssueChange {
|
||||
id Int @id @default(autoincrement())
|
||||
issueId Int
|
||||
issue Issue @relation(fields: [issueId], references: [id], onDelete: Cascade)
|
||||
changeId String
|
||||
field String
|
||||
oldValue String?
|
||||
newValue String?
|
||||
actorId String?
|
||||
actor User? @relation(fields: [actorId], references: [id], onDelete: SetNull)
|
||||
changedAt DateTime @db.Timestamptz(3)
|
||||
|
||||
@@index([issueId, changedAt])
|
||||
@@index([field, changedAt])
|
||||
@@index([actorId])
|
||||
@@map("issue_change")
|
||||
}
|
||||
Reference in new issue
Block a user