mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -94,10 +94,21 @@ async function applyAdvertisementFields(advertisement, body) {
|
||||
// status is intentionally NOT settable here — it's derived via deriveStatus()
|
||||
// right before save, based on is_active + start_date/end_date.
|
||||
|
||||
if (body.content_mode !== undefined) {
|
||||
if (!["image", "content"].includes(body.content_mode)) {
|
||||
const err = new Error(`Invalid content_mode. Must be one of: image, content`);
|
||||
err.status = 400;
|
||||
throw err;
|
||||
}
|
||||
advertisement.content_mode = body.content_mode;
|
||||
}
|
||||
|
||||
if (body.badge_label !== undefined) advertisement.badge_label = body.badge_label;
|
||||
if (body.headline !== undefined) advertisement.headline = body.headline;
|
||||
if (body.description !== undefined) advertisement.description = body.description;
|
||||
if (body.image_url !== undefined) advertisement.image_url = body.image_url;
|
||||
if (body.redirect_link !== undefined) advertisement.redirect_link = body.redirect_link || null;
|
||||
if (body.landing_page !== undefined) advertisement.landing_page = body.landing_page || null;
|
||||
|
||||
if (body.image_asset_id !== undefined) {
|
||||
if (body.image_asset_id === null) {
|
||||
@@ -136,8 +147,27 @@ async function applyAdvertisementFields(advertisement, body) {
|
||||
|
||||
// ─── GET ALL ──────────────────────────────────────────────────────────────────
|
||||
|
||||
// Keeps the stored `status` column in sync with deriveStatus() before the
|
||||
// filtered query runs — status is otherwise only recomputed on individual
|
||||
// row reads, so filtering by status (e.g. "expired") would miss rows whose
|
||||
// start_date/end_date lapsed since they were last saved.
|
||||
async function syncDerivedStatuses() {
|
||||
await sequelize.query(`
|
||||
UPDATE advertisements
|
||||
SET status = CASE
|
||||
WHEN is_active = false THEN 'draft'
|
||||
WHEN end_date IS NOT NULL AND end_date < NOW() THEN 'expired'
|
||||
WHEN start_date IS NOT NULL AND start_date > NOW() THEN 'scheduled'
|
||||
ELSE 'active'
|
||||
END
|
||||
WHERE "deletedAt" IS NULL
|
||||
`);
|
||||
}
|
||||
|
||||
exports.getAdvertisements = async (req, res) => {
|
||||
try {
|
||||
await syncDerivedStatuses();
|
||||
|
||||
const result = await paginate(Advertisement, req, {
|
||||
excludeAttributes: adminExclude,
|
||||
jsonbSchemas,
|
||||
@@ -275,10 +305,6 @@ exports.updateAdvertisement = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(ads-7): Once expired (end_date passed), an advertisement should be
|
||||
// auto-archived (soft-deleted via the same path as archiveAdvertisement below)
|
||||
// instead of just sitting at derived status "expired" indefinitely. Add a
|
||||
// cron job — see TODO(ads-7) in new_starr/cron/client.cron.js.
|
||||
// ─── ARCHIVE (single) ─────────────────────────────────────────────────────────
|
||||
|
||||
exports.archiveAdvertisement = async (req, res) => {
|
||||
@@ -382,7 +408,7 @@ exports.getArchivedAdvertisements = async (req, res) => {
|
||||
excludeAttributes: adminExclude,
|
||||
jsonbSchemas,
|
||||
computedAttributes,
|
||||
context: "list",
|
||||
context: "archived",
|
||||
auditOptions: { mdl_Users, parentAlias: 'Advertisement' },
|
||||
findOptions: { paranoid: false, where: { deletedAt: { [Op.ne]: null } } },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user