eletrotupi / tcc/ api/src/lib/queue/processors/insights/dailySleep.tse2b786d3d7b4d089bb8eb05b23eafd24b3ab2774
2.7 KB | 106 lines Raw
1
import { prisma } from "@app/lib/prisma";
2
import { InsightType, InsightPeriod } from "@prisma/client";
3
import { InsightPeriodPayload } from "@app/lib/queue/types";
4
// XXX: date-fns?
5
import { formatHours, formatDiff } from "@app/utils/calc";
6
import { startOfDay, addDays, subDays } from "date-fns";
7

8
export async function processDailySleep({
9
  userId,
10
  periodStart,
11
}: InsightPeriodPayload): Promise<void> {
12
  const today = startOfDay(new Date(periodStart));
13
  const tomorrow = addDays(today, 1);
14
  const yesterday = subDays(today, 1);
15

16
  const [todayRecords, yesterdayRecords] = await Promise.all([
17
    prisma.sleepRecord.findMany({
18
      where: { userId, date: { gte: today, lt: tomorrow } },
19
      select: { average: true },
20
    }),
21
    prisma.sleepRecord.findMany({
22
      where: { userId, date: { gte: yesterday, lt: today } },
23
      select: { average: true },
24
    }),
25
  ]);
26

27
  console.log("todayRecords, yesterdayRecords", todayRecords, yesterdayRecords);
28

29
  if (todayRecords.length === 0) return;
30

31
  // average is stored in hours
32
  // sum across all records for the day
33
  const totalToday = todayRecords.reduce(
34
    (sum: number, r: { average: number }) => sum + r.average,
35
    0,
36
  );
37
  const totalYesterday =
38
    yesterdayRecords.length > 0
39
      ? yesterdayRecords.reduce(
40
          (sum: number, r: { average: number }) => sum + r.average,
41
          0,
42
        )
43
      : null;
44

45
  const diffMinutes =
46
    totalYesterday !== null
47
      ? Math.round((totalToday - totalYesterday) * 60)
48
      : null;
49

50
  const sessionCount = todayRecords.length; // 1 = normal night, 2+ = nap(s)
51

52
  const diffStr =
53
    diffMinutes !== null && Math.abs(diffMinutes) >= 5
54
      ? `${formatDiff(diffMinutes)} que ontem`
55
      : "";
56

57
  const napStr =
58
    sessionCount > 1
59
      ? `incluindo ${sessionCount - 1} cochilo${sessionCount > 2 ? "s" : ""}`
60
      : "";
61

62
  await prisma.insight.upsert({
63
    where: {
64
      userId_type_periodStart: {
65
        userId,
66
        type: InsightType.DAILY_SLEEP,
67
        periodStart: today,
68
      },
69
    },
70
    update: {
71
      body: buildBody(totalToday),
72
      metadata: {
73
        totalHours: totalToday,
74
        diffMinutes,
75
        diffStr,
76
        sessionCount,
77
        napStr,
78
        hadNaps: sessionCount > 1,
79
      },
80
      generatedAt: new Date(),
81
    },
82
    create: {
83
      userId,
84
      type: InsightType.DAILY_SLEEP,
85
      period: InsightPeriod.DAILY,
86
      title: "Sono",
87
      body: buildBody(totalToday),
88
      metadata: {
89
        totalHours: totalToday,
90
        diffMinutes,
91
        sessionCount,
92
        diffStr,
93
        napStr,
94
        hadNaps: sessionCount > 1,
95
      },
96
      periodStart: today,
97
      periodEnd: tomorrow,
98
    },
99
  });
100
}
101

102
function buildBody(total: number): string {
103
  const totalStr = formatHours(total);
104

105
  return `${totalStr} de sono hoje`;
106
}