@allbluecn/database 0.4.12 → 0.4.13

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 (30) hide show
  1. package/generated/browser.ts +15 -0
  2. package/generated/client.ts +15 -0
  3. package/generated/internal/class.ts +34 -4
  4. package/generated/internal/prismaNamespace.ts +274 -3
  5. package/generated/internal/prismaNamespaceBrowser.ts +48 -2
  6. package/generated/models/Notification.ts +1485 -0
  7. package/generated/models/NotificationPreference.ts +1289 -0
  8. package/generated/models/TeamInvitation.ts +257 -22
  9. package/generated/models/TeamJoinRequest.ts +1798 -0
  10. package/generated/models/User.ts +3505 -1125
  11. package/generated/models.ts +3 -0
  12. package/generated-sqlite/browser.ts +15 -0
  13. package/generated-sqlite/client.ts +15 -0
  14. package/generated-sqlite/internal/class.ts +34 -4
  15. package/generated-sqlite/internal/prismaNamespace.ts +274 -3
  16. package/generated-sqlite/internal/prismaNamespaceBrowser.ts +48 -2
  17. package/generated-sqlite/models/Notification.ts +1482 -0
  18. package/generated-sqlite/models/NotificationPreference.ts +1287 -0
  19. package/generated-sqlite/models/TeamInvitation.ts +257 -22
  20. package/generated-sqlite/models/TeamJoinRequest.ts +1793 -0
  21. package/generated-sqlite/models/User.ts +2578 -662
  22. package/generated-sqlite/models.ts +3 -0
  23. package/migrations/20260826162419_add_applicant_email/migration.sql +2 -0
  24. package/migrations/20260826170000_team_invitation_email_nullable_message/migration.sql +6 -0
  25. package/migrations/20260826180000_backfill_invitation_accepted_by/migration.sql +8 -0
  26. package/migrations/20260827044250_add_team_join_request/migration.sql +29 -0
  27. package/migrations/20260827102354_add_notifications/migration.sql +37 -0
  28. package/package.json +2 -2
  29. package/schema.prisma +67 -11
  30. package/schema.sqlite.prisma +66 -11
@@ -15,6 +15,7 @@ export type * from './models/ProjectMember'
15
15
  export type * from './models/Workspace'
16
16
  export type * from './models/TeamMembership'
17
17
  export type * from './models/TeamInvitation'
18
+ export type * from './models/TeamJoinRequest'
18
19
  export type * from './models/ProjectActivity'
19
20
  export type * from './models/ChatThread'
20
21
  export type * from './models/ChatMessage'
@@ -85,4 +86,6 @@ export type * from './models/ComplianceExport'
85
86
  export type * from './models/UserAgent'
86
87
  export type * from './models/UserSkill'
87
88
  export type * from './models/DeveloperLog'
89
+ export type * from './models/Notification'
90
+ export type * from './models/NotificationPreference'
88
91
  export type * from './commonInputTypes'
