feat: Puente Mayúscula-Minúscula + TTS SpeechSynthesis + E2E fixes

This commit is contained in:
renato97
2026-07-21 15:31:46 -03:00
commit fa8e0c58ce
120 changed files with 16013 additions and 0 deletions
@@ -0,0 +1,180 @@
-- CreateTable
CREATE TABLE "Parent" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"name" TEXT,
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
"image" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"familyId" TEXT NOT NULL,
CONSTRAINT "Parent_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"email" TEXT,
"userId" TEXT,
"parentId" TEXT,
"token" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"ipAddress" TEXT,
"userAgent" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"accountId" TEXT NOT NULL,
"providerId" TEXT NOT NULL,
"parentId" TEXT NOT NULL,
"accessToken" TEXT,
"refreshToken" TEXT,
"idToken" TEXT,
"accessTokenExpiresAt" TIMESTAMP(3),
"scope" TEXT,
"password" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Verification" (
"id" TEXT NOT NULL,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Verification_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Family" (
"id" TEXT NOT NULL,
"name" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Family_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Child" (
"id" TEXT NOT NULL,
"name" TEXT,
"avatar" TEXT,
"birthdate" TIMESTAMP(3),
"profileNotes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"familyId" TEXT NOT NULL,
CONSTRAINT "Child_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Device" (
"id" TEXT NOT NULL,
"deviceFingerprint" TEXT NOT NULL,
"pairedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"lastSeen" TIMESTAMP(3) NOT NULL,
"role" TEXT NOT NULL DEFAULT 'child',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"childId" TEXT NOT NULL,
CONSTRAINT "Device_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "SessionLog" (
"id" TEXT NOT NULL,
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"endedAt" TIMESTAMP(3),
"durationSec" INTEGER,
"skillsPracticed" TEXT,
"childId" TEXT NOT NULL,
CONSTRAINT "SessionLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "SkillAttempt" (
"id" TEXT NOT NULL,
"skillCode" TEXT NOT NULL,
"promptLevel" INTEGER NOT NULL DEFAULT 0,
"correct" BOOLEAN NOT NULL,
"responseMs" INTEGER,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"sessionLogId" TEXT NOT NULL,
CONSTRAINT "SkillAttempt_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FsrsCard" (
"id" TEXT NOT NULL,
"skillCode" TEXT NOT NULL,
"dueAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"stability" DOUBLE PRECISION NOT NULL DEFAULT 0,
"difficulty" DOUBLE PRECISION NOT NULL DEFAULT 0,
"reps" INTEGER NOT NULL DEFAULT 0,
"lapses" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"childId" TEXT NOT NULL,
CONSTRAINT "FsrsCard_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Milestone" (
"id" TEXT NOT NULL,
"skillCode" TEXT NOT NULL,
"reachedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"childId" TEXT NOT NULL,
CONSTRAINT "Milestone_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Parent_email_key" ON "Parent"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Session_token_key" ON "Session"("token");
-- AddForeignKey
ALTER TABLE "Parent" ADD CONSTRAINT "Parent_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "Family"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Parent"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Parent"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Child" ADD CONSTRAINT "Child_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "Family"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Device" ADD CONSTRAINT "Device_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SessionLog" ADD CONSTRAINT "SessionLog_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SkillAttempt" ADD CONSTRAINT "SkillAttempt_sessionLogId_fkey" FOREIGN KEY ("sessionLogId") REFERENCES "SessionLog"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FsrsCard" ADD CONSTRAINT "FsrsCard_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Milestone" ADD CONSTRAINT "Milestone_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+3
View File
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
+180
View File
@@ -0,0 +1,180 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Parent {
id String @id @default(cuid())
email String @unique
name String?
emailVerified Boolean @default(false)
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
familyId String?
family Family? @relation(fields: [familyId], references: [id])
sessions Session[]
accounts Account[]
}
model Session {
id String @id @default(cuid())
email String?
userId String?
parentId String?
parent Parent? @relation(fields: [parentId], references: [id])
token String @unique
expiresAt DateTime
ipAddress String?
userAgent String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Account {
id String @id @default(cuid())
accountId String
providerId String
userId String
user Parent @relation(fields: [userId], references: [id])
accessToken String?
refreshToken String?
idToken String?
accessTokenExpiresAt DateTime?
scope String?
password String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Verification {
id String @id @default(cuid())
identifier String
value String
expiresAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Family {
id String @id @default(cuid())
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
parents Parent[]
children Child[]
}
model Child {
id String @id @default(cuid())
name String?
avatar String?
birthdate DateTime?
profileNotes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
familyId String
family Family @relation(fields: [familyId], references: [id])
devices Device[]
sessions SessionLog[]
fsrsCards FsrsCard[]
milestones Milestone[]
curriculumProgress CurriculumProgress[]
}
model Device {
id String @id @default(cuid())
deviceFingerprint String
pairedAt DateTime @default(now())
lastSeen DateTime @updatedAt
role String @default("child")
createdAt DateTime @default(now())
childId String
child Child @relation(fields: [childId], references: [id])
}
model SessionLog {
id String @id @default(cuid())
startedAt DateTime @default(now())
endedAt DateTime?
durationSec Int?
skillsPracticed String?
childId String
child Child @relation(fields: [childId], references: [id])
skillAttempts SkillAttempt[]
}
model SkillAttempt {
id String @id @default(cuid())
skillCode String
promptLevel Int @default(0)
correct Boolean
responseMs Int?
errorType String?
exerciseId String?
stage Int?
createdAt DateTime @default(now())
sessionLogId String
sessionLog SessionLog @relation(fields: [sessionLogId], references: [id])
}
model CurriculumProgress {
id String @id @default(cuid())
topic String
stage Int
unlockedAt DateTime @default(now())
completedAt DateTime?
childId String
child Child @relation(fields: [childId], references: [id])
@@unique([childId, topic, stage])
}
model FsrsCard {
id String @id @default(cuid())
skillCode String
dueAt DateTime @default(now())
stability Float @default(0)
difficulty Float @default(0)
reps Int @default(0)
lapses Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
childId String
child Child @relation(fields: [childId], references: [id])
}
model Milestone {
id String @id @default(cuid())
skillCode String
reachedAt DateTime @default(now())
childId String
child Child @relation(fields: [childId], references: [id])
@@unique([childId, skillCode])
}
model PendingPairing {
id String @id @default(cuid())
code String @unique
deviceFingerprint String?
childId String?
createdAt DateTime @default(now())
expiresAt DateTime
}