LoopKitBackend
Prisma Adapter
Use Prisma as the storage backend for LoopKit
Setup
import { PrismaLoopKitAdapter } from '@loopkit/nestjs';
const adapter = new PrismaLoopKitAdapter(prismaClient);The adapter expects a Prisma client with the following models:
| Prisma Model | Entity |
|---|---|
loopKitCard | Cards |
loopKitNote | Notes |
loopKitNoteType | Note Types |
loopKitDeck | Decks |
loopKitDeckPreset | Deck Presets |
loopKitReviewLog | Review Logs |
Required Prisma Schema
Add these models to your schema.prisma:
model LoopKitCard {
id String @id @default(uuid())
noteId String
templateId String
deckId String
state String @default("new")
easeFactor Float @default(2.5)
interval Float @default(0)
dueDate DateTime @default(now())
currentStep Int @default(0)
lapseCount Int @default(0)
reviewCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
note LoopKitNote @relation(fields: [noteId], references: [id], onDelete: Cascade)
deck LoopKitDeck @relation(fields: [deckId], references: [id])
@@unique([noteId, templateId])
@@index([deckId, state])
@@index([deckId, dueDate])
}
model LoopKitNote {
id String @id @default(uuid())
noteTypeId String
fields Json
tags Json @default("[]")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
noteType LoopKitNoteType @relation(fields: [noteTypeId], references: [id])
cards LoopKitCard[]
}
model LoopKitNoteType {
id String @id @default(uuid())
name String @unique
fields Json
templates Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notes LoopKitNote[]
}
model LoopKitDeck {
id String @id @default(uuid())
name String
description String?
parentDeckId String?
presetId String?
configOverrides Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
parent LoopKitDeck? @relation("DeckHierarchy", fields: [parentDeckId], references: [id])
children LoopKitDeck[] @relation("DeckHierarchy")
preset LoopKitDeckPreset? @relation(fields: [presetId], references: [id])
cards LoopKitCard[]
logs LoopKitReviewLog[]
}
model LoopKitDeckPreset {
id String @id @default(uuid())
name String
config Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
decks LoopKitDeck[]
}
model LoopKitReviewLog {
id String @id @default(uuid())
cardId String
deckId String
grade String
prevState Json
newState Json
reviewedAt DateTime @default(now())
timeTakenMs Int
deck LoopKitDeck @relation(fields: [deckId], references: [id])
@@index([cardId])
@@index([deckId, reviewedAt])
}Then run prisma migrate dev to apply the schema.
Error Mapping
The adapter maps Prisma errors to LoopKit errors:
| Prisma Code | LoopKit Error | Description |
|---|---|---|
P2002 | DuplicateEntityError | Unique constraint violation |
P2025 | EntityNotFoundError | Record not found |
P2034 | ConcurrencyConflictError | Transaction conflict |
| Connection errors | StorageConnectionError | Database unreachable |
JSON Fields
The adapter automatically serializes/deserializes JSON fields:
fields,tagson Notesfields,templateson NoteTypesconfigOverrideson Decksconfigon PresetsprevState,newStateon ReviewLogs
Transaction Support
await adapter.transaction(async (txStorage) => {
const note = await txStorage.createNote({ ... });
await txStorage.createCard({ noteId: note.id, ... });
});The adapter creates a new PrismaLoopKitAdapter wrapping the Prisma transaction client.