mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
139 lines
6.4 KiB
JavaScript
139 lines
6.4 KiB
JavaScript
'use strict';
|
|
|
|
const mdl_TierCategories = require('../../models/tiers/tier_categories.mdl');
|
|
const mdl_TierPlans = require('../../models/tiers/tier_plans.mdl');
|
|
const Asset = require('../../models/assets/assets.mdl');
|
|
const R = require('../../utils/response.util');
|
|
const logActivity = require('../../utils/logActivity.util');
|
|
|
|
require('../../models/tiers/tier.associations');
|
|
|
|
const ASSET_ATTRS = ['asset_id', 'file_url', 'display_name', 'mime_type'];
|
|
|
|
const withBadge = [{ model: Asset, as: 'badgeAsset', attributes: ASSET_ATTRS, required: false }];
|
|
|
|
// ─── GET /admin/tiers/categories ─────────────────────────────────────────────
|
|
|
|
exports.getCategories = async (req, res) => {
|
|
try {
|
|
const categories = await mdl_TierCategories.findAll({
|
|
include: withBadge,
|
|
order: [['rank', 'ASC']],
|
|
});
|
|
return R.success(res, 'Tier categories retrieved.', categories);
|
|
} catch (err) {
|
|
console.error('[ADMIN][GET TIER CATEGORIES]', err);
|
|
return R.error(res, 'Could not retrieve tier categories.', 500);
|
|
}
|
|
};
|
|
|
|
// ─── GET /admin/tiers/categories/:id ─────────────────────────────────────────
|
|
|
|
exports.getCategory = async (req, res) => {
|
|
try {
|
|
const cat = await mdl_TierCategories.findByPk(req.params.id, { include: withBadge });
|
|
if (!cat) return R.error(res, 'Tier category not found.', 404);
|
|
return R.success(res, 'Tier category retrieved.', cat);
|
|
} catch (err) {
|
|
console.error('[ADMIN][GET TIER CATEGORY]', err);
|
|
return R.error(res, 'Could not retrieve tier category.', 500);
|
|
}
|
|
};
|
|
|
|
// ─── POST /admin/tiers/categories ────────────────────────────────────────────
|
|
|
|
exports.createCategory = async (req, res) => {
|
|
try {
|
|
const { slug, name, description, rank, color, badge_asset_id, badge_icon, badge_label, is_special } = req.body;
|
|
if (!slug || !name) return R.error(res, 'slug and name are required.', 400);
|
|
|
|
const parsedRank = Number(rank ?? 1);
|
|
if (parsedRank <= 0) return R.error(res, 'Non-default tier categories must have rank greater than 0.', 400);
|
|
|
|
const exists = await mdl_TierCategories.findOne({ where: { slug } });
|
|
if (exists) return R.error(res, `A tier category with slug "${slug}" already exists.`, 409);
|
|
|
|
const cat = await mdl_TierCategories.create({
|
|
slug, name,
|
|
description: description ?? null,
|
|
rank: parsedRank,
|
|
color: color || 'purple',
|
|
badge_asset_id: badge_asset_id || null,
|
|
badge_icon: badge_icon || null,
|
|
badge_label: badge_label ?? null,
|
|
is_default: false,
|
|
is_active: true,
|
|
is_special: !!is_special,
|
|
});
|
|
|
|
logActivity(req.user?.user_id, 'create_tier_category', { entityType: 'tier_category', details: { slug, name } });
|
|
|
|
const result = await mdl_TierCategories.findByPk(cat.tier_category_id, { include: withBadge });
|
|
return R.success(res, 'Tier category created.', result, 201);
|
|
} catch (err) {
|
|
console.error('[ADMIN][CREATE TIER CATEGORY]', err);
|
|
return R.error(res, 'Could not create tier category.', 500);
|
|
}
|
|
};
|
|
|
|
// ─── PUT /admin/tiers/categories/:id ─────────────────────────────────────────
|
|
|
|
exports.updateCategory = async (req, res) => {
|
|
try {
|
|
const cat = await mdl_TierCategories.findByPk(req.params.id);
|
|
if (!cat) return R.error(res, 'Tier category not found.', 404);
|
|
|
|
const { name, description, rank, color, badge_asset_id, badge_icon, badge_label, is_active, is_special } = req.body;
|
|
|
|
if (!cat.is_default && rank !== undefined) {
|
|
const parsedRank = Number(rank);
|
|
if (parsedRank <= 0) return R.error(res, 'Non-default tier categories must have rank greater than 0.', 400);
|
|
}
|
|
|
|
await cat.update({
|
|
name: name ?? cat.name,
|
|
description: description !== undefined ? (description || null) : cat.description,
|
|
rank: rank !== undefined ? Number(rank) : cat.rank,
|
|
color: color !== undefined ? (color || cat.color) : cat.color,
|
|
badge_asset_id: badge_asset_id !== undefined ? (badge_asset_id || null) : cat.badge_asset_id,
|
|
badge_icon: badge_icon !== undefined ? (badge_icon || null) : cat.badge_icon,
|
|
badge_label: badge_label !== undefined ? (badge_label || null) : cat.badge_label,
|
|
// Default category (free) cannot be deactivated
|
|
is_active: (!cat.is_default && is_active !== undefined) ? is_active : cat.is_active,
|
|
is_special: is_special !== undefined ? !!is_special : cat.is_special,
|
|
});
|
|
|
|
logActivity(req.user?.user_id, 'update_tier_category', { entityType: 'tier_category', details: { id: cat.tier_category_id, slug: cat.slug } });
|
|
|
|
const result = await mdl_TierCategories.findByPk(cat.tier_category_id, { include: withBadge });
|
|
return R.success(res, 'Tier category updated.', result);
|
|
} catch (err) {
|
|
console.error('[ADMIN][UPDATE TIER CATEGORY]', err);
|
|
return R.error(res, 'Could not update tier category.', 500);
|
|
}
|
|
};
|
|
|
|
// ─── DELETE /admin/tiers/categories/:id ──────────────────────────────────────
|
|
|
|
exports.deleteCategory = async (req, res) => {
|
|
try {
|
|
const cat = await mdl_TierCategories.findByPk(req.params.id);
|
|
if (!cat) return R.error(res, 'Tier category not found.', 404);
|
|
if (cat.is_default) return R.error(res, 'The default (Free) tier category cannot be deleted.', 400);
|
|
|
|
// Block deletion if active plans still reference this category
|
|
const activePlans = await mdl_TierPlans.count({
|
|
where: { tier_category_id: cat.tier_category_id, is_active: true },
|
|
});
|
|
if (activePlans > 0)
|
|
return R.error(res, `Cannot delete — ${activePlans} active plan(s) belong to this category. Archive or reassign them first.`, 409);
|
|
|
|
await cat.destroy();
|
|
logActivity(req.user?.user_id, 'delete_tier_category', { entityType: 'tier_category', details: { slug: cat.slug } });
|
|
return R.success(res, 'Tier category deleted.');
|
|
} catch (err) {
|
|
console.error('[ADMIN][DELETE TIER CATEGORY]', err);
|
|
return R.error(res, 'Could not delete tier category.', 500);
|
|
}
|
|
};
|