Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bcanata/maieutic/llms.txt

Use this file to discover all available pages before exploring further.

Maieutic uses Prisma 6 with SQLite for local development. The schema is designed so that swapping to Postgres is a one-line change in prisma/schema.prisma — no application code needs to change. All migrations live in prisma/migrations/ and are applied automatically by the Prisma CLI.

Running migrations

Apply all pending migrations and generate the Prisma client with:
npx prisma migrate dev
The SQLite database file (dev.db) is gitignored. Prisma creates it automatically the first time you run npx prisma migrate dev.

Data models

Exercise

Represents a single programming problem authored by an instructor.
FieldTypeDescription
idString (slug)Unique identifier, used in URLs (e.g. vowels-demo)
titleStringHuman-readable exercise name shown to students
instructorPromptTextStringThe plain-text prompt the instructor wrote
specGateDimensionsJSON (SpecDimension[])Dimensions that a student’s specification must address before the code editor unlocks
expectedDivergencesJSON (ExpectedDivergence[])Patterns Opus expects to appear when student code diverges from the spec
studentLevelStringOne of week_1_2, week_3_6, or week_7_plus
unitStringOne of unit_1, unit_2, unit_3, or unit_4
publishedAtDateTime?null until the instructor publishes the exercise
opusGeneratedDimensionsJSONOpus first-pass dimensions, preserved for audit
opusGeneratedDivergencesJSONOpus first-pass divergences, preserved for audit
opusGeneratedStudentLevelStringOpus first-pass level classification, preserved for audit
The opusGenerated* fields store the raw Opus output before the instructor edits it. They are not shown to students.

ExerciseTranslation

A per-language cache of the student-visible text for an exercise.
FieldTypeDescription
exerciseIdStringForeign key to Exercise
langStringLanguage code: en or es
titleStringTranslated exercise title
instructorPromptTextStringTranslated prompt text
createdAtDateTimeWhen the translation was generated
Translations are populated on demand the first time a student in that language loads the exercise. Subsequent requests read from this cache. To invalidate a translation — for example after editing the exercise — delete the corresponding row. There is no automatic invalidation.

Session

Represents one student’s attempt at one exercise.
FieldTypeDescription
idString (cuid)Auto-generated unique identifier
studentIdStringFree-form student identifier (no authentication in the MVP)
exerciseIdStringForeign key to Exercise
currentPhaseInt1 (spec), 2 (coding), 3 (review), or 4 (closed)
phase1DataJSONAll state for the specification phase, including iteration history and help requests
phase2DataJSONAll state for the coding phase, including Opus exchanges, revisions, and final code
phase3DataJSON?All state for the review phase, including divergences and student responses
liveSummariesJSONAppend-only array of Opus-generated session summaries
startedAtDateTimeWhen the session was created
lastActiveAtDateTimeUpdated on every student action
completedAtDateTime?Set when the session reaches phase 4

SessionEvent

An append-only audit log. Every significant action in a session writes a row here.
FieldTypeDescription
idString (cuid)Auto-generated unique identifier
sessionIdStringForeign key to Session
kindStringEvent type (see table below)
payloadJSONEvent-specific data, validated against the kind’s schema
createdAtDateTimeWhen the event was recorded
Event kinds:
kindWhen it fires
session_startedA new session is created
phase_transitionThe session advances to the next phase
alignment_failureA student’s divergence response was classified as diverged (did not match Opus’s prediction)
help_requestThe student requests instructor help
help_resolvedAn instructor marks a help request resolved
revisionThe student submits a new version of their code in phase 2
summary_refreshOpus generates a new live summary for the session

Resetting the database

To start from a completely clean state, delete the database file and re-run migrations:
rm prisma/dev.db
npx prisma migrate dev
This drops all data and recreates the schema. See Loading demo data and fixtures to repopulate with demo sessions afterwards.

Switching to Postgres

In prisma/schema.prisma, change the datasource provider and URL:
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
Then update DATABASE_URL in your .env file to a Postgres connection string:
DATABASE_URL="postgresql://user:password@localhost:5432/maieutic"
Run npx prisma migrate dev to apply all migrations against the new database. No application code needs to change.

Build docs developers (and LLMs) love