My App
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 ModelEntity
loopKitCardCards
loopKitNoteNotes
loopKitNoteTypeNote Types
loopKitDeckDecks
loopKitDeckPresetDeck Presets
loopKitReviewLogReview 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

    @@map("loopkit_cards")
}

model LoopKitNote {
    id         String   @id @default(uuid())
    noteTypeId String
    fields     String   // JSON
    tags       String   // JSON
    createdAt  DateTime @default(now())
    updatedAt  DateTime @updatedAt

    @@map("loopkit_notes")
}

model LoopKitNoteType {
    id        String   @id @default(uuid())
    name      String
    fields    String   // JSON
    templates String   // JSON
    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt

    @@map("loopkit_note_types")
}

model LoopKitDeck {
    id              String   @id @default(uuid())
    name            String
    description     String?
    parentDeckId    String?
    presetId        String?
    configOverrides String?  // JSON
    createdAt       DateTime @default(now())
    updatedAt       DateTime @updatedAt

    @@map("loopkit_decks")
}

model LoopKitDeckPreset {
    id        String   @id @default(uuid())
    name      String
    config    String   // JSON
    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt

    @@map("loopkit_deck_presets")
}

model LoopKitReviewLog {
    id          String   @id @default(uuid())
    cardId      String
    deckId      String
    grade       String
    prevState   String   // JSON
    newState    String   // JSON
    reviewedAt  DateTime @default(now())
    timeTakenMs Int
    createdAt   DateTime @default(now())

    @@map("loopkit_review_logs")
}

Error Mapping

The adapter maps Prisma errors to LoopKit errors:

Prisma CodeLoopKit ErrorDescription
P2002DuplicateEntityErrorUnique constraint violation
P2025EntityNotFoundErrorRecord not found
P2034ConcurrencyConflictErrorTransaction conflict
Connection errorsStorageConnectionErrorDatabase unreachable

JSON Fields

The adapter automatically serializes/deserializes JSON fields:

  • fields, tags on Notes
  • fields, templates on NoteTypes
  • configOverrides on Decks
  • config on Presets
  • prevState, newState on 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.

On this page