Initial working commit
Some checks failed
Automated Container Build / build-and-push (push) Failing after 7s
Some checks failed
Automated Container Build / build-and-push (push) Failing after 7s
This commit is contained in:
parent
666ceb7325
commit
b7ce314f01
105 changed files with 35510 additions and 11 deletions
130
prisma/migrations/20260628011409_init/migration.sql
Normal file
130
prisma/migrations/20260628011409_init/migration.sql
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE "Class" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"slug" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Deck" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"classId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "Deck_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Flashcard" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"deckId" TEXT NOT NULL,
|
||||
"front" TEXT NOT NULL,
|
||||
"back" TEXT NOT NULL,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
CONSTRAINT "Flashcard_deckId_fkey" FOREIGN KEY ("deckId") REFERENCES "Deck" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "QuizSet" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"classId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "QuizSet_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Question" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"quizSetId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"prompt" TEXT NOT NULL,
|
||||
"rationale" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
CONSTRAINT "Question_quizSetId_fkey" FOREIGN KEY ("quizSetId") REFERENCES "QuizSet" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AnswerOption" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"questionId" TEXT NOT NULL,
|
||||
"text" TEXT NOT NULL,
|
||||
"isCorrect" BOOLEAN NOT NULL DEFAULT false,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
CONSTRAINT "AnswerOption_questionId_fkey" FOREIGN KEY ("questionId") REFERENCES "Question" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "StudyProgress" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"contentType" TEXT NOT NULL,
|
||||
"deckId" TEXT,
|
||||
"quizSetId" TEXT,
|
||||
"mode" TEXT NOT NULL,
|
||||
"currentIndex" INTEGER NOT NULL DEFAULT 0,
|
||||
"orderJson" TEXT NOT NULL,
|
||||
"answersJson" TEXT,
|
||||
"cardResultsJson" TEXT,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "StudyProgress_deckId_fkey" FOREIGN KEY ("deckId") REFERENCES "Deck" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "StudyProgress_quizSetId_fkey" FOREIGN KEY ("quizSetId") REFERENCES "QuizSet" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "QuizAttempt" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"quizSetId" TEXT NOT NULL,
|
||||
"score" REAL NOT NULL,
|
||||
"maxScore" INTEGER NOT NULL,
|
||||
"answersJson" TEXT NOT NULL,
|
||||
"isPartialRetake" BOOLEAN NOT NULL DEFAULT false,
|
||||
"completedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "QuizAttempt_quizSetId_fkey" FOREIGN KEY ("quizSetId") REFERENCES "QuizSet" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ShareLink" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"targetType" TEXT NOT NULL,
|
||||
"deckId" TEXT,
|
||||
"quizSetId" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "ShareLink_deckId_fkey" FOREIGN KEY ("deckId") REFERENCES "Deck" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "ShareLink_quizSetId_fkey" FOREIGN KEY ("quizSetId") REFERENCES "QuizSet" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuthSecurity" (
|
||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT DEFAULT 1,
|
||||
"failedAttempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"lockedUntil" DATETIME,
|
||||
"lastAttemptAt" DATETIME
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Setting" (
|
||||
"key" TEXT NOT NULL PRIMARY KEY,
|
||||
"value" TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Class_slug_key" ON "Class"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StudyProgress_deckId_mode_key" ON "StudyProgress"("deckId", "mode");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StudyProgress_quizSetId_mode_key" ON "StudyProgress"("quizSetId", "mode");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ShareLink_deckId_key" ON "ShareLink"("deckId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ShareLink_quizSetId_key" ON "ShareLink"("quizSetId");
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "sqlite"
|
||||
135
prisma/schema.prisma
Normal file
135
prisma/schema.prisma
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
datasource db {
|
||||
provider = "sqlite"
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client"
|
||||
output = "../src/generated/prisma"
|
||||
}
|
||||
|
||||
model Class {
|
||||
id String @id @default(uuid())
|
||||
slug String @unique
|
||||
name String
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
decks Deck[]
|
||||
quizSets QuizSet[]
|
||||
}
|
||||
|
||||
model Deck {
|
||||
id String @id @default(uuid())
|
||||
classId String
|
||||
name String
|
||||
description String?
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||||
cards Flashcard[]
|
||||
shareLink ShareLink?
|
||||
progress StudyProgress[]
|
||||
}
|
||||
|
||||
model Flashcard {
|
||||
id String @id @default(uuid())
|
||||
deckId String
|
||||
front String
|
||||
back String
|
||||
sortOrder Int @default(0)
|
||||
|
||||
deck Deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model QuizSet {
|
||||
id String @id @default(uuid())
|
||||
classId String
|
||||
name String
|
||||
description String?
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||||
questions Question[]
|
||||
attempts QuizAttempt[]
|
||||
shareLink ShareLink?
|
||||
progress StudyProgress[]
|
||||
}
|
||||
|
||||
model Question {
|
||||
id String @id @default(uuid())
|
||||
quizSetId String
|
||||
type String // "MULTIPLE_CHOICE" | "SATA"
|
||||
prompt String
|
||||
rationale String
|
||||
category String
|
||||
sortOrder Int @default(0)
|
||||
|
||||
quizSet QuizSet @relation(fields: [quizSetId], references: [id], onDelete: Cascade)
|
||||
options AnswerOption[]
|
||||
}
|
||||
|
||||
model AnswerOption {
|
||||
id String @id @default(uuid())
|
||||
questionId String
|
||||
text String
|
||||
isCorrect Boolean @default(false)
|
||||
sortOrder Int @default(0)
|
||||
|
||||
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model StudyProgress {
|
||||
id String @id @default(uuid())
|
||||
contentType String // "DECK" | "QUIZ"
|
||||
deckId String?
|
||||
quizSetId String?
|
||||
mode String // "SEQUENTIAL" | "SHUFFLED"
|
||||
currentIndex Int @default(0)
|
||||
orderJson String // JSON array of card/question ids
|
||||
answersJson String? // in-progress quiz answers
|
||||
cardResultsJson String? // per-card grades for decks
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
deck Deck? @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
||||
quizSet QuizSet? @relation(fields: [quizSetId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([deckId, mode])
|
||||
@@unique([quizSetId, mode])
|
||||
}
|
||||
|
||||
model QuizAttempt {
|
||||
id String @id @default(uuid())
|
||||
quizSetId String
|
||||
score Float
|
||||
maxScore Int
|
||||
answersJson String
|
||||
isPartialRetake Boolean @default(false)
|
||||
completedAt DateTime @default(now())
|
||||
|
||||
quizSet QuizSet @relation(fields: [quizSetId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model ShareLink {
|
||||
id String @id @default(uuid())
|
||||
targetType String // "DECK" | "QUIZ"
|
||||
deckId String? @unique
|
||||
quizSetId String? @unique
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
deck Deck? @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
||||
quizSet QuizSet? @relation(fields: [quizSetId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model AuthSecurity {
|
||||
id Int @id @default(1)
|
||||
failedAttempts Int @default(0)
|
||||
lockedUntil DateTime?
|
||||
lastAttemptAt DateTime?
|
||||
}
|
||||
|
||||
model Setting {
|
||||
key String @id
|
||||
value String
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue