import { usePrisma } from "../utils/prisma"; // ─── Types ──────────────────────────────────────────────────────────────────── export type ProtectionType = "nefilter" | "vpn" | "dns"; export const PROTECTION_TYPES: ProtectionType[] = [ "nefilter", "vpn", "dns", ]; export interface DeviceProtectionStateRecord { id: string; userId: string; deviceId: string; platform: string; protectionType: string; active: boolean; lastSeenAt: Date | null; changedAt: Date; reason: string | null; } // ─── Write ───────────────────────────────────────────────────────────────────── /** * Upserts the per-device/per-protection-type state. * * If `active` changed compared to the existing row (or there was no row), an * entry is appended to `DeviceProtectionStateLog` with `occurredAt = now()`. */ export async function upsertDeviceProtectionState( userId: string, deviceId: string, platform: string, protectionType: ProtectionType, active: boolean, lastSeenAt?: Date | null, reason?: string | null, source?: string | null, ): Promise { const db = usePrisma(); const now = new Date(); const existing = await db.deviceProtectionState.findUnique({ where: { userId_deviceId_protectionType: { userId, deviceId, protectionType }, }, }); const changed = !existing || existing.active !== active; const row = await db.deviceProtectionState.upsert({ where: { userId_deviceId_protectionType: { userId, deviceId, protectionType }, }, create: { userId, deviceId, platform, protectionType, active, lastSeenAt: lastSeenAt ?? null, changedAt: now, reason: reason ?? null, }, update: { platform, active, lastSeenAt: lastSeenAt === undefined ? undefined : lastSeenAt, changedAt: now, reason: reason === undefined ? undefined : reason, }, }); if (changed) { await db.deviceProtectionStateLog.create({ data: { userId, deviceId, protectionType, active, occurredAt: now, reason: reason ?? null, source: source ?? "app", }, }); } return row; } // ─── Read ────────────────────────────────────────────────────────────────────── /** Returns the current state for one protection type on a device. */ export async function getDeviceProtectionState( userId: string, deviceId: string, protectionType: ProtectionType, ): Promise { const db = usePrisma(); return db.deviceProtectionState.findUnique({ where: { userId_deviceId_protectionType: { userId, deviceId, protectionType }, }, }); } /** Lists all protection states for a user, optionally filtered to one device. */ export async function listDeviceProtectionStates( userId: string, deviceId?: string, ): Promise { const db = usePrisma(); return db.deviceProtectionState.findMany({ where: { userId, ...(deviceId ? { deviceId } : {}), }, orderBy: [{ deviceId: "asc" }, { protectionType: "asc" }], }); }