services/FeedbackService.jsjavascript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("../utils/errors.js");
const feedback_1 = __importDefault(require("../db/models/feedback"));
const winston_1 = __importDefault(require("../plugins/winston"));
const MailService_1 = __importDefault(require("./MailService"));
const UserService_1 = __importDefault(require("./UserService"));
const { Sequelize, Op } = require("sequelize");
/**
 * Service for handling user feedback.
 * Manages feedback submission, retrieval, and processing.
 *
 * @class FeedbackService
 */
class FeedbackService {
    /**
     * Create a new Feedback
     *
     * @param {number} stars - Number of stars given in the feedback.
     * @param {string} text - Text content of the feedback.
     * @param {UUID} actingUserId - ID of the user submitting the feedback.
     * @returns {Promise<Feedback>} The created feedback object.
     */
    create(stars, text, actingUserId) {
        winston_1.default.debug(`FeedbackService create ${JSON.stringify({ stars, text, actingUserId })}`);
        return feedback_1.default.create({
            stars,
            text,
            UserId: actingUserId,
            creatorId: actingUserId,
            updaterId: actingUserId,
        }).then(async (feedback) => {
            let user = null;
            if (actingUserId)
                user = await UserService_1.default.findById(actingUserId).catch(() => null);
            if (!user)
                throw new errors_1.NotFoundError("User does not exist in order to create this feedback");
            if (user.email)
                MailService_1.default.sendFeedbackNotice(user?.username, user?.email, feedback.stars, feedback.text);
            return feedback;
        });
    }
    /**
     * Get all Feedbacks
     *
     * @param {UUID[]} ownerIds - IDs of the owners whose feedbacks are to be retrieved.
     * @param {UUID} actingUserId - ID of the acting user.
     * @returns {Promise<Feedback[]>} List of feedbacks for the user.
     */
    getAll(ownerIds, actingUserId) {
        winston_1.default.debug(`FeedbackService getAll ${JSON.stringify({ ownerIds, actingUserId })}`);
        return feedback_1.default.findAll({ where: { UserId: { [Op.in]: ownerIds } } });
    }
    /**
     * Get newest Feedback
     *
     * @returns {Promise<Feedback>} The most recently created feedback.
     */
    getNewest() {
        winston_1.default.debug(`FeedbackService getNewest`);
        return feedback_1.default.findAll({ order: ["createdAt"] }).then((feedbackList) => {
            return feedbackList[0];
        });
    }
    /**
     * Get the average stars of all Feedbacks
     *
     * @returns {Promise<number>} The average rating of all feedbacks.
     */
    getTotalAverage() {
        winston_1.default.debug(`FeedbackService getTotalAverage`);
        return feedback_1.default.findAll({
            attributes: [[Sequelize.fn("avg", Sequelize.col("stars")), "stars"]],
        }).then((result) => parseFloat(String(result[0].dataValues.stars)));
    }
    /**
     * Get the average stars of all Feedbacks in the last month
     *
     * @returns {Promise<number>} The average rating of feedbacks from the last month.
     */
    getAverageOfLastMonth() {
        winston_1.default.debug(`FeedbackService getAverageOfLastMonth`);
        return feedback_1.default.findAll({
            where: {
                createdAt: { [Op.gt]: new Date().valueOf() - 1000 * 60 * 60 * 24 * 30 },
            },
            attributes: [[Sequelize.fn("avg", Sequelize.col("stars")), "stars"]],
        }).then((result) => parseFloat(String(result[0].dataValues.stars)));
    }
    async migrateCreatorUpdater() {
        winston_1.default.debug(`FeedbackService migrateCreatorUpdater`);
        const feedbacks = await feedback_1.default.findAll({
            where: { creatorId: { [Op.is]: null }, UserId: { [Op.not]: null } },
        });
        await Promise.all(feedbacks.map((feedback) => feedback.update({
            creatorId: feedback.UserId,
            updaterId: feedback.UserId,
        })));
    }
}
exports.default = new FeedbackService();