Commit Graph
18 Commits
Author SHA1 Message Date
derekcandClaude Opus 5.5 5a2510059d Fix timer action 500s after FastAPI upgrade
FastAPI 0.141 raises when response serialization hits a lazy-load
(current_block.subject.options) in async context, where 0.115 silently
skipped it. Eager-load Subject.options in session get/timer and the TV
dashboard queries. Pin pydantic 2.13.5.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-24 23:51:10 -07:00
derekcandClaude Sonnet 4.6 fdd85d3df5 Add per-block agenda overrides for daily sessions
- Add 📝 Agenda button to each block in Today's Schedule on the Dashboard
- Dialog allows setting a free-text activity/note for that block for the current day
- Agenda replaces subject options in the TV center panel while set; clears on session end
- Backend: new SessionBlockAgenda model, PUT /api/sessions/{id}/blocks/{block_id}/agenda
- Agendas included in dashboard snapshot and session_update WS broadcast
- New agenda_update WS event keeps TV in sync live when agenda is saved or cleared
- Update README with feature description, project structure, and WS event table

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-19 07:58:30 -07:00
derekcandClaude Sonnet 4.6 ff9a863393 Add Done button, tablet controls, super admin management, midnight strike reset, and activity log improvements
- Done button snaps block to full duration, marks complete, logs "Marked Done by User"; Reset after Done fully un-completes the block
- Session action buttons stretch full-width and double height for tablet tapping
- Super admin: reset password, disable/enable accounts, delete user (with cascade), last active date per user's timezone
- Disabled account login returns specific error message instead of generic invalid credentials
- Users can change own password from Admin → Settings
- Strikes reset automatically at midnight in user's configured timezone (lazy reset on page load)
- Break timer state fully restored when navigating away and back to dashboard
- Timer no longer auto-starts on navigation if it wasn't running before
- Implicit pause guard: no duplicate pause events when switching already-paused blocks or starting a break
- Block selection events removed from activity log; all event types have human-readable labels
- House emoji favicon via inline SVG data URI
- README updated to reflect all changes

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-06 00:08:15 -08:00
derekcandClaude Sonnet 4.6 a8e1b322f1 Tie break timer and main block timer together
- Starting break now pauses the main block timer (frontend optimistic +
  backend implicit pause event recorded before break_start)
- Resuming/starting the main block while break is active pauses the
  break timer and exits break mode on all clients including TV
- Timer display counts negative past zero so overtime is visible while
  label stays "Done!"
- Fixed WS start handler incorrectly skipping break-mode clear when
  restarting the same block; resume handler now also clears break mode

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-03 14:24:50 -08:00
derekcandClaude Sonnet 4.6 c565c94a23 Remove school day hours from schedule templates
The day progress bar no longer uses day start/end times (it uses block
durations instead), so the field is no longer needed.

Removed from: Admin UI, schedule store, schedule model/schemas/router,
session broadcast payload, dashboard snapshot, and startup migrations.
DB columns are left in place (harmless, no migration required).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-03 13:45:05 -08:00
derekcandClaude Sonnet 4.6 87315b8902 Add break time feature to schedule blocks
- Admin: per-block "Break Time" checkbox + duration (min) setting; new
  Break Activities section (global list, same pattern as Morning Routine)
- Dashboard: break timer section appears on blocks with break enabled;
  Start/Pause/Resume/Reset controls work independently of the main timer
- TV: left column switches to amber break badge + countdown during break;
  center column shows configurable Break Activities list
- Backend: break_time_enabled/break_time_minutes columns on schedule_blocks
  (auto-migrated on startup); break_activity_items table + CRUD router;
  break timer events (break_start/pause/resume/reset) stored as TimerEvents
  and broadcast via WebSocket; break_activities included in dashboard
  snapshot and session_update broadcast

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-03 08:40:49 -08:00
derekcandClaude Sonnet 4.6 1420d57e7e Add Reset button and move End Day to right side of actions bar
Reset clears the current block's elapsed time to zero and immediately
starts the timer. A shared compute_block_elapsed() utility (utils/timer.py)
handles the elapsed calculation in both the sessions and dashboard routers,
and correctly treats "reset" events as zero-elapsed restart markers so
page reloads after a reset show accurate times.

