feat(collab): restore cross-account sharing and reliable realtime sync

This commit is contained in:
2026-02-13 19:02:03 +01:00
parent 12da89b815
commit 75cbe97bc0
18 changed files with 1242 additions and 167 deletions
@@ -0,0 +1,42 @@
-- CreateTable
CREATE TABLE "DrawingShareLink" (
"id" TEXT NOT NULL PRIMARY KEY,
"drawingId" TEXT NOT NULL,
"role" TEXT NOT NULL,
"token" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "DrawingShareLink_drawingId_fkey" FOREIGN KEY ("drawingId") REFERENCES "Drawing" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "DrawingShareGrant" (
"id" TEXT NOT NULL PRIMARY KEY,
"drawingId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"shareLinkId" TEXT NOT NULL,
"role" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "DrawingShareGrant_drawingId_fkey" FOREIGN KEY ("drawingId") REFERENCES "Drawing" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "DrawingShareGrant_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "DrawingShareGrant_shareLinkId_fkey" FOREIGN KEY ("shareLinkId") REFERENCES "DrawingShareLink" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "DrawingShareLink_token_key" ON "DrawingShareLink"("token");
-- CreateIndex
CREATE INDEX "DrawingShareLink_drawingId_idx" ON "DrawingShareLink"("drawingId");
-- CreateIndex
CREATE UNIQUE INDEX "DrawingShareLink_drawingId_role_key" ON "DrawingShareLink"("drawingId", "role");
-- CreateIndex
CREATE INDEX "DrawingShareGrant_drawingId_userId_idx" ON "DrawingShareGrant"("drawingId", "userId");
-- CreateIndex
CREATE INDEX "DrawingShareGrant_userId_createdAt_idx" ON "DrawingShareGrant"("userId", "createdAt");
-- CreateIndex
CREATE UNIQUE INDEX "DrawingShareGrant_drawingId_userId_shareLinkId_key" ON "DrawingShareGrant"("drawingId", "userId", "shareLinkId");
+35
View File
@@ -27,6 +27,7 @@ model User {
passwordResetTokens PasswordResetToken[]
refreshTokens RefreshToken[]
auditLogs AuditLog[]
drawingShareGrants DrawingShareGrant[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
@@ -67,6 +68,8 @@ model Drawing {
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
collectionId String?
collection Collection? @relation(fields: [collectionId], references: [id])
shareLinks DrawingShareLink[]
shareGrants DrawingShareGrant[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -74,6 +77,38 @@ model Drawing {
@@index([userId, collectionId, updatedAt])
}
model DrawingShareLink {
id String @id @default(uuid())
drawingId String
drawing Drawing @relation(fields: [drawingId], references: [id], onDelete: Cascade)
role String
token String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
grants DrawingShareGrant[]
@@unique([drawingId, role])
@@index([drawingId])
}
model DrawingShareGrant {
id String @id @default(uuid())
drawingId String
drawing Drawing @relation(fields: [drawingId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
shareLinkId String
shareLink DrawingShareLink @relation(fields: [shareLinkId], references: [id], onDelete: Cascade)
role String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([drawingId, userId, shareLinkId])
@@index([drawingId, userId])
@@index([userId, createdAt])
}
model Library {
id String @id // User-specific library ID (e.g., "user_<userId>")
items String @default("[]") // Stored as JSON string array of library items