Add comprehensive README
Covers project overview, tech stack, directory structure, getting started steps, usage guide, dev mode, database migrations, WebSocket events, and environment variable reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
241
README.md
241
README.md
@@ -1,3 +1,240 @@
|
|||||||
# homeschool
|
# Homeschool Dashboard
|
||||||
|
|
||||||
Homeschool Dashboard for tracking day to day learning.
|
A self-hosted web app for managing homeschool schedules, tracking daily learning sessions, and logging activities. Features a full-screen TV dashboard with live timers and real-time updates via WebSockets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **TV Dashboard** — Full-screen display for the living room TV. Shows the current subject, countdown timer, day progress, and upcoming schedule blocks. Updates live without page refresh.
|
||||||
|
- **Schedule Builder** — Create named schedule templates with time blocks assigned to subjects. Assign templates per-child or share across all children.
|
||||||
|
- **Daily Sessions** — Start a school day against a schedule template. Track which blocks are active, paused, or complete.
|
||||||
|
- **Activity Log** — Manually log school activities with subject, duration, and notes. Browse and filter history by date.
|
||||||
|
- **Multi-Child Support** — Manage multiple students under one parent account, each with their own color, schedule, and history.
|
||||||
|
- **JWT Authentication** — Secure parent login with access tokens and httpOnly refresh cookies. TV dashboard is public (no login required).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
| Layer | Technology |
|
||||||
|
|-------|-----------|
|
||||||
|
| Frontend | Vue 3 + Vite + Pinia + Vue Router |
|
||||||
|
| Frontend server | nginx (Docker) |
|
||||||
|
| Backend API | FastAPI (Python 3.12) |
|
||||||
|
| Real-time | WebSockets via FastAPI |
|
||||||
|
| Database | MySQL 8 |
|
||||||
|
| ORM | SQLAlchemy 2.0 (async) |
|
||||||
|
| Migrations | Alembic |
|
||||||
|
| Auth | JWT — python-jose + passlib/bcrypt |
|
||||||
|
| Orchestration | Docker Compose |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
homeschool/
|
||||||
|
├── docker-compose.yml # Production stack (3 services)
|
||||||
|
├── docker-compose.override.yml # Dev overrides (hot reload)
|
||||||
|
├── .env.example # Environment variable template
|
||||||
|
│
|
||||||
|
├── backend/
|
||||||
|
│ ├── Dockerfile
|
||||||
|
│ ├── requirements.txt
|
||||||
|
│ ├── alembic/ # Database migrations
|
||||||
|
│ └── app/
|
||||||
|
│ ├── main.py # FastAPI app entry point
|
||||||
|
│ ├── config.py # Settings (reads from .env)
|
||||||
|
│ ├── database.py # Async SQLAlchemy engine
|
||||||
|
│ ├── dependencies.py # Auth dependencies (get_current_user)
|
||||||
|
│ ├── auth/jwt.py # Token creation, password hashing
|
||||||
|
│ ├── models/ # SQLAlchemy ORM models
|
||||||
|
│ ├── schemas/ # Pydantic request/response schemas
|
||||||
|
│ ├── routers/ # API route handlers
|
||||||
|
│ └── websocket/manager.py # WebSocket connection manager
|
||||||
|
│
|
||||||
|
└── frontend/
|
||||||
|
├── Dockerfile # Multi-stage: Node build → nginx serve
|
||||||
|
├── nginx.conf # Proxy /api/ and /ws/ to backend
|
||||||
|
└── src/
|
||||||
|
├── composables/
|
||||||
|
│ ├── useApi.js # Axios with auto token-refresh
|
||||||
|
│ └── useWebSocket.js # Auto-reconnecting WebSocket
|
||||||
|
├── stores/ # Pinia: auth, children, schedule
|
||||||
|
├── views/ # LoginView, TVView, DashboardView, etc.
|
||||||
|
└── components/ # TimerDisplay, ScheduleBlock, NavBar, etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed
|
||||||
|
- Port `8054` available on the host
|
||||||
|
|
||||||
|
### 1. Clone the repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.chns.tech/CooperandGoodman/homeschool.git
|
||||||
|
cd homeschool
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create your `.env` file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `.env` and fill in the values:
|
||||||
|
|
||||||
|
```env
|
||||||
|
MYSQL_ROOT_PASSWORD=your_secure_root_password
|
||||||
|
MYSQL_DATABASE=homeschool
|
||||||
|
MYSQL_USER=homeschool
|
||||||
|
MYSQL_PASSWORD=your_secure_db_password
|
||||||
|
|
||||||
|
# Generate with: openssl rand -hex 32
|
||||||
|
SECRET_KEY=your_generated_secret_key
|
||||||
|
|
||||||
|
ALGORITHM=HS256
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
|
REFRESH_TOKEN_EXPIRE_DAYS=30
|
||||||
|
|
||||||
|
# Your host IP or domain (no trailing slash)
|
||||||
|
CORS_ORIGINS=http://localhost:8054
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Build and start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
The first build takes a few minutes (npm install + pip install). On subsequent starts it's fast.
|
||||||
|
|
||||||
|
### 4. Register your parent account
|
||||||
|
|
||||||
|
Open **http://localhost:8054/login** and register. This creates your admin account.
|
||||||
|
|
||||||
|
### 5. Set up your data (in order)
|
||||||
|
|
||||||
|
1. **Admin** (`/admin`) → Add each child, pick a color
|
||||||
|
2. **Admin** → Add subjects (Math, Reading, Science, etc.) with emoji icons and colors
|
||||||
|
3. **Schedules** (`/schedules`) → Create a schedule template, add time blocks assigned to subjects
|
||||||
|
4. **Dashboard** (`/dashboard`) → Click "Start Day", choose a template
|
||||||
|
5. **TV** → Open `http://your-lan-ip:8054/tv/1` on the living room TV (replace `1` with the child's ID)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Parent Views (require login)
|
||||||
|
|
||||||
|
| URL | Description |
|
||||||
|
|-----|-------------|
|
||||||
|
| `/dashboard` | Overview, start/stop sessions, timer controls, link to TV view |
|
||||||
|
| `/schedules` | Create and edit schedule templates and time blocks |
|
||||||
|
| `/logs` | Browse and add activity log entries |
|
||||||
|
| `/admin` | Manage children and subjects |
|
||||||
|
|
||||||
|
### TV Dashboard (no login)
|
||||||
|
|
||||||
|
| URL | Description |
|
||||||
|
|-----|-------------|
|
||||||
|
| `/tv/:childId` | Full-screen display — current block, countdown timer, day progress |
|
||||||
|
|
||||||
|
Point a browser on the living room TV at `http://your-lan-ip:8054/tv/1`. The page connects via WebSocket and updates automatically when a parent starts/stops/advances the timer from the Dashboard.
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
|
||||||
|
FastAPI auto-generates interactive API docs:
|
||||||
|
|
||||||
|
- **Swagger UI** — `http://localhost:8054/api/docs`
|
||||||
|
- **ReDoc** — `http://localhost:8054/api/redoc`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development Mode
|
||||||
|
|
||||||
|
The `docker-compose.override.yml` file enables hot reload automatically when running locally:
|
||||||
|
|
||||||
|
- **Backend** — uvicorn `--reload` watches `backend/app/` for changes
|
||||||
|
- **Frontend** — Vite HMR on port `5173` (mapped to `8054` in dev mode)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up --build # override is applied automatically in dev
|
||||||
|
```
|
||||||
|
|
||||||
|
To run production mode explicitly (no hot reload):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Migrations
|
||||||
|
|
||||||
|
Alembic is configured for async SQLAlchemy migrations.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate a new migration after changing models
|
||||||
|
docker compose exec backend alembic revision --autogenerate -m "description"
|
||||||
|
|
||||||
|
# Apply pending migrations
|
||||||
|
docker compose exec backend alembic upgrade head
|
||||||
|
|
||||||
|
# Roll back one migration
|
||||||
|
docker compose exec backend alembic downgrade -1
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** On first startup the app auto-creates all tables via SQLAlchemy's `create_all`. Alembic is used for schema changes after the initial setup.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WebSocket Events
|
||||||
|
|
||||||
|
The TV dashboard connects to `ws://host/ws/{child_id}` and receives JSON events:
|
||||||
|
|
||||||
|
| Event | Triggered by | Payload |
|
||||||
|
|-------|-------------|---------|
|
||||||
|
| `session_update` | Session start/end | Full session snapshot |
|
||||||
|
| `start` | Timer started | `session_id`, `block_id`, `current_block_id` |
|
||||||
|
| `pause` | Timer paused | `session_id`, `block_id` |
|
||||||
|
| `resume` | Timer resumed | `session_id`, `block_id` |
|
||||||
|
| `complete` | Block completed | `session_id`, `block_id` |
|
||||||
|
| `skip` | Block skipped | `session_id`, `block_id` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Variables Reference
|
||||||
|
|
||||||
|
| Variable | Required | Description |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| `MYSQL_ROOT_PASSWORD` | Yes | MySQL root password |
|
||||||
|
| `MYSQL_DATABASE` | Yes | Database name (default: `homeschool`) |
|
||||||
|
| `MYSQL_USER` | Yes | App database user |
|
||||||
|
| `MYSQL_PASSWORD` | Yes | App database password |
|
||||||
|
| `SECRET_KEY` | Yes | JWT signing key — generate with `openssl rand -hex 32` |
|
||||||
|
| `ALGORITHM` | No | JWT algorithm (default: `HS256`) |
|
||||||
|
| `ACCESS_TOKEN_EXPIRE_MINUTES` | No | Access token lifetime (default: `30`) |
|
||||||
|
| `REFRESH_TOKEN_EXPIRE_DAYS` | No | Refresh token lifetime (default: `30`) |
|
||||||
|
| `CORS_ORIGINS` | No | Comma-separated allowed origins (default: `http://localhost:8054`) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stopping and Restarting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop containers (data preserved in Docker volume)
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Stop and wipe the database volume (full reset)
|
||||||
|
docker compose down -v
|
||||||
|
|
||||||
|
# Restart without rebuilding
|
||||||
|
docker compose up
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user