import { listUserDevices, registerDevice } from "../../db/devices"; import { getProfile } from "../../db/profile"; import { getPlanLimits } from "../../utils/plan-features"; /** * POST /api/devices/register * * Body: { deviceId: string, platform: string, model?: string, name?: string } * * Idempotent: gleiche deviceId für gleichen User → updated lastSeenAt + 200. * Wenn neues Device + Limit erreicht → 403 mit { error, devices } damit der * Frontend-Drawer dem User die Wahl gibt, welches Gerät er freigibt. */ export default defineEventHandler(async (event) => { // Bootstrap: kein Device-Check sonst wäre erstes Register unmöglich (chicken-egg) const user = await requireUser(event, { skipDeviceCheck: true }); const body = await readBody(event); const { deviceId, platform, model, name, osVersion } = body as { deviceId?: string; platform?: string; model?: string; name?: string; osVersion?: string; }; if (!deviceId || !platform) { throw createError({ statusCode: 400, message: "deviceId und platform required", }); } if (!["ios", "android", "web"].includes(platform)) { throw createError({ statusCode: 400, message: "invalid platform" }); } const profile = await getProfile(user.id); const limits = getPlanLimits(profile?.plan ?? "free"); try { const { device, created, merged } = await registerDevice({ userId: user.id, deviceId, platform, model: model ?? null, name: name ?? null, osVersion: osVersion ?? null, maxDevices: limits.maxAppDevices, }); return { device, created, merged: merged ?? false, max: limits.maxAppDevices }; } catch (err: any) { if (err.code === "DEVICE_LIMIT_REACHED") { const allDevices = await listUserDevices(user.id); const devices = allDevices.map((d) => ({ ...d, isCurrent: d.deviceId === deviceId, })); throw createError({ statusCode: 403, statusMessage: "device_limit_reached", data: { error: "device_limit_reached", max: limits.maxAppDevices, plan: profile?.plan ?? "free", devices, }, }); } throw err; } });