Files
crewli/api/routes/console.php
bert.hausmans 609280d061 feat(timetable): DemoteExpiredOptions scheduled command
`artist:demote-expired-options` artisan command finds every
ArtistEngagement still in Option whose option_expires_at has passed,
transitions it back to Draft via the existing state-machine
(transitionStatus), and writes an `option_expired` activity entry
with the original expiry timestamp captured in properties so the
audit log distinguishes system-driven expiries from manual demotions.

Idempotency: the state-machine bails when the engagement is no longer
in Option, so a second run within the same minute is a no-op for any
given row. The auto-logged `updated` row + the explicit
`status_changed` + the `option_expired` entries are emitted only by
the run that actually performs the transition.

Scheduled in routes/console.php daily at 03:00 Europe/Amsterdam,
matching the existing nightly low-traffic window.

Notification (email project leader on demotion) is deferred to the
notification framework that lands post-Accreditation; tracked under
BACKLOG entry ART-DEMOTE-NOTIFICATION.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 20:59:39 +02:00

26 lines
876 B
PHP

<?php
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');
Schedule::command('invitations:expire')->daily();
// RFC-TIMETABLE v0.2 — demote engagements whose option_expires_at has
// passed back to Draft. Daily at 03:00 Europe/Amsterdam (matches the
// scheduler's nightly window for low-traffic state changes).
Schedule::command('artist:demote-expired-options')
->dailyAt('03:00')
->timezone('Europe/Amsterdam');
// Telescope retention — dev-only (mirrors AppServiceProvider's
// environment gate). 48h is enough for debugging without filling the
// dev database.
Schedule::command('telescope:prune --hours=48')
->daily()
->environments(['local', 'testing']);