Add Day Started event to activity log with template name

- On session start, insert a session_start TimerEvent so the action
  appears in the activity log timeline
- Load DailySession.template via selectinload in the timeline query
  so the template name is available without extra round-trips
- _to_timeline_out maps the template name into block_label for
  session_start events, displaying as "Day started — Template Name"
- Add session_start to EVENT_META on the frontend (🏫 icon)
- Hide the Edit button for session_start entries since changing their
  event type to a block-level action doesn't make sense

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 14:22:07 -08:00
parent 823260cdd8
commit 37416436ba
3 changed files with 25 additions and 9 deletions

View File

@@ -31,7 +31,10 @@ async def get_timeline(
.where(Child.user_id == current_user.id)
.options(
selectinload(TimerEvent.block).selectinload(ScheduleBlock.subject),
selectinload(TimerEvent.session).selectinload(DailySession.child),
selectinload(TimerEvent.session).options(
selectinload(DailySession.child),
selectinload(DailySession.template),
),
)
.order_by(TimerEvent.occurred_at.desc())
)
@@ -49,6 +52,10 @@ async def get_timeline(
def _to_timeline_out(e: TimerEvent) -> TimelineEventOut:
blk = e.block
sub = blk.subject if blk else None
if e.event_type == "session_start":
block_label = e.session.template.name if e.session.template else None
else:
block_label = (blk.label or sub.name) if blk and sub else (blk.label if blk else None)
return TimelineEventOut(
id=e.id,
event_type=e.event_type,
@@ -56,7 +63,7 @@ def _to_timeline_out(e: TimerEvent) -> TimelineEventOut:
session_date=e.session.session_date,
child_id=e.session.child_id,
child_name=e.session.child.name,
block_label=(blk.label or sub.name) if blk and sub else (blk.label if blk else None),
block_label=block_label,
subject_name=sub.name if sub else None,
subject_icon=sub.icon if sub else None,
subject_color=sub.color if sub else None,
@@ -71,7 +78,10 @@ async def _get_timer_event(event_id: int, current_user: User, db: AsyncSession)
.where(TimerEvent.id == event_id, Child.user_id == current_user.id)
.options(
selectinload(TimerEvent.block).selectinload(ScheduleBlock.subject),
selectinload(TimerEvent.session).selectinload(DailySession.child),
selectinload(TimerEvent.session).options(
selectinload(DailySession.child),
selectinload(DailySession.template),
),
)
)
event = result.scalar_one_or_none()