• Mahmoud Aglan's avatar
    fix(training): give generated sessions a branch, and reserve the pitch they... · 5c5d1330
    Mahmoud Aglan authored
    fix(training): give generated sessions a branch, and reserve the pitch they were actually scheduled on
    
    Three defects on one path, all silent, all found while auditing a tenant whose
    sessions were invisible on every branch screen.
    
    BranchContext::branchIdForStamping() returns null in console and queue context —
    deliberately, because a cron that silently billed one branch would be worse than
    an unfiltered read. But that is exactly where sessions are born: the 02:00
    sessions:generate-upcoming run, and the TrainingSchedule::saved() hook. So
    SessionGeneratorService and AttendanceGenerationService, which both relied on the
    BelongsToBranch creating hook, have been writing branch_id NULL since they were
    written. On a strictly-scoped table that is not a leak but a disappearance: the
    row is in the database, counted by SQL, and on no screen in the product. It is
    also why attendance:backfill exists at 02:30 — it repairs the attendance half
    nightly, with the same session -> group attribution now applied at the source.
    
    CreateAutoReservation resolved the schedule by (training_group_id, day_of_week)
    and took ->first(): no start_time match, no is_active filter, no ordering. A
    group that trains twice on one weekday, or that has a deactivated row sitting
    beside a live one, booked whichever row sorted first — the wrong hour, or another
    branch's pitch entirely. The session already records which schedule row produced
    it, so use it; the (group, weekday) lookup survives only as a fallback for a
    session with no schedule_id, and now matches on time and is_active.
    
    The listener swallows its own exceptions into a log line, so none of this ever
    surfaced as an error.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    5c5d1330
Name
Last commit
Last update
..
Enums Loading commit data...
Events Loading commit data...
Listeners Loading commit data...
Models Loading commit data...
Services Loading commit data...
Support Loading commit data...