import { promises as fs } from 'fs'; import path from 'path'; import type { NextRequest } from 'next/server'; import type { Scene, Stage } from '@/lib/types/stage'; export const CLASSROOMS_DIR = path.join(process.cwd(), 'data', 'classrooms'); export const CLASSROOM_JOBS_DIR = path.join(process.cwd(), 'data', 'classroom-jobs'); async function ensureDir(dir: string) { await fs.mkdir(dir, { recursive: true }); } export async function ensureClassroomsDir() { await ensureDir(CLASSROOMS_DIR); } export async function ensureClassroomJobsDir() { await ensureDir(CLASSROOM_JOBS_DIR); } export async function writeJsonFileAtomic(filePath: string, data: unknown) { const dir = path.dirname(filePath); await ensureDir(dir); const tempFilePath = `${filePath}.${process.pid}.${Date.now()}.tmp`; const content = JSON.stringify(data, null, 2); await fs.writeFile(tempFilePath, content, 'utf-8'); await fs.rename(tempFilePath, filePath); } export function buildRequestOrigin(req: NextRequest): string { return req.headers.get('x-forwarded-host') ? `${req.headers.get('x-forwarded-proto') || 'http'}://${req.headers.get('x-forwarded-host')}` : req.nextUrl.origin; } export interface PersistedClassroomData { id: string; stage: Stage; scenes: Scene[]; createdAt: string; } export function isValidClassroomId(id: string): boolean { return /^[a-zA-Z0-9_-]+$/.test(id); } export async function readClassroom(id: string): Promise { const filePath = path.join(CLASSROOMS_DIR, `${id}.json`); try { const content = await fs.readFile(filePath, 'utf-8'); return JSON.parse(content) as PersistedClassroomData; } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') { return null; } throw error; } } export async function persistClassroom( data: { id: string; stage: Stage; scenes: Scene[]; }, baseUrl: string, ): Promise { const classroomData: PersistedClassroomData = { id: data.id, stage: data.stage, scenes: data.scenes, createdAt: new Date().toISOString(), }; await ensureClassroomsDir(); const filePath = path.join(CLASSROOMS_DIR, `${data.id}.json`); await writeJsonFileAtomic(filePath, classroomData); return { ...classroomData, url: `${baseUrl}/classroom/${data.id}`, }; }