feat(admin): add event alert detectors
This commit is contained in:
parent
4bae4b0ec3
commit
ab3f0a8b39
2 changed files with 164 additions and 1 deletions
|
|
@ -161,4 +161,69 @@ export async function detectPreRegistrantExpired() {
|
|||
}
|
||||
}
|
||||
|
||||
function eventItem(ev, sublabel) {
|
||||
return {
|
||||
id: String(ev._id),
|
||||
label: ev.title,
|
||||
sublabel,
|
||||
href: '/admin/events'
|
||||
}
|
||||
}
|
||||
|
||||
export async function detectDraftEventsImminent() {
|
||||
await connectDB()
|
||||
const now = new Date()
|
||||
const horizon = new Date(now.getTime() + ALERT_THRESHOLDS.DRAFT_IMMINENT_DAYS * DAY_MS)
|
||||
const events = await Event
|
||||
.find({
|
||||
isVisible: false,
|
||||
isCancelled: { $ne: true },
|
||||
startDate: { $gte: now, $lte: horizon }
|
||||
})
|
||||
.select('title startDate')
|
||||
.lean()
|
||||
return {
|
||||
type: 'event_draft_imminent',
|
||||
severity: 'critical',
|
||||
title: 'Draft events with imminent start',
|
||||
items: events.map((ev) => {
|
||||
const days = Math.max(0, Math.ceil((new Date(ev.startDate).getTime() - Date.now()) / DAY_MS))
|
||||
return eventItem(ev, `Starts in ${days} days`)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function detectEventsNearCapacity() {
|
||||
await connectDB()
|
||||
const now = new Date()
|
||||
const events = await Event
|
||||
.find({
|
||||
'tickets.enabled': true,
|
||||
'tickets.capacity.total': { $gt: 0 },
|
||||
isCancelled: { $ne: true },
|
||||
startDate: { $gte: now }
|
||||
})
|
||||
.select('title startDate tickets registrations')
|
||||
.lean()
|
||||
|
||||
const matched = events
|
||||
.map((ev) => {
|
||||
const total = ev.tickets?.capacity?.total
|
||||
if (!total) return null
|
||||
const reserved = ev.tickets?.capacity?.reserved || 0
|
||||
const taken = (ev.registrations?.length || 0) + reserved
|
||||
const ratio = taken / total
|
||||
if (ratio < ALERT_THRESHOLDS.NEAR_CAPACITY_RATIO) return null
|
||||
return eventItem(ev, `${taken} / ${total} seats taken`)
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
return {
|
||||
type: 'event_near_capacity',
|
||||
severity: 'attention',
|
||||
title: 'Events approaching capacity',
|
||||
items: matched
|
||||
}
|
||||
}
|
||||
|
||||
// Aggregator lands in task 8.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue