BoardKitBackend
Prisma Adapter
PrismaBoardAdapter setup and Prisma schema reference
PrismaBoardAdapter implements BoardStorage using Prisma. It uses structural typing and never imports @prisma/client directly.
Setup
import { PrismaBoardAdapter } from '@hfu.digital/boardkit-nestjs';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const boardStorage = new PrismaBoardAdapter({
board: prisma.board,
page: prisma.page,
element: prisma.element,
boardMember: prisma.boardMember,
shareLink: prisma.shareLink,
});Configuration Interface
interface PrismaBoardAdapterConfig {
board: PrismaDelegate;
page: PrismaDelegate;
element: PrismaElementDelegate;
boardMember: PrismaBoardMemberDelegate;
shareLink: PrismaShareLinkDelegate;
}Each delegate matches the structural shape of Prisma model clients (e.g., prisma.board). This means you can use any ORM or database client that provides the same method signatures.
Prisma Schema
Here is a reference Prisma schema for the required models:
model Board {
id String @id @default(uuid())
name String
ownerId String
sessionType String @default("persistent")
isArchived Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
pages Page[]
members BoardMember[]
shareLinks ShareLink[]
}
model Page {
id String @id @default(uuid())
boardId String
name String
order Int
thumbnail String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
board Board @relation(fields: [boardId], references: [id], onDelete: Cascade)
elements Element[]
}
model Element {
id String @id @default(uuid())
pageId String
type String
data Json
zIndex Int
lockedBy String?
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
page Page @relation(fields: [pageId], references: [id], onDelete: Cascade)
}
model BoardMember {
id String @id @default(uuid())
boardId String
userId String
role String
joinedAt DateTime @default(now())
board Board @relation(fields: [boardId], references: [id], onDelete: Cascade)
@@unique([boardId, userId])
}
model ShareLink {
id String @id @default(uuid())
boardId String
token String @unique
permission String
expiresAt DateTime?
createdAt DateTime @default(now())
board Board @relation(fields: [boardId], references: [id], onDelete: Cascade)
}
model BoardEvent {
id String @id @default(uuid())
boardId String
pageId String?
type String
payload Json
userId String
sequence Int
timestamp DateTime @default(now())
@@index([boardId, sequence])
}
model BoardSnapshot {
id String @id @default(uuid())
boardId String
snapshotData Json
eventSequence Int
createdAt DateTime @default(now())
@@index([boardId])
}How It Works
- Board CRUD: Direct Prisma
create,findUnique,findMany,update,delete - Page ordering: Pages are sorted by
orderfield;reorderPagesupdates each page's order - Element upsert: Uses Prisma's
upsertfor each element (create if new, update if existing) - Element batch delete: Uses
deleteManywithid: { in: ids } - Share links: Token generated with
crypto.randomUUID(), expiration checked on resolve - Members: Uses
findFirstto check existence, thencreateorupdate