Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-12 12:39:17 +08:00
parent 82ea9c77c4
commit ea3e82e54c
47 changed files with 1301 additions and 481 deletions
+31 -5
View File
@@ -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 } } },
});