@@ -0,0 +1,2 @@
1
+ -- AlterTable
2
+ ALTER TABLE "team_invitations" ADD COLUMN IF NOT EXISTS "applicantEmail" TEXT;
@@ -0,0 +1,6 @@
1
+ -- AlterTable
2
+ ALTER TABLE "team_invitations" ALTER COLUMN "email" DROP NOT NULL;
3
+ ALTER TABLE "team_invitations" ADD COLUMN "message" TEXT;
4
+
5
+ -- 迁移现有 link 渠道邀请的 email='' 占位为 NULL,释放唯一约束冲突(允许多条 link 记录共存)
6
+ UPDATE "team_invitations" SET "email" = NULL WHERE "email" = '';
@@ -0,0 +1,8 @@
1
+ -- 回填存量 pending_approval 邀请的 acceptedBy(此前 accept 只写 applicantEmail 未写 acceptedBy)
2
+ UPDATE "team_invitations" ti
3
+ SET "acceptedBy" = u.id
4
+ FROM "users" u
5
+ WHERE ti.status = 'pending_approval'
6
+ AND ti."acceptedBy" IS NULL
7
+ AND ti."applicantEmail" IS NOT NULL
8
+ AND LOWER(u.email) = LOWER(ti."applicantEmail");
@@ -0,0 +1,29 @@
1
+ -- CreateTable
2
+ CREATE TABLE "team_join_requests" (
3
+ "id" TEXT NOT NULL,
4
+ "invitationId" TEXT NOT NULL,
5
+ "ownerId" TEXT NOT NULL,
6
+ "userId" TEXT,
7
+ "email" TEXT NOT NULL,
8
+ "status" TEXT NOT NULL DEFAULT 'pending',
9
+ "seatType" TEXT NOT NULL DEFAULT 'member',
10
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
+ "processedAt" TIMESTAMP(3),
12
+
13
+ CONSTRAINT "team_join_requests_pkey" PRIMARY KEY ("id")
14
+ );
15
+
16
+ -- CreateIndex
17
+ CREATE INDEX "team_join_requests_ownerId_status_idx" ON "team_join_requests"("ownerId", "status");
18
+
19
+ -- CreateIndex
20
+ CREATE UNIQUE INDEX "team_join_requests_invitationId_email_key" ON "team_join_requests"("invitationId", "email");
21
+
22
+ -- AddForeignKey
23
+ ALTER TABLE "team_join_requests" ADD CONSTRAINT "team_join_requests_invitationId_fkey" FOREIGN KEY ("invitationId") REFERENCES "team_invitations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
24
+
25
+ -- AddForeignKey
26
+ ALTER TABLE "team_join_requests" ADD CONSTRAINT "team_join_requests_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
27
+
28
+ -- AddForeignKey
29
+ ALTER TABLE "team_join_requests" ADD CONSTRAINT "team_join_requests_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,37 @@
1
+ -- CreateTable
2
+ CREATE TABLE "notifications" (
3
+ "id" TEXT NOT NULL,
4
+ "userId" TEXT NOT NULL,
5
+ "category" TEXT NOT NULL,
6
+ "type" TEXT NOT NULL,
7
+ "title" TEXT NOT NULL,
8
+ "body" TEXT,
9
+ "link" TEXT,
10
+ "readAt" TIMESTAMP(3),
11
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
12
+
13
+ CONSTRAINT "notifications_pkey" PRIMARY KEY ("id")
14
+ );
15
+
16
+ -- CreateTable
17
+ CREATE TABLE "notification_preferences" (
18
+ "userId" TEXT NOT NULL,
19
+ "categories" JSONB NOT NULL,
20
+ "dndEnabled" BOOLEAN NOT NULL DEFAULT false,
21
+ "dndStart" TEXT NOT NULL DEFAULT '22:00',
22
+ "dndEnd" TEXT NOT NULL DEFAULT '08:00',
23
+
24
+ CONSTRAINT "notification_preferences_pkey" PRIMARY KEY ("userId")
25
+ );
26
+
27
+ -- CreateIndex
28
+ CREATE INDEX "notifications_userId_createdAt_idx" ON "notifications"("userId", "createdAt" DESC);
29
+
30
+ -- CreateIndex
31
+ CREATE INDEX "notifications_userId_readAt_idx" ON "notifications"("userId", "readAt");
32
+
33
+ -- AddForeignKey
34
+ ALTER TABLE "notifications" ADD CONSTRAINT "notifications_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
35
+
36
+ -- AddForeignKey
37
+ ALTER TABLE "notification_preferences" ADD CONSTRAINT "notification_preferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allbluecn/database",
3
- "version": "0.4.12",
3
+ "version": "0.4.13",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -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/shared": "0.4.12"
18
+ "@allbluecn/shared": "0.4.13"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/better-sqlite3": "^7.6.13",
package/schema.prisma CHANGED
@@ -100,9 +100,13 @@ model User {
100
100
  workspaceMemberships TeamMembership[] @relation("teamOwner")
101
101
  teamJoined TeamMembership? @relation("teamMember")
102
102
  sentInvitations TeamInvitation[] @relation("invitationOwner")
103
+ ownedJoinRequests TeamJoinRequest[] @relation("joinRequestOwner")
104
+ applicantJoinRequests TeamJoinRequest[] @relation("joinRequestApplicant")
103
105
  aiUsageLogs AiUsageLog[]
104
106
  agents UserAgent[]
105
107
  skills UserSkill[]
108
+ notifications Notification[]
109
+ notificationPreference NotificationPreference?
106
110
 
107
111
  issuedLicenses LicenseKey[] @relation("LicenseIssuer")
108
112
  ssoMappings SsoMapping[]
@@ -212,23 +216,45 @@ model TeamMembership {
212
216
 
213
217
  // 团队邀请
214
218
  model TeamInvitation {
215
- id String @id @default(cuid())
216
- ownerId String
217
- owner User @relation("invitationOwner", fields: [ownerId], references: [id], onDelete: Cascade)
218
- email String
219
- seatType String @default("member")
220
- token String @unique
221
- channel String @default("email")
222
- status String @default("pending")
223
- expiresAt DateTime
224
- createdAt DateTime @default(now())
225
- acceptedBy String?
219
+ id String @id @default(cuid())
220
+ ownerId String
221
+ owner User @relation("invitationOwner", fields: [ownerId], references: [id], onDelete: Cascade)
222
+ email String?
223
+ seatType String @default("member")
224
+ token String @unique
225
+ channel String @default("email")
226
+ status String @default("pending")
227
+ expiresAt DateTime
228
+ createdAt DateTime @default(now())
229
+ acceptedBy String?
230
+ applicantEmail String?
231
+ message String?
232
+ joinRequests TeamJoinRequest[]
226
233
  @@unique([ownerId, email])
227
234
  @@index([ownerId])
228
235
  @@index([email])
229
236
  @@map("team_invitations")
230
237
  }
231
238
 
239
+ // 用户加入团队申请(链接渠道,与 TeamInvitation 分离:一条链接可承载多个申请)
240
+ model TeamJoinRequest {
241
+ id String @id @default(cuid())
242
+ invitationId String
243
+ invitation TeamInvitation @relation(fields: [invitationId], references: [id], onDelete: Cascade)
244
+ ownerId String
245
+ owner User @relation("joinRequestOwner", fields: [ownerId], references: [id], onDelete: Cascade)
246
+ userId String?
247
+ applicant User? @relation("joinRequestApplicant", fields: [userId], references: [id], onDelete: SetNull)
248
+ email String
249
+ status String @default("pending")
250
+ seatType String @default("member")
251
+ createdAt DateTime @default(now())
252
+ processedAt DateTime?
253
+ @@unique([invitationId, email])
254
+ @@index([ownerId, status])
255
+ @@map("team_join_requests")
256
+ }
257
+
232
258
  // 项目活动记录
233
259
  model ProjectActivity {
234
260
  id String @id @default(cuid())
@@ -2029,3 +2055,33 @@ model DeveloperLog {
2029
2055
  @@index([year, date])
2030
2056
  @@map("developer_logs")
2031
2057
  }
2058
+
2059
+ // 通知(团队邀请、协作请求、系统消息等)
2060
+ model Notification {
2061
+ id String @id @default(cuid())
2062
+ userId String
2063
+ category String // team | collaboration | system | billing | security
2064
+ type String // 细分事件类型:team.invite_request、billing.payment_failed 等
2065
+ title String
2066
+ body String?
2067
+ link String?
2068
+ readAt DateTime?
2069
+ createdAt DateTime @default(now())
2070
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
2071
+
2072
+ @@index([userId, createdAt(sort: Desc)])
2073
+ @@index([userId, readAt])
2074
+ @@map("notifications")
2075
+ }
2076
+
2077
+ // 通知偏好(免打扰时段、分类开关)
2078
+ model NotificationPreference {
2079
+ userId String @id
2080
+ categories Json
2081
+ dndEnabled Boolean @default(false)
2082
+ dndStart String @default("22:00")
2083
+ dndEnd String @default("08:00")
2084
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
2085
+
2086
+ @@map("notification_preferences")
2087
+ }
@@ -92,9 +92,13 @@ model User {
92
92
  workspaceMemberships TeamMembership[] @relation("teamOwner")
93
93
  teamJoined TeamMembership? @relation("teamMember")
94
94
  sentInvitations TeamInvitation[] @relation("invitationOwner")
95
+ ownedJoinRequests TeamJoinRequest[] @relation("joinRequestOwner")
96
+ applicantJoinRequests TeamJoinRequest[] @relation("joinRequestApplicant")
95
97
  aiUsageLogs AiUsageLog[]
96
98
  agents UserAgent[]
97
99
  skills UserSkill[]
100
+ notifications Notification[]
101
+ notificationPreference NotificationPreference?
98
102
  subscription Subscription?
99
103
 
100
104
  @@map("users")
@@ -173,23 +177,44 @@ model TeamMembership {
173
177
 
174
178
  // 团队邀请
175
179
  model TeamInvitation {
176
- id String @id @default(cuid())
177
- ownerId String
178
- owner User @relation("invitationOwner", fields: [ownerId], references: [id], onDelete: Cascade)
179
- email String
180
- seatType String @default("member")
181
- token String @unique
182
- channel String @default("email")
183
- status String @default("pending")
184
- expiresAt DateTime
185
- createdAt DateTime @default(now())
186
- acceptedBy String?
180
+ id String @id @default(cuid())
181
+ ownerId String
182
+ owner User @relation("invitationOwner", fields: [ownerId], references: [id], onDelete: Cascade)
183
+ email String?
184
+ seatType String @default("member")
185
+ token String @unique
186
+ channel String @default("email")
187
+ status String @default("pending")
188
+ expiresAt DateTime
189
+ createdAt DateTime @default(now())
190
+ acceptedBy String?
191
+ applicantEmail String?
192
+ message String?
193
+ joinRequests TeamJoinRequest[]
187
194
  @@unique([ownerId, email])
188
195
  @@index([ownerId])
189
196
  @@index([email])
190
197
  @@map("team_invitations")
191
198
  }
192
199
 
200
+ model TeamJoinRequest {
201
+ id String @id @default(cuid())
202
+ invitationId String
203
+ invitation TeamInvitation @relation(fields: [invitationId], references: [id], onDelete: Cascade)
204
+ ownerId String
205
+ owner User @relation("joinRequestOwner", fields: [ownerId], references: [id], onDelete: Cascade)
206
+ userId String?
207
+ applicant User? @relation("joinRequestApplicant", fields: [userId], references: [id], onDelete: SetNull)
208
+ email String
209
+ status String @default("pending")
210
+ seatType String @default("member")
211
+ createdAt DateTime @default(now())
212
+ processedAt DateTime?
213
+ @@unique([invitationId, email])
214
+ @@index([ownerId, status])
215
+ @@map("team_join_requests")
216
+ }
217
+
193
218
  // 项目活动记录
194
219
  model ProjectActivity {
195
220
  id String @id @default(cuid())
@@ -1599,3 +1624,33 @@ model DeveloperLog {
1599
1624
  @@index([year, date])
1600
1625
  @@map("developer_logs")
1601
1626
  }
1627
+
1628
+ // 通知(团队邀请、协作请求、系统消息等)
1629
+ model Notification {
1630
+ id String @id @default(cuid())
1631
+ userId String
1632
+ category String // team | collaboration | system | billing | security
1633
+ type String // 细分事件类型:team.invite_request、billing.payment_failed 等
1634
+ title String
1635
+ body String?
1636
+ link String?
1637
+ readAt DateTime?
1638
+ createdAt DateTime @default(now())
1639
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1640
+
1641
+ @@index([userId, createdAt(sort: Desc)])
1642
+ @@index([userId, readAt])
1643
+ @@map("notifications")
1644
+ }
1645
+
1646
+ // 通知偏好(免打扰时段、分类开关)
1647
+ model NotificationPreference {
1648
+ userId String @id
1649
+ categories Json
1650
+ dndEnabled Boolean @default(false)
1651
+ dndStart String @default("22:00")
1652
+ dndEnd String @default("08:00")
1653
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1654
+
1655
+ @@map("notification_preferences")
1656
+ }