RoomKitBackend
Prisma Adapter
Use the PrismaRoomKitAdapter with your Prisma schema
Overview
PrismaRoomKitAdapter is a composite adapter that implements all 11 storage interfaces using a Prisma client. It provides a zero-configuration persistence layer so you can get started without writing custom storage classes.
import { PrismaRoomKitAdapter } from '@roomkit/nestjs';Usage
Pass your Prisma client to the adapter and register it with the module.
import { PrismaRoomKitAdapter } from '@roomkit/nestjs';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const adapter = new PrismaRoomKitAdapter(prisma);
RoomKitModule.register({
storage: adapter,
});The adapter handles all transaction management, optimistic concurrency, hierarchy cascading, and conflict checking internally.
Prisma Schema Reference
The following models must be present in your Prisma schema. The adapter expects these exact model names and field types.
LocationNode
model LocationNode {
id String @id @default(cuid())
type LocationNodeType
displayName String
path String @unique
parentId String?
parent LocationNode? @relation("LocationHierarchy", fields: [parentId], references: [id])
children LocationNode[] @relation("LocationHierarchy")
aliases String[]
rooms Room[]
blackouts BlackoutWindow[]
configs ConfigEntry[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Room
model Room {
id String @id @default(cuid())
locationNodeId String
locationNode LocationNode @relation(fields: [locationNodeId], references: [id])
seatedCapacity Int
examCapacity Int
standingCapacity Int
equipment RoomEquipment[]
accessibility RoomAccessibility[]
partitions RoomPartition[]
partitionParentId String?
partitionParent RoomPartition? @relation("PartitionChildren", fields: [partitionParentId], references: [id])
operatingHours OperatingHours[]
bookings Booking[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}RoomEquipment
model RoomEquipment {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
name String
quantity Int @default(1)
}RoomAccessibility
model RoomAccessibility {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
feature String
}RoomPartition
model RoomPartition {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
children Room[] @relation("PartitionChildren")
}OperatingHours
model OperatingHours {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
dayOfWeek Int
opensAt String
closesAt String
}Booking
model Booking {
id String @id @default(cuid())
roomId String
room Room @relation(fields: [roomId], references: [id])
requesterId String
onBehalfOfId String?
title String
purposeType String
startsAt DateTime
endsAt DateTime
status BookingStatus @default(requested)
priorityTierId String?
priorityTier PriorityTier? @relation(fields: [priorityTierId], references: [id])
recurrenceRuleId String?
recurrenceRule RecurrenceRule? @relation(fields: [recurrenceRuleId], references: [id])
idempotencyKey String? @unique
version Int @default(1)
cancellationReason String?
transitions BookingStateTransition[]
conflicts ConflictRecord[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}BookingStateTransition
model BookingStateTransition {
id String @id @default(cuid())
bookingId String
booking Booking @relation(fields: [bookingId], references: [id])
fromStatus BookingStatus
toStatus BookingStatus
triggeredBy String
createdAt DateTime @default(now())
}RecurrenceRule
model RecurrenceRule {
id String @id @default(cuid())
frequency RecurrenceFrequency
interval Int @default(1)
until DateTime?
count Int?
byDay String[]
exceptions DateTime[]
modifications Json[]
modType RecurrenceModType?
bookings Booking[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}BlackoutWindow
model BlackoutWindow {
id String @id @default(cuid())
locationNodeId String
locationNode LocationNode @relation(fields: [locationNodeId], references: [id])
scope BlackoutScope
title String
reason String?
startsAt DateTime
endsAt DateTime
isRecurring Boolean @default(false)
recurrenceRuleId String?
createdAt DateTime @default(now())
}ConflictRecord
model ConflictRecord {
id String @id @default(cuid())
bookingId String
booking Booking @relation(fields: [bookingId], references: [id])
conflictsWith String
roomId String
timeRange Json
resolutionType ConflictResolutionType?
resolvedAt DateTime?
createdAt DateTime @default(now())
}ConfigEntry
model ConfigEntry {
id String @id @default(cuid())
key String
value Json
locationNodeId String?
locationNode LocationNode? @relation(fields: [locationNodeId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([key, locationNodeId])
}PriorityTier
model PriorityTier {
id String @id @default(cuid())
name String @unique
weight Int
bookings Booking[]
}ExamSession
model ExamSession {
id String @id @default(cuid())
cohortId String
roomId String
layoutType ExamLayoutType
seatingPlan Json?
startsAt DateTime
endsAt DateTime
bookingId String?
invigilators String[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}BulkOperation
model BulkOperation {
id String @id @default(cuid())
type BulkOperationType
status BulkOperationStatus @default(pending)
totalItems Int @default(0)
processedItems Int @default(0)
conflictsDetected Int @default(0)
resultSummary Json?
triggeredBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Enums
enum LocationNodeType {
institution
campus
building
floor
room
}
enum BookingStatus {
requested
confirmed
in_progress
completed
cancelled
}
enum RecurrenceFrequency {
daily
weekly
biweekly
monthly
}
enum RecurrenceModType {
single
this_and_future
all
}
enum BlackoutScope {
room
floor
building
campus
institution
}
enum ExamLayoutType {
individual_desks
grouped_tables
computer_lab
custom
}
enum ConflictResolutionType {
auto_cancelled
priority_override
manual_resolution
}
enum BulkOperationType {
semester_import
date_shift
batch_cancel
}
enum BulkOperationStatus {
pending
processing
completed
failed
}