My App
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
}

On this page