eletrotupi / tcc / api/src/services/mood.service.ts master
2.9 KB Raw
import { prisma } from "@app/lib/prisma";
import { Mood } from "@prisma/client";
import { rollingPeriod } from "@app/lib/queue/processors/insights/utils";
import { InsightJobName } from "@app/lib/queue/types";
import { getQueue } from "@app/lib/queue";

import { CreateMoodInput } from "@app/schemas";

export const createMood = async (
  userId: number,
  input: CreateMoodInput,
): Promise<Mood> => {
  const { moodComponents, ...moodData } = input;

  const mood = prisma.mood.create({
    data: {
      ...moodData,
      userId,
      moodComponents: {
        create: moodComponents,
      },
    },
    include: { moodComponents: true },
  });

  void enqueueOnDemandInsights(userId);

  return mood;
};

export const getMoodsByUserId = async (
  userId: number,
  params?: {
    limit?: number;
    page?: number;
    from?: string;
    to?: string;
  },
): Promise<{
  entries: Mood[];
  total: number;
  page: number;
  nextPage: number | null;
}> => {
  const page = params?.page ?? 1;
  const limit = params?.limit ?? 20;
  const skip = (page - 1) * limit;

  const where = {
    userId,
    ...(params?.from || params?.to
      ? {
          moment: {
            ...(params.from && { gte: new Date(params.from) }),
            ...(params.to && { lte: new Date(params.to) }),
          },
        }
      : {}),
  };

  const [entries, total] = await Promise.all([
    prisma.mood.findMany({
      where,
      include: { moodComponents: true },
      orderBy: { moment: "desc" },
      take: limit,
      skip,
    }),
    prisma.mood.count({ where }),
  ]);

  const totalPages = Math.ceil(total / limit);

  return {
    entries,
    total,
    page,
    nextPage: page < totalPages ? page + 1 : null,
  };
};

export const getMoodById = async (id: number): Promise<Mood | null> => {
  return await prisma.mood.findUnique({
    where: {
      id,
    },
    include: { moodComponents: true },
  });
};

export const destroyMoodById = async (
  userId: number,
  id: number,
): Promise<Mood> => {
  return await prisma.mood.delete({
    where: {
      id,
      userId,
    },
  });
};

export const enqueueOnDemandInsights = async (
  userId: number,
): Promise<void> => {
  const queue = getQueue("insights");
  const period = rollingPeriod(7);
  const payload = { userId, ...period };

  await queue.addBulk([
    {
      name: InsightJobName.MoodTrend,
      data: payload,
      opts: {
        jobId: `mood-trend-${userId}-${new Date().toDateString()}`,
        removeOnComplete: true,
      },
    },
    {
      name: InsightJobName.EnergySleep,
      data: payload,
      opts: {
        jobId: `energy-sleep-${userId}-${new Date().toDateString()}`,
        removeOnComplete: true,
      },
    },
    {
      name: InsightJobName.DailyEnergy,
      data: payload,
      opts: {
        jobId: `daily-energy-${userId}-${new Date().toDateString()}`,
        removeOnComplete: true,
      },
    },
  ]);
};