Add Meeting system subject and notification system

- Auto-create a locked "Meeting" subject for every user on registration
  and seed it for all existing users on startup
- Meeting subject cannot be deleted or renamed (is_system flag)
- 5-minute corner toast warning on Dashboard and TV with live countdown,
  dismiss button, and 1-minute re-notify if dismissed
- At start time: full-screen TV overlay with 30-second auto-dismiss,
  automatic pause of running block, switch to Meeting block, and
  auto-start of Meeting timer
- Web Audio API chimes: rising on warnings, falling at meeting start
- Update README with Meeting subject and notification system docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 23:44:21 -08:00
parent c560055b10
commit f645d78c83
10 changed files with 356 additions and 11 deletions

View File

@@ -11,6 +11,7 @@ from app.auth.jwt import (
)
from app.dependencies import get_db
from app.models.user import User
from app.models.subject import Subject
from app.schemas.auth import LoginRequest, RegisterRequest, TokenResponse
from app.schemas.user import UserOut
@@ -39,6 +40,16 @@ async def register(body: RegisterRequest, response: Response, db: AsyncSession =
await db.commit()
await db.refresh(user)
meeting = Subject(
user_id=user.id,
name="Meeting",
icon="📅",
color="#6366f1",
is_system=True,
)
db.add(meeting)
await db.commit()
access = create_access_token({"sub": str(user.id)})
refresh = create_refresh_token({"sub": str(user.id)})
response.set_cookie(REFRESH_COOKIE, refresh, **COOKIE_OPTS)

View File

@@ -101,6 +101,8 @@ async def delete_subject(
subject = result.scalar_one_or_none()
if not subject:
raise HTTPException(status_code=404, detail="Subject not found")
if subject.is_system:
raise HTTPException(status_code=403, detail="System subjects cannot be deleted")
await db.delete(subject)
await db.commit()