// Laboratorio del giroscopio (solo para desarrollo; se borrará junto con public/gyrolab.js y su botón en Ajustes). // Guarda las grabaciones de los sensores en DATA_DIR/gyrolab/, una por paso del guion. import fs from 'node:fs' import path from 'node:path' const MAX_BYTES = 4 * 1024 * 1024 const SESSION = /^[a-z0-9]{4,24}$/, STEP = /^[a-z0-9-]{2,24}$/ export function setupGyroLab({ DATA_DIR, HttpError, json }) { const dir = path.join(DATA_DIR, 'gyrolab') async function readRaw(req) { let size = 0 const chunks = [] for await (const c of req) { size += c.length if (size > MAX_BYTES) throw new HttpError(413, 'Grabación demasiado grande') chunks.push(c) } try { return JSON.parse(Buffer.concat(chunks).toString()) } catch { throw new HttpError(400, 'JSON inválido') } } async function route(p, method, req, res, user) { if (p !== '/api/gyrolab') return false if (method === 'GET') { const mine = fs.existsSync(dir) ? fs.readdirSync(dir).filter(f => f.startsWith(`u${user.id}-`)) : [] return json(res, 200, { files: mine.sort() }) } if (method !== 'POST') throw new HttpError(405, 'Método no permitido') const body = await readRaw(req) if (!SESSION.test(body?.session || '') || !STEP.test(body?.step || '')) throw new HttpError(400, 'Sesión o paso no válidos') if (!Array.isArray(body.ori) || !Array.isArray(body.mot)) throw new HttpError(400, 'Faltan lecturas') fs.mkdirSync(dir, { recursive: true }) const name = `u${user.id}-${body.session}-${body.step}.json` fs.writeFileSync(path.join(dir, name), JSON.stringify({ ...body, user: user.username, savedAt: Date.now() })) return json(res, 200, { ok: true, file: name }) } return { route } }