Layout: Start/Pause/Resume/Reset are grouped on the left; End Day sits
on the right via justify-content: space-between.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-03 00:17:02 -08:00
derekcandClaude Sonnet 4.6 cc599603cf Add manual block start and fix timer display labels
Blocks are now selected without auto-starting the timer. Clicking a block
makes it current (highlighted) but leaves it in a ready state. A "Start"
button (indigo) triggers timing for a fresh block; "Resume" appears for
previously-worked blocks; "Pause" remains while running.

Also fixes the sidebar duration label to show "Done!" when elapsed ≥ total
and "< 1 min" for sub-minute remaining time instead of "0 min".

Backend adds a "select" event type that records an implicit pause for the
previous block, updates current_block_id, and broadcasts is_paused=true
with prev_block_elapsed_seconds so the TV sidebar stays accurate.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-03 00:09:27 -08:00
derekcandClaude Sonnet 4.6 ca858c2050 Include morning routine in session_update WebSocket broadcast
_broadcast_session was missing morning_routine in its payload, so the
TV dashboard's applySnapshot reset the list to [] whenever a session
started or updated via WebSocket. A page refresh was required to
restore the items since only the REST dashboard endpoint included them.

Now queries MorningRoutineItem via child→user_id and adds the list to
every session_update broadcast, matching the dashboard snapshot.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-01 22:38:46 -08:00
derekcandClaude Sonnet 4.6 f730e9edf9 Show timer remaining per block and fix single-click block switching
- Block list on both dashboards now shows time remaining on each block's
  timer (allocated duration minus elapsed) instead of total duration;
  the active block counts down live every second
- Fix block switching requiring 2 clicks: replace separate pause+start
  requests with a single start request; backend implicitly records a
  pause event for the previous block atomically
- Export blockElapsedCache from store so views can compute per-block
  elapsed for both running and paused blocks

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-01 22:00:23 -08:00
derekcandClaude Sonnet 4.6 a02876c20d Fix double-click to switch blocks and TV elapsed reset
Double-click fix:
- After awaiting the pause, optimistically set current_block_id and
  isPaused on the store so the UI switches instantly. The subsequent
  WS start event confirms the state without requiring a second click.

TV elapsed reset fix:
- The TV's local cache was empty for blocks paused before it connected,
  so returning to those blocks showed 0 elapsed.
- Backend now computes the block's accumulated elapsed from previous
  start/pause cycles and includes it as block_elapsed_seconds in the
  'start' WS event payload.
- All clients (Dashboard and TV) now use this authoritative server value
  instead of relying solely on the local cache.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-01 21:33:36 -08:00
derekcandClaude Sonnet 4.6 37416436ba 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 <[email protected]>
2026-03-01 14:22:07 -08:00
derekcandClaude Sonnet 4.6 80109976bf Reset child strikes to 0 when starting a new day session
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-28 17:21:22 -08:00
derekcandClaude Sonnet 4.6 7346159745 Sort schedule blocks by start time instead of order_index
Backend queries and model relationship now order by time_start.
Frontend also sorts blocks client-side for reliability across all views.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-28 16:22:17 -08:00
derekcandClaude Sonnet 4.6 c9441a9c9a Add subject options and redesign TV dashboard layout
Subject options:
- New subject_options table (auto-created on startup)
- SubjectOut now includes options list; all eager-loading chains updated
- Admin: Options panel per subject with add, inline edit, and delete
- WS broadcast and dashboard API include options in block subject data

TV dashboard:
- Three equal columns: Timer | Activities | Schedule
- Activities column shows current subject's options in large readable text
- Activities area has subject-colored border and tinted background
- Subject name and label displayed correctly using embedded subject data

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-28 11:18:55 -08:00
derekcandClaude Sonnet 4.6 1042c20fbb Fix day progress missing on TV dashboard after session start
The WS broadcast payload was missing day_start_time, day_end_time, and
duration_minutes, so applySnapshot nulled them out on session_update.
Now _broadcast_session fetches the template and includes all fields.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-28 10:30:50 -08:00
derekcandClaude Sonnet 4.6 ad10f9bc61 Fix End Day not updating dashboard without refresh
Broadcast is_active in WS timer payload so the frontend can immediately
clear the session when the backend marks it complete.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-27 23:43:04 -08:00
derekcandClaude Sonnet 4.6 417b3adfe8 Initial project scaffold
Full-stack homeschool web app with FastAPI backend, Vue 3 frontend,
MySQL database, and Docker Compose orchestration. Includes JWT auth,
WebSocket real-time TV dashboard, schedule builder, activity logging,
and multi-child support.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-02-27 22:56:56 -08:00