feat: EduEasy checkpoint - plan, scaffolding, pedagogia modules, components child+parent, API routes, Prisma schema, Docker infra, Better Auth
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
import { auth } from "@/lib/auth"
|
||||
import { toNextJsHandler } from "better-auth/next-js"
|
||||
|
||||
export const { POST, GET } = toNextJsHandler(auth)
|
||||
@@ -0,0 +1,49 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import { prisma } from "@/lib/db"
|
||||
import { randomUUID } from "crypto"
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const { deviceFingerprint, pairingCode: incomingCode } = await request.json()
|
||||
|
||||
if (incomingCode) {
|
||||
// Step 2: Parent's device confirms pairing
|
||||
const device = await prisma.device.findFirst({
|
||||
where: { deviceFingerprint: incomingCode },
|
||||
include: { child: true },
|
||||
})
|
||||
|
||||
if (!device) {
|
||||
return NextResponse.json({ error: "Código inválido" }, { status: 404 })
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
childId: device.childId,
|
||||
childName: device.child.name,
|
||||
})
|
||||
}
|
||||
|
||||
// Step 1: Child device requests pairing
|
||||
const existingDevice = await prisma.device.findFirst({
|
||||
where: { deviceFingerprint },
|
||||
})
|
||||
|
||||
if (existingDevice) {
|
||||
return NextResponse.json({
|
||||
paired: true,
|
||||
childId: existingDevice.childId,
|
||||
})
|
||||
}
|
||||
|
||||
const pairingCode = randomUUID().slice(0, 8)
|
||||
|
||||
return NextResponse.json({
|
||||
paired: false,
|
||||
pairingCode,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Pairing error:", error)
|
||||
return NextResponse.json({ error: "Internal error" }, { status: 500 })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
import { prisma } from "@/lib/db"
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json()
|
||||
const { childId, session, attempts } = body
|
||||
|
||||
if (!childId || !session) {
|
||||
return NextResponse.json({ error: "Missing required fields" }, { status: 400 })
|
||||
}
|
||||
|
||||
const sessionLog = await prisma.sessionLog.create({
|
||||
data: {
|
||||
childId,
|
||||
startedAt: new Date(session.startedAt),
|
||||
endedAt: session.endedAt ? new Date(session.endedAt) : undefined,
|
||||
durationSec: session.durationSec,
|
||||
skillsPracticed: session.skillsPracticed,
|
||||
skillAttempts: {
|
||||
create: (attempts || []).map((a: any) => ({
|
||||
skillCode: a.skillCode,
|
||||
promptLevel: a.promptLevel ?? 0,
|
||||
correct: a.correct,
|
||||
responseMs: a.responseMs,
|
||||
})),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return NextResponse.json({ success: true, sessionId: sessionLog.id })
|
||||
} catch (error) {
|
||||
console.error("Sync error:", error)
|
||||
return NextResponse.json({ error: "Internal error" }, { status: 500 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user