services/AdminService.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 admin_1 = __importDefault(require("../db/models/admin"));
const { Op } = require("sequelize");
const { logger } = require("../plugins/winston");
/**
 * Service for managing admin entities and their operations.
 * Handles CRUD operations and admin-specific logic.
 *
 * @class AdminService
 */
class AdminService {
    /**
     * Find or create an Admin by username. If not found, creates a new Admin with the given password.
     * @param {string} username - The admin's username.
     * @param {string} password - The admin's password.
     * @returns {Promise<Array<Admin|boolean>>} The found or newly created Admin instance and a boolean indicating if it was created.
     */
    async findOrCreate(username, password) {
        logger.debug(`AdminService findOrCreate ${JSON.stringify({
            username,
            password: password ? "<redacted>" : "undefined",
        })}`);
        const [admin, created] = await admin_1.default.findOrCreate({
            where: { username },
            defaults: {
                username,
                password,
            },
        });
        return [admin, created];
    }
    /**
     * Find an Admin by username.
     * @param {string} username - The admin's username.
     * @param {Object} options - Options object.
     * @param {string} [options.scope="defaultScope"] - Sequelize scope to use.
     * @returns {Promise<Admin|null>} The found Admin or null if not found.
     */
    findByUsername(username, { scope = "defaultScope" } = {}) {
        logger.debug(`AdminService findByUsername ${JSON.stringify({ username, scope })}`);
        return admin_1.default.scope(scope).findOne({ where: { username } }); // njsscan-ignore: node_nosqli_injection
    }
    /**
     * Find an Admin by its ID.
     * @param {UUID} id - The admin's UUID.
     * @returns {Promise<Admin|null>} The found Admin or null if not found.
     */
    findById(id) {
        logger.debug(`AdminService findById ${JSON.stringify({ id })}`);
        return admin_1.default.findByPk(id);
    }
    /**
     * Get the total number of Admins in the database.
     * @returns {Promise<number>} The count of Admins.
     */
    getCount() {
        logger.debug(`AdminService getCount`);
        return admin_1.default.count();
    }
    /**
     * Get all Admins in the database.
     * @returns {Promise<Admin[]>} Array of all Admins.
     */
    getAll() {
        logger.debug(`AdminService getAll`);
        return admin_1.default.findAll();
    }
    /**
     * Get the trend of Admins (new minus deleted) in the last 30 days.
     * @returns {Promise<number>} The net number of Admins added in the last 30 days.
     */
    getTrend() {
        logger.debug(`AdminService getTrend`);
        return Promise.all([
            admin_1.default.count({
                where: {
                    createdAt: {
                        [Op.gt]: new Date().valueOf() - 1000 * 60 * 60 * 24 * 30,
                    },
                },
            }),
            admin_1.default.count({
                where: {
                    deletedAt: {
                        [Op.gt]: new Date().valueOf() - 1000 * 60 * 60 * 24 * 30,
                    },
                },
            }),
        ]).then(([created, deleted]) => created - deleted);
    }
    /**
     * Update an Admin by ID.
     * @param {UUID} id - The admin's UUID.
     * @param {Object} data - The update data.
     * @returns {Promise<Admin>} The updated Admin instance.
     * @throws {Error} If no Admin with the given ID is found.
     */
    update(id, data) {
        const { password, ...logdata } = data;
        logger.debug(`AdminService update ${JSON.stringify({
            id,
            data: { ...logdata, password: password ? "<redacted>" : "undefined" },
        })}`);
        return this.findById(id).then(async (admin) => {
            if (admin) {
                logger.debug(`AdminService update ${JSON.stringify({ id, data })}`);
                await admin.update(data);
                await admin.save();
                return this.findById(id);
            }
            else {
                logger.error(`No admin found with ID ${id} when updating`);
                throw new errors_1.NotFoundError(`No admin found with ID ${id} when updating`);
            }
        });
    }
    /**
     * Delete an Admin by ID.
     * @param {UUID} id - The admin's UUID.
     * @returns {Promise<void>} Resolves if deletion is successful.
     * @throws {Error} If no Admin with the given ID is found.
     */
    remove(id) {
        logger.debug(`AdminService remove ${JSON.stringify({ id })}`);
        return this.findById(id).then(async (admin) => {
            if (admin) {
                logger.debug(`AdminService remove ${JSON.stringify({ id })}`);
                return admin.destroy();
            }
            else {
                logger.error(`No admin found with ID ${id} when deleting`);
                throw new errors_1.NotFoundError(`No admin found with ID ${id} when deleting`);
            }
        });
    }
}
exports.default = new AdminService();