services/SeasonService.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 season_1 = __importDefault(require("../db/models/season"));
const accessControl_1 = require("../utils/accessControl");
const stripProtectedFields_1 = require("../utils/stripProtectedFields.js");
const { Op } = require("sequelize");
const { logger } = require("../plugins/winston");
/**
* Service for managing season entities and their associations.
* Handles CRUD operations and season-specific logic.
*
* @class SeasonService
*/
class SeasonService {
/**
* Get all seasons for a user.
* @param {string[] | null} ownerIds - Array of owner IDs the acting user has access to.
* @param {UUID} actingUserId - The acting user ID.
* @param {Object} options - Options for fetching seasons.
* @param {boolean} options.all - Whether to fetch all seasons.
* @returns {Promise<Array>} List of seasons.
*/
async getAll(ownerIds, actingUserId, isAdmin = false, options = { all: false }) {
logger.debug(`SeasonService getAll ${JSON.stringify({ ownerIds, actingUserId, isAdmin, options })}`);
const accessibleOwnerIds = ownerIds && ownerIds.length > 0
? await (0, accessControl_1.filterAccessibleOwnerIds)(ownerIds, actingUserId, isAdmin)
: [];
if (accessibleOwnerIds.length > 0)
return season_1.default.findAll({
where: options.all
? {}
: {
UserId: {
[Op.or]: [{ [Op.in]: accessibleOwnerIds }, { [Op.eq]: null }],
},
},
order: [["year", "DESC NULLS LAST"], "createdAt"],
});
else
return season_1.default.findAll({
where: options.all ? {} : { UserId: { [Op.is]: null } },
order: [["year", "DESC NULLS LAST"], "createdAt"],
});
}
/**
* Get the total count of seasons.
* @returns {Promise<number>} Count of seasons.
*/
getCount() {
logger.debug(`SeasonService getCount`);
return season_1.default.count();
}
/**
* Get the trend of season creation in the last 30 days.
* @returns {Promise<number>} Count of seasons created in the last 30 days.
*/
getTrend() {
logger.debug(`SeasonService getTrend`);
return season_1.default.count({
where: {
createdAt: { [Op.gt]: new Date().valueOf() - 1000 * 60 * 60 * 24 * 30 },
},
});
}
/**
* Create a new season.
*
* @param {string} name - Name of the season.
* @param {number} year - Year of the season.
* @param {UUID|null} ownerId - Owner ID. If null/undefined, falls back to actingUserId
* @param {UUID} actingUserId - The acting user ID.
* @param {boolean} [isAdmin=false]
* @returns {Promise<Object>} Created season object.
*/
async create(name, year, ownerId, actingUserId, isAdmin = false) {
logger.debug(`SeasonService create ${JSON.stringify({
name,
year,
ownerId,
actingUserId,
isAdmin,
})}`);
await (0, accessControl_1.checkWriteAccess)(ownerId, actingUserId, isAdmin);
return season_1.default.create({
name,
year,
UserId: ownerId,
creatorId: actingUserId,
updaterId: actingUserId,
});
}
/**
* Update an existing season.
* @param {UUID} id - ID of the season to update.
* @param {Object} data - Data to update the season with.
* @param {UUID} actingUserId - The acting user ID.
* @param {Object} options - Options for updating the season.
* @param {boolean} options.all - Whether to update all seasons.
* @returns {Promise<Object>} Updated season object.
* @throws Will throw an error if the season is not found.
*/
async update(id, data, actingUserId, isAdmin = false, options = { all: false }) {
logger.debug(`SeasonService update ${JSON.stringify({ id, data, actingUserId, isAdmin, options })}`);
const foundSeason = await season_1.default.findByPk(id);
if (!foundSeason) {
logger.error(`No season found with ID ${id} when updating`);
throw new errors_1.NotFoundError(`No season found with ID ${id} when updating`);
}
await (0, accessControl_1.checkWriteAccess)(foundSeason.UserId, actingUserId, isAdmin);
await foundSeason.update({
...(0, stripProtectedFields_1.stripProtectedUpdateFields)(data),
updaterId: actingUserId,
});
return foundSeason.save();
}
/**
* Remove a season.
* @param {UUID} id - ID of the season to remove.
* @param {UUID} actingUserId - The acting user ID.
* @param {Object} options - Options for removing the season.
* @param {boolean} options.all - Whether to remove all seasons.
* @returns {Promise<void>} Resolves when the season is removed.
* @throws Will throw an error if the season is not found.
*/
async remove(id, actingUserId, isAdmin = false, options = { all: false }) {
logger.debug(`SeasonService remove ${JSON.stringify({ id, actingUserId, isAdmin, options })}`);
const foundSeason = await season_1.default.findByPk(id);
if (!foundSeason) {
logger.error(`No season found with ID ${id} when deleting`);
throw new errors_1.NotFoundError(`No season found with ID ${id} when deleting`);
}
await (0, accessControl_1.checkDeleteAccess)(foundSeason.UserId, actingUserId, isAdmin);
return foundSeason.destroy();
}
async migrateCreatorUpdater() {
logger.debug(`SeasonService migrateCreatorUpdater`);
const seasons = await season_1.default.findAll({
where: { creatorId: { [Op.is]: null }, UserId: { [Op.not]: null } },
});
await Promise.all(seasons.map((season) => season.update({ creatorId: season.UserId, updaterId: season.UserId })));
}
}
exports.default = new SeasonService();