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 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 07:58:30 -07:00
parent d724262e27
commit fdd85d3df5
9 changed files with 246 additions and 17 deletions

View File

@@ -12,6 +12,7 @@ A self-hosted web app for managing homeschool schedules, tracking daily learning
- **Break Activities** — A global list of break-time activities (e.g. "Get a snack", "Go outside") managed in Admin → Break Activities, using the same add/edit/delete interface as Morning Routine. These items are shown on the TV during any active break.
- **Rules & Expectations** — Define a list of household rules or expectations in Admin → Rules & Expectations. Items can be reordered by dragging with the handle on the left. From the Dashboard, press the **Rules/Expectations** button in the Overlays card to show them as a full-screen numbered overlay on the TV. The button turns highlighted with a pulsing **LIVE** badge while the overlay is active. Press it again to dismiss. Tapping anywhere on the TV overlay also dismisses it locally.
- **Dashboard Overlays** — A dedicated card on the parent Dashboard groups controls that push full-screen content to the TV. Currently contains the Rules/Expectations overlay button; designed to accommodate additional overlay types in the future.
- **Block Agenda Override** — Each block in the Today's Schedule card has a 📝 button. Clicking it opens a dialog where you can type a custom activity or note for that block for the current day (e.g. "Chapter 5 reading", "Worksheet page 12"). While an agenda is set, the TV center panel shows that text instead of the block's normal subject options. Agendas are saved per session and automatically forgotten when the day ends — they never carry over to future sessions. The TV updates live via WebSocket as soon as an agenda is saved or cleared.
- **Day Progress Bar** — Both the TV dashboard and the parent dashboard display a progress bar showing how far through the day the child is. Progress is calculated from total scheduled block time vs. remaining block time — not wall-clock time — so it advances only as blocks are actively worked. On the TV the bar is labeled **Start** and **Finish**. On the parent dashboard the left label shows the scheduled start time of the first block and the right label shows a live-updating **estimated finish time** computed as the current time plus all remaining block time and break time for incomplete blocks.
- **Schedule Builder** — Create named schedule templates with time blocks assigned to subjects. Each block supports an optional custom duration override, label, and break time setting. Managed inside the Admin page.
- **Daily Sessions** — Start a school day against a schedule template. Click any block in the list to select it as the current block. Use the **Start** button to begin timing, **Pause** to stop, **Resume** to continue from where you left off, **Done** to mark it as fully complete, and **Reset** to clear the elapsed time back to zero (timer stays paused). Elapsed time per block is remembered across switches, so returning to a block picks up where it left off.
@@ -79,6 +80,7 @@ homeschool/
│ │ ├── morning_routine.py# MorningRoutineItem
│ │ ├── break_activity.py # BreakActivityItem
│ │ ├── rule.py # RuleItem (rules & expectations)
│ │ ├── session_block_agenda.py # SessionBlockAgenda (per-session block overrides)
│ │ ├── strike.py # StrikeEvent (strike history)
│ │ └── user.py # User (incl. timezone, last_active_at)
│ ├── schemas/ # Pydantic request/response schemas
@@ -87,7 +89,7 @@ homeschool/
│ │ ├── children.py # Children CRUD + strikes + midnight reset
│ │ ├── subjects.py
│ │ ├── schedules.py
│ │ ├── sessions.py # Timer actions + break timer events
│ │ ├── sessions.py # Timer actions + break timer events + block agenda upsert
│ │ ├── logs.py # Timeline + strike events
│ │ ├── morning_routine.py
│ │ ├── break_activity.py # Break activities CRUD
@@ -197,7 +199,7 @@ Open **http://localhost:8054/login** and register. This creates your admin accou
| URL | Description |
|-----|-------------|
| `/dashboard` | Overview, start/stop sessions, select and time blocks, issue behavior strikes, trigger TV overlays |
| `/dashboard` | Overview, start/stop sessions, select and time blocks, set per-block agendas, issue behavior strikes, trigger TV overlays |
| `/logs` | Browse timer and strike event history and manual notes; filter by child and date |
| `/admin` | Manage children, subjects (with activity options), morning routine, break activities, rules & expectations, schedule templates, and account settings (timezone, password). Includes a Buy Me a Coffee support link at the top of the page. |
@@ -274,7 +276,7 @@ The TV dashboard connects to `ws://host/ws/{child_id}` and receives JSON events:
| Event | Triggered by | Key payload fields |
|-------|-------------|---------|
| `session_update` | Session start | Full session snapshot including blocks, morning routine, break activities, and day times |
| `session_update` | Session start | Full session snapshot including blocks, morning routine, break activities, block agendas, and day times |
| `start` | Block timer started | `block_id`, `current_block_id`, `block_elapsed_seconds`, `prev_block_id`, `prev_block_elapsed_seconds` |
| `pause` | Block timer paused | `block_id`, `current_block_id` |
| `resume` | Block timer resumed | `block_id`, `current_block_id` |
@@ -287,6 +289,7 @@ The TV dashboard connects to `ws://host/ws/{child_id}` and receives JSON events:
| `strikes_update` | Strike issued/cleared/midnight reset | `strikes` |
| `show_rules` | Rules/Expectations overlay triggered from Dashboard | `rules` (array of rule text strings) |
| `hide_rules` | Rules/Expectations overlay dismissed from Dashboard | — |
| `agenda_update` | Block agenda saved or cleared from Dashboard | `block_id`, `text` (empty string = cleared) |
**Notes:**
@@ -296,6 +299,7 @@ The TV dashboard connects to `ws://host/ws/{child_id}` and receives JSON events:
- `select` events are broadcast via WebSocket but are **not** persisted to the database or shown in the activity log.
- Implicit `pause` events (written when switching blocks or starting a break) are only recorded if the block's timer was actually running — no duplicate pauses are written if the block was already paused or never started.
- Break timer events (`break_*`) do not affect block selection or elapsed time for the main block timer.
- `agenda_update` events are scoped to the current session — agendas are cleared automatically when the session ends and are never carried forward to future days.
---