Remove phase implementation plans, design notes, and source spreadsheet that are no longer needed. Add architecture.md, API_REFERENCE.md, and database_schema.md for ongoing development and debugging reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
203 lines
7.0 KiB
Markdown
203 lines
7.0 KiB
Markdown
# Database Schema
|
|
|
|
SQLite database at `data/sneakyswole.db`, managed by SQLModel ORM with Alembic migrations.
|
|
|
|
---
|
|
|
|
## Tables
|
|
|
|
### `users`
|
|
|
|
User profiles (admin and regular). Admin has login credentials; regular profiles are managed by the admin.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `username` | VARCHAR | UNIQUE, indexed | Login identifier |
|
|
| `password_hash` | VARCHAR | default="" | bcrypt hash (admin only) |
|
|
| `display_name` | VARCHAR | default="" | Name shown in UI |
|
|
| `height` | VARCHAR | nullable | e.g., "6'0\"" |
|
|
| `weight` | VARCHAR | nullable | e.g., "260 lbs" |
|
|
| `goals` | VARCHAR | nullable | Free-text training goals |
|
|
| `is_admin` | BOOLEAN | default=False | Admin privileges flag |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
| `updated_at` | DATETIME | auto | Last update time |
|
|
|
|
**Model:** `app/models/user.py:User`
|
|
|
|
---
|
|
|
|
### `exercises`
|
|
|
|
Exercise library catalog. Each exercise belongs to a workout day.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `name` | VARCHAR | indexed | e.g., "DB Chest Press (Floor)" |
|
|
| `muscle_group` | VARCHAR | default="" | e.g., "Chest", "Shoulders" |
|
|
| `workout_day` | VARCHAR | indexed | "Push", "Pull", "Lower", "Full Body" |
|
|
| `sets` | INTEGER | default=3 | Default number of sets |
|
|
| `tempo` | VARCHAR | default="" | e.g., "3-1-2" (eccentric-pause-concentric) |
|
|
| `form_cues` | VARCHAR | default="" | Detailed form instructions |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
|
|
**Model:** `app/models/exercise.py:Exercise`
|
|
|
|
---
|
|
|
|
### `warmups`
|
|
|
|
Standardized warmup routine displayed before every workout.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `name` | VARCHAR | indexed | e.g., "Cat / Cow" |
|
|
| `type` | VARCHAR | default="" | Category: "Thoracic Mob", "Hip Mobility", etc. |
|
|
| `reps` | VARCHAR | default="" | e.g., "8 reps", "8 each side" |
|
|
| `form_cues` | VARCHAR | default="" | Detailed form instructions |
|
|
| `sort_order` | INTEGER | default=0 | Display order in warmup sequence |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
|
|
**Model:** `app/models/warmup.py:Warmup`
|
|
|
|
---
|
|
|
|
### `workout_days`
|
|
|
|
The 4-day training split definition.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `name` | VARCHAR | UNIQUE, indexed | "Push", "Pull", "Lower", "Full Body" |
|
|
| `day_number` | INTEGER | UNIQUE | Order in rotation (1-4) |
|
|
| `description` | VARCHAR | default="" | Brief focus description |
|
|
|
|
**Model:** `app/models/workout_day.py:WorkoutDay`
|
|
|
|
---
|
|
|
|
### `user_exercise_programs`
|
|
|
|
Per-user programming targets linking users to exercises with week 1/4 goals.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `user_id` | INTEGER | FK → `users.id`, indexed | Profile this applies to |
|
|
| `exercise_id` | INTEGER | FK → `exercises.id`, indexed | Exercise being programmed |
|
|
| `wk1_reps` | VARCHAR | default="" | Week 1 target reps (e.g., "10", "30 sec") |
|
|
| `wk4_reps` | VARCHAR | default="" | Week 4 target reps |
|
|
| `wk1_weight` | VARCHAR | default="" | Week 1 target weight (e.g., "30 lbs", "BW") |
|
|
| `wk4_weight` | VARCHAR | default="" | Week 4 target weight |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
| `updated_at` | DATETIME | auto | Last update time |
|
|
|
|
**Model:** `app/models/user_exercise_program.py:UserExerciseProgram`
|
|
|
|
---
|
|
|
|
### `workout_sessions`
|
|
|
|
A completed workout session — ties a user to a workout day on a date.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `user_id` | INTEGER | FK → `users.id`, indexed | Who did the workout |
|
|
| `workout_day_id` | INTEGER | FK → `workout_days.id` | Which day was trained |
|
|
| `date` | DATE | default=today | Date the workout was performed |
|
|
| `notes` | VARCHAR | nullable | Free-text session notes |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
|
|
**Model:** `app/models/workout_session.py:WorkoutSession`
|
|
|
|
---
|
|
|
|
### `workout_logs`
|
|
|
|
Individual set logs within a session. Each row = one set of one exercise.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `session_id` | INTEGER | FK → `workout_sessions.id`, indexed | Parent session |
|
|
| `exercise_id` | INTEGER | FK → `exercises.id` | Which exercise |
|
|
| `set_number` | INTEGER | default=1 | Set number (1, 2, 3...) |
|
|
| `reps_completed` | INTEGER | default=0 | Actual reps performed |
|
|
| `weight_used` | VARCHAR | default="" | Weight used (e.g., "30 lbs", "BW") |
|
|
| `felt_easy` | BOOLEAN | default=False | Progression signal |
|
|
| `notes` | VARCHAR | nullable | Per-set notes |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
|
|
**Model:** `app/models/workout_log.py:WorkoutLog`
|
|
|
|
---
|
|
|
|
### `progress_log`
|
|
|
|
Progression tracking — what the engine suggested vs what the user actually did.
|
|
|
|
| Column | Type | Constraints | Description |
|
|
|--------|------|------------|-------------|
|
|
| `id` | INTEGER | PK, auto-increment | |
|
|
| `user_id` | INTEGER | FK → `users.id`, indexed | Profile being tracked |
|
|
| `exercise_id` | INTEGER | FK → `exercises.id` | Exercise being tracked |
|
|
| `date` | DATE | default=today | Date of progression entry |
|
|
| `suggested_reps` | INTEGER | nullable | Engine recommendation |
|
|
| `suggested_weight` | VARCHAR | nullable | Engine recommendation |
|
|
| `actual_reps` | INTEGER | nullable | What user actually did |
|
|
| `actual_weight` | VARCHAR | nullable | What user actually used |
|
|
| `progression_applied` | VARCHAR | nullable | Type: "reps_increase", "weight_increase", "deload" |
|
|
| `created_at` | DATETIME | auto | Record creation time |
|
|
|
|
**Model:** `app/models/progress_log.py:ProgressLog`
|
|
|
|
---
|
|
|
|
## Relationships
|
|
|
|
```
|
|
users
|
|
├── user_exercise_programs (1:N via user_id)
|
|
├── workout_sessions (1:N via user_id)
|
|
└── progress_log (1:N via user_id)
|
|
|
|
exercises
|
|
├── user_exercise_programs (1:N via exercise_id)
|
|
├── workout_logs (1:N via exercise_id)
|
|
└── progress_log (1:N via exercise_id)
|
|
|
|
workout_days
|
|
└── workout_sessions (1:N via workout_day_id)
|
|
|
|
workout_sessions
|
|
└── workout_logs (1:N via session_id)
|
|
```
|
|
|
|
---
|
|
|
|
## Migrations
|
|
|
|
Managed by Alembic. Config at `alembic.ini`, migration scripts at `alembic/versions/`.
|
|
|
|
- **Initial migration:** `1855836abf6c_initial_schema_8_tables.py` — creates all 8 tables
|
|
|
|
To create a new migration:
|
|
```bash
|
|
alembic revision --autogenerate -m "description"
|
|
alembic upgrade head
|
|
```
|
|
|
|
---
|
|
|
|
## Seeding
|
|
|
|
On first startup, `SeedService.seed_all()` reads:
|
|
- `config/exercises.yaml` — exercise catalog + warmups + workout days
|
|
- `config/user_programs.yaml` — per-user week 1/4 targets
|
|
|
|
Admin user is created from `ADMIN_USERNAME` / `ADMIN_PASSWORD` env vars with bcrypt hash. Seeding is skipped if data already exists.
|