import { prisma } from "@app/lib/prisma"; import { InsightType, InsightPeriod } from "@prisma/client"; import { InsightPeriodPayload } from "@app/lib/queue/types"; import { avg } from "@app/utils/calc"; import { appDayWindow } from "@app/lib/queue/processors/insights/utils"; export async function processDailyEnergy({ userId, periodStart, }: InsightPeriodPayload): Promise { const { start, end } = appDayWindow(new Date(periodStart)); const moods = await prisma.mood.findMany({ where: { userId, moment: { gte: start, lt: end } }, orderBy: { moment: "asc" }, select: { energyLevel: true, stressLevel: true, anxietyLevel: true, selectedMood: true, moment: true, }, }); if (moods.length === 0) return; const avgEnergy = parseFloat(avg(moods.map((m) => m.energyLevel)).toFixed(2)); const avgStress = parseFloat(avg(moods.map((m) => m.stressLevel)).toFixed(2)); const avgAnxiety = parseFloat( avg(moods.map((m) => m.anxietyLevel)).toFixed(2), ); const peak = Math.max(...moods.map((m) => m.energyLevel)); const trough = Math.min(...moods.map((m) => m.energyLevel)); // Trend across the day: compare first half vs second half entries // Not that great, but it works const mid = Math.floor(moods.length / 2); const morningAvg = moods.length > 1 ? avg(moods.slice(0, mid).map((m) => m.energyLevel)) : null; const eveningAvg = moods.length > 1 ? avg(moods.slice(mid).map((m) => m.energyLevel)) : null; const dayTrend = morningAvg && eveningAvg ? parseFloat((((eveningAvg - morningAvg) / morningAvg) * 100).toFixed(1)) : null; await prisma.insight.upsert({ where: { userId_type_periodStart: { userId, type: InsightType.DAILY_ENERGY, periodStart: start, }, }, update: { body: buildBody(avgEnergy, dayTrend), metadata: { avgEnergy, avgStress, avgAnxiety, peak, trough, dayTrend, entryCount: moods.length, }, generatedAt: new Date(), }, create: { userId, type: InsightType.DAILY_ENERGY, period: InsightPeriod.DAILY, title: "Energia do Dia", body: buildBody(avgEnergy, dayTrend), metadata: { avgEnergy, avgStress, avgAnxiety, peak, trough, dayTrend, entryCount: moods.length, }, periodStart: start, periodEnd: end, }, }); } function buildBody(avgEnergy: number, dayTrend: number | null): string { const level = avgEnergy >= 7 ? "alta" : avgEnergy >= 4 ? "moderada" : "baixa"; if (dayTrend === null) return `Energia ${level} hoje.`; if (dayTrend > 10) return `Energia ${level} hoje, com melhora ao longo do dia.`; if (dayTrend < -10) return `Energia ${level} hoje, com queda ao longo do dia.`; return `Energia ${level} e estável ao longo do dia.`; }