feat: initial project setup with roadmap, exercise data, and docs

Establish SneakySwole project foundation:
- CLAUDE.md with project overview, stack, and development guidelines
- 5-phase roadmap (scaffold, data layer, workout UI, logging, progression)
- Exercise library YAML with 6 warmups and 20 exercises (form cues, tempo, sets)
- User programs YAML with week 1/4 targets for Phillip and Daughter
- Design doc capturing roadmap, data, and auth model decisions
- Code guidelines, security standards, and .gitignore
- Source workout spreadsheet (workout_plan_v2.xlsx)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 21:55:31 -06:00
commit 3f7ce965e1
10 changed files with 1010 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
# Python
__pycache__/
*.py[cod]
*.pyo
*.egg-info/
dist/
build/
*.egg
# Virtual environments
.venv/
venv/
# Environment variables
.env
# SQLite database
data/*.db
data/*.db-journal
data/*.db-wal
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Docker
docker-compose.override.yaml
# Testing
.pytest_cache/
.coverage
htmlcov/

119
CLAUDE.md Normal file
View File

@@ -0,0 +1,119 @@
# CLAUDE.md
## Project Overview
**Purpose:** SneakySwole — an open-source workout tracking and programming app
**Technologies:** Python, FastAPI, SQLite3, HTMX, Pico CSS (dark theme), Docker
**Description:** A lightweight, open-source workout platform built with FastAPI on the backend,
HTMX for dynamic frontend interactions (no heavy JS framework), SQLite3 for local/embedded
data storage, and a dark-themed UI lightly based on Pico CSS. Fully containerized via Docker
for easy self-hosting. Designed to be self-hostable, simple to contribute to, and easy to extend.
**GitHub handle:** sneakygeek (not sneakyllc)
---
## Development Guidelines
### Project Structure
I prefer to have my source in `app`, not `src`.
I prefer **centralizing common logic** such as HTTP wrappers, logging handlers, validators, etc.
I like keeping things **modular**, with:
* `/app/services/...` — business logic, workout plans, progression calculations
* `/app/utils/...` — shared helpers, formatters, validators
* `/app/models/...` — SQLite/SQLModel schema definitions
* `/app/routes/...` — FastAPI route handlers (one file per domain)
* `/app/templates/...` — Jinja2 HTML templates (HTMX-friendly, partial-first)
* `/app/static/...` — CSS overrides, minimal JS, any static assets
* `Dockerfile` — container image definition
* `docker-compose.yaml` — primary way to run the app locally and in production
* `data/` — SQLite DB lives here (gitignored, persisted via Docker volume)
* Typed config loaders
* YAML-driven config structures
### Tech Stack Specifics
#### Backend
- **FastAPI** — all API and page routes
- **SQLite3** via the standard library or **SQLModel** for ORM if needed
- Keep DB access in `/app/services/` — never query the DB directly from routes
- Use **Alembic** for migrations even with SQLite (keeps things portable)
#### Frontend
- **HTMX** for all dynamic interactions — avoid writing vanilla JS unless absolutely necessary
- Prefer `hx-get` / `hx-post` with **partial HTML responses** (template fragments), not JSON
- **Pico CSS** as the base — dark theme via `data-theme="dark"` on `<html>`
- Custom overrides in `/app/static/css/sneakyswole.css` — keep Pico mostly untouched
- Templates use **Jinja2** (built into FastAPI via `Jinja2Templates`)
- Design should feel clean and gym-appropriate — dark, bold, minimal
#### Database
- **SQLite3** — single file DB, ideal for self-hosted / local use
- DB file lives at `data/sneakyswole.db` (excluded from git, gitignored)
- Schema covers: users, exercises, workouts, workout_days, sets, progress_log
- Seed data for default exercise library (from the spreadsheet program)
#### Docker
- Project is fully containerized — `Dockerfile` at the project root
- **`docker-compose.yaml`** at the project root is the primary way to run the app
- The `data/` directory (SQLite DB) is mounted as a **named volume** so data persists across container restarts
- Static files and templates are baked into the image — no bind mounts needed in production
- `.env` file is used for environment config (never committed); `docker-compose.yaml` references it via `env_file`
- Typical compose setup: single `app` service, port `8000` exposed, volume for `data/`
- Keep the image lean — use a slim Python base image (e.g. `python:3.12-slim`)
### Coding Standards
I often follow a pattern **brainstorm → design → code → revise** and like that flow.
Reference `docs/code_guidelines.md` for code standards and rules.
### Security Standards
Reference `docs/security.md` for security guidance and standards.
---
## ⚠️ CLAUDE WORKSPACE BELOW ⚠️
**The sections above define my development preferences and standards.**
**Everything below this line is working context for Claude to track project-specific information, decisions, and progress.**
---
## Claude Context & Project Notes
### Project Context
- Open-source project under the **sneakygeek** GitHub account
- Workout program based on a 4-day split: Push / Pull / Lower / Full Body
- Two user profiles initially: Phillip (260 lbs, 6'0", bulging disc) and Daughter (140 lbs, 5'8")
- Equipment: 2x adjustable dumbbells up to 55 lbs each + bodyweight
- Progression model: +1-2 reps/week, +5 lbs every 2 weeks, deload at week 5
- Warmup is standardized (Cat/Cow, Fire Hydrant, Thoracic Rotation/Extension, etc.)
- Each exercise has full form cues stored in the DB
- The spreadsheet (`workout_plan_v2.xlsx`) is the source of truth for the initial exercise seed data
### Core Features (Planned)
- [ ] User profiles with stats (weight, height, equipment)
- [ ] Workout day viewer (warmup + main workout)
- [ ] Per-exercise logging (sets, reps, weight, felt easy?)
- [ ] Auto-progression suggestions based on log history
- [ ] Exercise library with full form cues
- [ ] 4-week schedule view
- [ ] Progress log with history
- [ ] Dark UI, mobile-friendly
### Implementation Notes
<!-- Claude can track TODOs, known issues, technical debt, or areas needing attention -->
### Session History
<!-- Claude can maintain a log of significant changes or milestones -->
- **2026-02-23** — Project named SneakySwole. Stack finalized: FastAPI + SQLite3 + HTMX + Pico CSS dark theme + Docker (docker-compose.yaml). Workout program designed (4-day split, warmup routine, progressive overload model). Spreadsheet v2 completed with full form cues for all exercises.
### Active Tasks & Notes
<!-- Current work, blockers, reminders -->
- Set up initial FastAPI project scaffold
- Write `Dockerfile` and `docker-compose.yaml`
- Design SQLite schema based on workout spreadsheet structure
- Build Jinja2 base template with Pico dark theme
- Seed exercise library from spreadsheet data
### Change Log
<!-- Significant updates, refactors, or milestones -->
- **2026-02-23** — Initial CLAUDE.md created. Project overview, stack, and structure defined.

297
config/exercises.yaml Normal file
View File

@@ -0,0 +1,297 @@
# SneakySwole Exercise Library
# Source of truth for all exercises and warmups.
# Update this file to add/modify exercises, then re-run the seed script.
warmup:
- name: "Cat / Cow"
type: "Thoracic Mob"
reps: "8 reps"
form_cues: >
Start on hands and knees. For Cat: exhale and round your entire spine toward the ceiling,
tucking chin and pelvis. For Cow: inhale and let your belly drop toward the floor, lifting
your head and tailbone. Move slowly, one vertebra at a time.
- name: "Fire Hydrant"
type: "Hip Mobility"
reps: "8 each side"
form_cues: >
Stay on hands and knees. Keeping your knee bent at 90 degrees, lift one knee out to the
side like a dog at a fire hydrant. Keep your hips square — don't rotate your torso. Pause
at the top, lower slowly. Complete all reps on one side, then switch.
- name: "Thoracic Rotation"
type: "Thoracic Mob"
reps: "8 each side"
form_cues: >
Sit on the floor or a chair. Place one hand behind your head, elbow pointing out. Rotate
your upper back (not your hips) to open that elbow toward the ceiling. Think: 'rotate my
ribcage, not my lower back.' Hold 1 sec at end range, return slowly.
- name: "Thoracic Extension"
type: "Thoracic Mob"
reps: "8 reps"
form_cues: >
Sit in a chair. Clasp hands behind your head. Gently lean back over the top of the chair
back so your upper spine extends (arches) over it. Only the upper back moves — do NOT
hyperextend your neck or lower back. Hold 2 sec, return. Alternatively, use a foam roller
on the floor.
- name: "Glute Bridge"
type: "Glute Activation"
reps: "10 reps, 2s hold"
form_cues: >
Lie on your back, knees bent, feet flat on floor hip-width apart. Press through your heels
and squeeze your glutes to lift your hips until your body forms a straight line from knees
to shoulders. Hold 2 seconds at the top — really squeeze. Lower slowly. This is also a
gentle lumbar stabilizer.
- name: "World's Greatest Stretch"
type: "Full Body"
reps: "5 each side"
form_cues: >
Step into a deep lunge. Plant both hands inside your front foot. Drop your back knee to
the ground. Then rotate your top arm toward the ceiling, following it with your eyes. Hold
2 sec, return. Then straighten your front leg slightly for a hamstring stretch. This hits
hips, thoracic spine, hamstrings — all in one move.
exercises:
# Day 1 — Push
- name: "DB Chest Press (Floor)"
muscle_group: "Chest"
workout_day: "Push"
sets: 3
tempo: "3-1-2"
form_cues: >
Lie on the floor, knees bent, a dumbbell in each hand. Start with elbows at 90 degrees
and upper arms resting on the floor. Press both dumbbells straight up until arms are fully
extended above your chest — don't let them drift toward your face. Lower slowly until your
upper arms touch the floor again. Floor limits range of motion and protects shoulders. Keep
core braced throughout.
- name: "DB Shoulder Press (Seated)"
muscle_group: "Shoulders"
workout_day: "Push"
sets: 3
tempo: "3-1-2"
form_cues: >
Sit upright on a chair or bench with back supported. Hold a dumbbell in each hand at
shoulder height, palms facing forward, elbows at 90 degrees. Press both dumbbells directly
overhead until arms are fully extended — avoid locking elbows hard. Lower slowly back to
shoulder height. Keep your lower back pressed into the seat — do NOT arch your back. Seated
position removes spinal compression risk.
- name: "DB Lateral Raise"
muscle_group: "Shoulders"
workout_day: "Push"
sets: 3
tempo: "2-1-3"
form_cues: >
Stand with feet hip-width apart, a dumbbell in each hand at your sides, slight bend in
elbows. Raise both arms out to the sides until they reach shoulder height — like a T shape.
Your thumbs should be pointing slightly downward (tilt the 'pitcher'). Pause 1 sec at the
top. Lower slowly — resist gravity on the way down. Avoid shrugging your shoulders up.
- name: "Push-Up (Incline if needed)"
muscle_group: "Chest/Triceps"
workout_day: "Push"
sets: 3
tempo: "3-1-2"
form_cues: >
Place hands slightly wider than shoulder-width, fingers pointing forward. Body forms a
straight line from head to heels — do not let hips sag or pike up. Lower your chest toward
the floor by bending your elbows at a 45 degree angle from your body (not flared out). Pause
when chest is 1-2 inches from floor, then press back up. For incline: place hands on a chair
or countertop to reduce load.
- name: "DB Tricep Overhead Ext."
muscle_group: "Triceps"
workout_day: "Push"
sets: 3
tempo: "3-1-2"
form_cues: >
Sit or stand holding one dumbbell with both hands overhead, arms extended. Bend only at
the elbows to lower the dumbbell behind your head — keep your upper arms stationary and
pointed straight up. Lower until you feel a stretch in your triceps, then extend back to
start. Keep elbows close together; don't let them flare wide.
# Day 2 — Pull
- name: "DB Bent-Over Row (Supported)"
muscle_group: "Upper Back"
workout_day: "Pull"
sets: 3
tempo: "3-1-2"
form_cues: >
Place one knee and same-side hand on a bench for support, back flat and parallel to the
floor. Hold a dumbbell in your free hand hanging straight down. Pull the dumbbell up by
driving your elbow toward the ceiling — think 'pull your elbow to your back pocket.'
Squeeze your shoulder blade at the top for 1 sec. Lower slowly. Keep back completely
flat — no twisting or rotating.
- name: "DB Rear Delt Fly"
muscle_group: "Rear Delt"
workout_day: "Pull"
sets: 3
tempo: "2-1-3"
form_cues: >
Hinge forward at the hips about 45 degrees (like you're bowing), knees soft, back flat.
Hold a light dumbbell in each hand hanging below you, slight bend in elbows. Raise both
arms out to the sides — like opening wings — until they're at shoulder height. Lead with
your elbows, not your hands. Squeeze shoulder blades together at the top. Lower slowly.
Keep back flat throughout.
- name: "DB Hammer Curl"
muscle_group: "Biceps"
workout_day: "Pull"
sets: 3
tempo: "2-1-3"
form_cues: >
Same as a regular curl but palms face each other (neutral/hammer grip) throughout the
entire movement. Elbows stay pinned to your sides. Curl up, squeeze at the top, lower
slowly. This hits the brachialis (deeper bicep muscle) and forearm more than a regular
curl. Great grip builder.
- name: "DB Bicep Curl"
muscle_group: "Biceps"
workout_day: "Pull"
sets: 3
tempo: "2-1-3"
form_cues: >
Stand with feet hip-width apart, a dumbbell in each hand, palms facing forward, arms
fully extended. Keeping your upper arms pinned against your sides (elbows don't move!),
curl both dumbbells up toward your shoulders by contracting your biceps. Pause at the top
and squeeze for 1 sec. Lower slowly — 3 full seconds down. Do not swing your torso or
use momentum.
- name: "DB Shrug"
muscle_group: "Traps"
workout_day: "Pull"
sets: 3
tempo: "2-2-2"
form_cues: >
Stand holding a dumbbell in each hand at your sides, arms straight. Elevate (shrug) both
shoulders straight up toward your ears as high as they'll go — do NOT roll them forward or
backward, just straight up. Hold 2 sec at the top. Lower slowly. No rolling — rolling
actually reduces activation and can irritate the joint.
# Day 3 — Lower
- name: "Goblet Squat (DB)"
muscle_group: "Quads/Glutes"
workout_day: "Lower"
sets: 3
tempo: "3-1-2"
form_cues: >
Hold one dumbbell vertically at chest height with both hands cupped under the top weight.
Stand feet shoulder-width apart, toes slightly out. Push your knees out and sit your hips
DOWN and BACK — not just down. Descend until thighs are parallel to the floor or as low
as comfortable without rounding your lower back. Drive through your heels to stand. The
dumbbell at your chest acts as a counterbalance, making this the safest squat for disc
health.
- name: "Romanian Deadlift (DB)"
muscle_group: "Hamstrings"
workout_day: "Lower"
sets: 3
tempo: "3-1-2"
form_cues: >
Stand holding a dumbbell in each hand in front of your thighs, palms facing you. Soft
bend in knees (slight, not a squat). Hinge at the hips — push your hips straight BACK as
you lower the dumbbells down your legs. Keep the weights close to your body (they should
slide down your legs). Lower until you feel a stretch in your hamstrings (usually mid-shin),
then drive your hips forward to return to standing. STOP if you feel pain — lower back
must stay flat.
- name: "Reverse Lunge (DB)"
muscle_group: "Quads/Glutes"
workout_day: "Lower"
sets: 3
tempo: "3-1-2"
form_cues: >
Stand holding a dumbbell in each hand. Step one foot directly BEHIND you (not to the side)
and lower your back knee toward the floor, stopping 1-2 inches above ground. Front shin
stays vertical. Push through your front heel to return to standing. Step back is safer than
forward for the knee and puts less demand on the lower back. Alternate legs or complete all
reps on one side.
- name: "Glute Bridge (DB on hips)"
muscle_group: "Glutes"
workout_day: "Lower"
sets: 3
tempo: "2-2-1"
form_cues: >
Lie on your back, knees bent, feet flat, hip-width apart. Place a dumbbell across your
hips and hold it in place with both hands. Press through your heels and squeeze your glutes
hard to lift your hips until your body is in a straight line from knees to shoulders. At
the top, really hold and squeeze for 2 sec. Lower slowly. This is one of the best exercises
for building the glutes while being completely safe for the lower back.
- name: "Standing Calf Raise (DB)"
muscle_group: "Calves"
workout_day: "Lower"
sets: 3
tempo: "2-1-3"
form_cues: >
Stand holding a dumbbell in each hand, feet hip-width apart. Rise up onto the balls of
your feet as high as you can go — full extension. Hold 1 sec at the top. Lower slowly
until your heels are back on the floor (or slightly lower if standing on a step). Use a
wall for balance. Controlled tempo builds more calf than bouncing.
# Day 4 — Full Body
- name: "DB Thruster (Squat + Press)"
muscle_group: "Full Body"
workout_day: "Full Body"
sets: 3
tempo: "3-1-2"
form_cues: >
Hold a dumbbell in each hand at shoulder height, palms facing inward. Perform a
goblet-style squat: push hips back and down. As you drive back up to standing, use that
momentum to press both dumbbells directly overhead until arms are extended. Lower the
weights back to shoulders as you begin the next squat. One fluid movement: squat DOWN,
stand UP, press OVERHEAD. A full-body calorie burner.
- name: "DB Renegade Row"
muscle_group: "Back/Core"
workout_day: "Full Body"
sets: 3
tempo: "2-1-2"
form_cues: >
Get into a push-up position with a dumbbell in each hand (handles on the floor). Feet
wider than normal for stability. Keeping your hips square to the floor, row one dumbbell
up by driving your elbow toward the ceiling. Lower it, then row the other side. Don't
rotate your hips — brace your core like you're about to take a punch. This is a plank
+ row combined.
- name: "DB Rev. Lunge + Curl"
muscle_group: "Legs/Biceps"
workout_day: "Full Body"
sets: 3
tempo: "3-1-2"
form_cues: >
Hold a dumbbell in each hand, arms at your sides. Step one foot back into a reverse
lunge. As you lower into the lunge, simultaneously curl both dumbbells up to your
shoulders. Press back to standing and lower the dumbbells. This trains coordination,
balance, biceps, and legs in one efficient movement.
- name: "Dead Bug (BW)"
muscle_group: "Core/Stability"
workout_day: "Full Body"
sets: 3
tempo: "Slow"
form_cues: >
Lie on your back. Raise both arms straight up toward the ceiling. Raise both knees to
90 degrees (table-top position). Brace your core — press your lower back FLAT into the
floor. Now slowly lower your RIGHT arm overhead AND your LEFT leg toward the floor at
the same time. Stop before either touches the floor (or before your back arches). Return
and repeat with LEFT arm + RIGHT leg. This is the best core exercise for disc health
because it trains stability without spinal flexion.
- name: "DB Farmer's Carry"
muscle_group: "Full Body"
workout_day: "Full Body"
sets: 3
tempo: "Walk"
form_cues: >
Hold a heavy dumbbell in each hand at your sides. Stand tall — shoulders back, chest up,
core braced. Walk forward in a straight line at a steady pace. Keep your gaze forward and
avoid leaning to either side. Stop, set the weights down with control. This trains grip
strength, core stability, and full-body endurance simultaneously. One of the most
functional exercises you can do.

232
config/user_programs.yaml Normal file
View File

@@ -0,0 +1,232 @@
# SneakySwole User Programs
# Per-user exercise programming with week 1 and week 4 targets.
# Update this file to adjust programming, then re-run the seed script.
programs:
- user: "Phillip"
profile:
height: "6'0\""
weight: "260 lbs"
goals: "Fat loss, muscle build, back-safe movements"
exercises:
# Day 1 — Push
- name: "DB Chest Press (Floor)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "30 lbs"
wk4_weight: "40 lbs"
- name: "DB Shoulder Press (Seated)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
- name: "DB Lateral Raise"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "10 lbs"
wk4_weight: "15 lbs"
- name: "Push-Up (Incline if needed)"
wk1_reps: 6
wk4_reps: 15
wk1_weight: "BW"
wk4_weight: "BW"
- name: "DB Tricep Overhead Ext."
wk1_reps: 10
wk4_reps: 15
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
# Day 2 — Pull
- name: "DB Bent-Over Row (Supported)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "30 lbs"
wk4_weight: "45 lbs"
- name: "DB Rear Delt Fly"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "10 lbs"
wk4_weight: "15 lbs"
- name: "DB Hammer Curl"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
- name: "DB Bicep Curl"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
- name: "DB Shrug"
wk1_reps: 12
wk4_reps: 15
wk1_weight: "35 lbs"
wk4_weight: "50 lbs"
# Day 3 — Lower
- name: "Goblet Squat (DB)"
wk1_reps: 8
wk4_reps: 15
wk1_weight: "25 lbs"
wk4_weight: "40 lbs"
- name: "Romanian Deadlift (DB)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "25 lbs"
wk4_weight: "40 lbs"
- name: "Reverse Lunge (DB)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "Glute Bridge (DB on hips)"
wk1_reps: 12
wk4_reps: 20
wk1_weight: "25 lbs"
wk4_weight: "40 lbs"
- name: "Standing Calf Raise (DB)"
wk1_reps: 15
wk4_reps: 25
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
# Day 4 — Full Body
- name: "DB Thruster (Squat + Press)"
wk1_reps: 6
wk4_reps: 10
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
- name: "DB Renegade Row"
wk1_reps: 6
wk4_reps: 10
wk1_weight: "20 lbs"
wk4_weight: "30 lbs"
- name: "DB Rev. Lunge + Curl"
wk1_reps: 6
wk4_reps: 10
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "Dead Bug (BW)"
wk1_reps: 6
wk4_reps: 10
wk1_weight: "BW"
wk4_weight: "BW"
- name: "DB Farmer's Carry"
wk1_reps: "30 sec"
wk4_reps: "45 sec"
wk1_weight: "30 lbs"
wk4_weight: "45 lbs"
- user: "Daughter"
profile:
height: "5'8\""
weight: "140 lbs"
goals: "Toning, strength, general fitness"
exercises:
# Day 1 — Push
- name: "DB Chest Press (Floor)"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "DB Shoulder Press (Seated)"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "DB Lateral Raise"
wk1_reps: 12
wk4_reps: 18
wk1_weight: "8 lbs"
wk4_weight: "12 lbs"
- name: "Push-Up (Incline if needed)"
wk1_reps: 8
wk4_reps: 20
wk1_weight: "BW"
wk4_weight: "BW"
- name: "DB Tricep Overhead Ext."
wk1_reps: 12
wk4_reps: 18
wk1_weight: "8 lbs"
wk4_weight: "15 lbs"
# Day 2 — Pull
- name: "DB Bent-Over Row (Supported)"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "DB Rear Delt Fly"
wk1_reps: 12
wk4_reps: 18
wk1_weight: "8 lbs"
wk4_weight: "12 lbs"
- name: "DB Hammer Curl"
wk1_reps: 12
wk4_reps: 18
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "DB Bicep Curl"
wk1_reps: 12
wk4_reps: 18
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "DB Shrug"
wk1_reps: 12
wk4_reps: 18
wk1_weight: "20 lbs"
wk4_weight: "35 lbs"
# Day 3 — Lower
- name: "Goblet Squat (DB)"
wk1_reps: 12
wk4_reps: 20
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "Romanian Deadlift (DB)"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
- name: "Reverse Lunge (DB)"
wk1_reps: 10
wk4_reps: 15
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "Glute Bridge (DB on hips)"
wk1_reps: 15
wk4_reps: 25
wk1_weight: "15 lbs"
wk4_weight: "30 lbs"
- name: "Standing Calf Raise (DB)"
wk1_reps: 20
wk4_reps: 30
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"
# Day 4 — Full Body
- name: "DB Thruster (Squat + Press)"
wk1_reps: 8
wk4_reps: 15
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "DB Renegade Row"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "10 lbs"
wk4_weight: "20 lbs"
- name: "DB Rev. Lunge + Curl"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "10 lbs"
wk4_weight: "18 lbs"
- name: "Dead Bug (BW)"
wk1_reps: 8
wk4_reps: 12
wk1_weight: "BW"
wk4_weight: "BW"
- name: "DB Farmer's Carry"
wk1_reps: "30 sec"
wk4_reps: "45 sec"
wk1_weight: "15 lbs"
wk4_weight: "25 lbs"

22
docs/CLAUDE.md Normal file
View File

@@ -0,0 +1,22 @@
# Documentation Folder
This folder contains business planning, architecture decisions, and documentation.
**No application code belongs here.**
## Contents
| Document | Purpose |
|----------|---------|
| `code_guidelines.md` | Code creation guidelines and Git strategy |
| `security.md` | Python focused security code suggestions |
| `roadmap.md` | 5-phase development roadmap |
| `plans/` | Design documents and implementation plans |
## Guidelines
- Keep documents focused and concise
- Update docs when architecture decisions change
- Use markdown tables for structured information
- Include links to external documentation where relevant

120
docs/code_guidelines.md Normal file
View File

@@ -0,0 +1,120 @@
### Coding Standards
**Style & Structure**
- Prefer longer, explicit code over compact one-liners
- Always include docstrings for functions/classes + inline comments
- Strongly prefer OOP-style code (classes over functional/nested functions)
- Strong typing throughout (dataclasses, TypedDict, Enums, type hints)
- Value future-proofing and expanded usage insights
**Data Design**
- Use dataclasses for internal data modeling
- Typed JSON structures
- Functions return fully typed objects (no loose dicts)
- Snapshot files in JSON or YAML
- Human-readable fields (e.g., `scan_duration`)
**Templates & UI**
- Don't mix large HTML/CSS blocks in Python code
- Prefer Jinja templates for HTML rendering
- Clean CSS, minimal inline clutter, readable template logic
**Writing & Documentation**
- Markdown documentation
- Clear section headers
- Roadmap/Phase/Feature-Session style documents
- Boilerplate templates first, then refinements
**Logging**
- Use structlog (pip package)
- Setup logging at app start: `logger = logging.get_logger(__file__)`
**Preferred Pip Packages**
- API/Web Server: Flask
- HTTP: Requests
- Logging: Structlog
- Scheduling: APScheduler
### Error Handling
- Custom exception classes for domain-specific errors
- Consistent error response formats (JSON structure)
- Logging severity levels (ERROR vs WARNING)
### Configuration
- Each component has environment-specific configs in its own `/config/*.yaml`
- API: `/api/config/development.yaml`, `/api/config/production.yaml`
- Web: `/public_web/config/development.yaml`, `/public_web/config/production.yaml`
- `.env` for secrets (never committed)
- Maintain `.env.example` in each component for documentation
- Typed config loaders using dataclasses
- Validation on startup
### Containerization & Deployment
- Explicit Dockerfiles
- Production-friendly hardening (distroless/slim when meaningful)
- Clear build/push scripts that:
- Use git branch as tag
- Ask whether to tag `:latest`
- Ask whether to push
- Support private registries
### API Design
- RESTful conventions
- Versioning strategy (`/api/v1/...`)
- Standardized response format:
```json
{
"app": "<APP NAME>",
"version": "<APP VERSION>",
"status": <HTTP STATUS CODE>,
"timestamp": "<UTC ISO8601>",
"request_id": "<optional request id>",
"result": <data OR null>,
"error": {
"code": "<optional machine code>",
"message": "<human message>",
"details": {}
},
"meta": {}
}
```
### Dependency Management
- Use `requirements.txt` and virtual environments (`python3 -m venv venv`)
- Use path `venv` for all virtual environments
- Pin versions to version ranges
- Activate venv before running code (unless in Docker)
### Testing Standards
- Manual testing preferred for applications
- **API Backend:** Maintain `api/docs/API_TESTING.md` with endpoint examples, curl/httpie commands, expected responses
- **Unit tests:** Use pytest for API backend (`api/tests/`)
- **Web Frontend:** If using a web frontend, Manual testing checklist are created in `public_web/docs`
### Git Standards
**Branch Strategy:**
- `master` - Production-ready code only
- `dev` - Main development branch, integration point
- `beta` - (Optional) Public pre-release testing
**Workflow:**
- Feature work branches off `dev` (e.g., `feature/add-scheduler`)
- Merge features back to `dev` for testing
- Promote `dev``beta` for public testing (when applicable)
- Promote `beta` (or `dev`) → `master` for production
**Commit Messages:**
- Use conventional commit format: `feat:`, `fix:`, `docs:`, `refactor:`, etc.
- Keep commits atomic and focused
- Write clear, descriptive messages
**Tagging:**
- Tag releases on `master` with semantic versioning (e.g., `v1.2.3`)
- Optionally tag beta releases (e.g., `v1.2.3-beta.1`)
---
## Workflow Preference
I follow a pattern: **brainstorm → design → code → revise**

View File

@@ -0,0 +1,76 @@
# Design: Roadmap, Exercise Data, and Auth Model
**Date:** 2026-02-23
**Status:** Approved
## Overview
This document captures the design decisions for the SneakySwole roadmap structure, exercise data management, and authentication model.
## Roadmap Structure
Five phases, each producing a testable milestone:
1. **Scaffold & Infrastructure** — project structure, Docker, base template, logging
2. **Data Layer & Seeding** — SQLite schema, Alembic migrations, YAML-based exercise/program seeding
3. **Workout UI** — admin auth, profile management, workout viewer, exercise browser
4. **Logging & Tracking** — per-exercise logging, session tracking, log history
5. **Progression & Analytics** — auto-progression, schedule view, progress dashboard
Full details in `docs/roadmap.md`.
## Exercise Data Design
### Separated YAML Files
Exercise data is split into two config files for clean separation of concerns:
- **`config/exercises.yaml`** — Universal exercise library
- Exercise name, muscle group, workout day, sets, tempo, form cues
- Warmup exercises (name, type, reps/time, form cues)
- Rarely changes; defines the available exercise catalog
- **`config/user_programs.yaml`** — Per-user programming
- References exercises by name
- Week 1 and week 4 reps and weights per user per exercise
- Changes when users adjust their programming or new users are added
### Seeding Flow
1. On first run (empty DB), the seed script reads both YAML files
2. Exercises and warmups are inserted into their respective tables
3. User profiles are created (admin from `.env`, others from user_programs.yaml)
4. User-specific programming (reps/weights) is linked to exercises and users
5. Subsequent runs skip seeding if data already exists
### Why YAML Over Spreadsheet
- Human-readable and version-controllable
- Easy to update without special tools
- Can be validated with schema checks
- Spreadsheet remains source of truth for initial data extraction only
## Authentication Model
### Phase 1: Simple Admin Auth
- Single admin user with credentials stored in `.env` (`ADMIN_USERNAME`, `ADMIN_PASSWORD`)
- On first run, admin user is created in DB with bcrypt-hashed password
- Admin logs in via a simple login form (session-based auth)
- Admin creates user profiles through the UI (no login for profiles)
- Profile switcher in navigation allows admin to select the active profile
- All workout logging happens under the selected profile
### Security Considerations
- Passwords hashed with bcrypt (never stored plaintext)
- `.env` file is gitignored and never committed
- `.env.example` documents required variables without real values
- Session tokens with reasonable expiry
- Admin-only routes protected by auth middleware
### Future Upgrade Path
- Phase 1 auth is designed to be replaceable
- If multi-user login is needed later, add login credentials to the user profiles table
- Profile switcher becomes unnecessary when each user logs in independently

59
docs/roadmap.md Normal file
View File

@@ -0,0 +1,59 @@
# SneakySwole Roadmap
## Phase 1: Scaffold & Infrastructure
Set up the project foundation — everything needed before writing features.
- FastAPI project structure (`app/` with routes, services, models, templates, static, utils)
- Dockerfile + docker-compose.yaml (SQLite volume, port 8000, `.env` support)
- Pico CSS dark theme base template (Jinja2 with `data-theme="dark"`)
- `.env` / `.env.example` with admin credentials (`ADMIN_USERNAME`, `ADMIN_PASSWORD`)
- `uv` for dependency management, `requirements.txt` with pinned versions
- Structlog logging setup
- Basic health check route (`/health`)
## Phase 2: Data Layer & Seeding
Build the database schema and seed it from YAML config files.
- SQLite schema via Alembic migrations
- Tables: users, exercises, warmups, workout_days, user_exercise_programs, sets, progress_log
- `config/exercises.yaml` — exercise library (name, muscle group, workout day, sets, tempo, form cues)
- `config/user_programs.yaml` — per-user week 1/4 reps and weights for each exercise
- Seed script that loads YAML into DB on first run
- Admin user auto-created from `.env` credentials on startup (password hashed with bcrypt)
- Two initial user profiles seeded: Phillip and Daughter
- Service layer for all DB access (no direct queries from routes)
## Phase 3: Workout UI
The core user-facing experience — viewing workouts and managing profiles.
- Admin login (simple session-based auth, password hashed)
- Profile switcher in nav (admin selects active user profile)
- Admin can create and edit user profiles (name, weight, height, goals)
- Workout day viewer — warmup routine + main exercises with full form cues
- Exercise library browser (search/filter by muscle group, workout day)
- All interactions via HTMX partials (no JSON APIs, no vanilla JS)
## Phase 4: Logging & Tracking
Enable workout logging so users can track what they actually did.
- Per-exercise logging: sets completed, reps, weight used, "felt easy?" toggle
- Workout session model (date, user profile, workout day)
- HTMX inline logging — log directly from the workout day view
- Log history view per user profile
- Edit/delete past log entries
## Phase 5: Progression & Analytics
Smart suggestions and visual progress tracking.
- Auto-progression engine based on log history
- +1-2 reps/week, +5 lbs every 2 weeks
- Deload detection at week 5 (-20% weight)
- 4-week schedule view (calendar-style, shows which day maps to which date)
- Progress dashboard per user profile
- Per-exercise progress history and trends
- Summary stats (total volume, streak tracking)

46
docs/security.md Normal file
View File

@@ -0,0 +1,46 @@
## Foundational Security Instructions
- Act as a security-aware software engineer generating secure Python code.
- Produce implementations that are **secure-by-design and secure-by-default**, not merely cosmetically "secured."
- Focus on **preventing vulnerabilities**, not renaming functions or adding superficial security wrappers.
- Explicitly identify **trust boundaries** (user input, external systems, internal components) and apply stricter controls at all boundary crossings.
- Treat **all external input as untrusted by default**, regardless of source, and validate or sanitize it before use.
- Explicitly consider **data sensitivity** (e.g., public, internal, confidential, regulated) and enforce controls appropriate to the highest sensitivity level involved.
- Clearly distinguish between **authentication**, **authorization**, and **session management**, and never conflate their responsibilities.
- Ensure implementations **fail securely**: errors, exceptions, and edge cases MUST NOT expose sensitive data or weaken security guarantees.
- Use inline comments (when generating code) to clearly highlight critical security controls, assumptions, and security-relevant design decisions.
- Adhere strictly to OWASP best practices, with particular consideration for the OWASP ASVS.
- **Avoid slopsquatting and dependency confusion**: never guess package names or APIs; only reference well-known, reputable, and maintained libraries. Explicitly note any uncommon or low-reputation dependencies.
- Do not hardcode secrets, credentials, tokens, or cryptographic material. Always require secure external configuration or secret management mechanisms.
---
## Common Weaknesses for Python
### CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
**Summary:** Failure to properly sanitize or encode user input can lead to injection of malicious scripts into web pages, enabling XSS attacks.
**Mitigation Rule:** All user input rendered in web pages MUST be sanitized and contextually encoded using a secure library such as `bleach` or `html.escape`.
### CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
**Summary:** Unsanitized user input in SQL queries can allow attackers to execute arbitrary SQL commands, compromising data integrity and confidentiality.
**Mitigation Rule:** SQL queries MUST use parameterized statements or prepared statements provided by libraries such as `sqlite3` or `SQLAlchemy`. Direct concatenation of user input into queries MUST NOT be used.
### CWE-327: Use of a Broken or Risky Cryptographic Algorithm
**Summary:** Using outdated or insecure cryptographic algorithms can compromise data confidentiality and integrity.
**Mitigation Rule:** Cryptographic operations MUST use secure algorithms provided by the `cryptography` library. Deprecated algorithms such as MD5 or SHA-1 MUST NOT be used.
### CWE-798: Use of Hard-coded Credentials
**Summary:** Hardcoding credentials in source code can lead to unauthorized access if the code is exposed or leaked.
**Mitigation Rule:** Secrets, credentials, and tokens MUST be stored securely using environment variables, secret management tools, or configuration files outside the source code repository.
### CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
**Summary:** Improper error handling or logging can expose sensitive data to unauthorized users.
**Mitigation Rule:** Error messages and logs MUST NOT include sensitive information such as stack traces, database connection strings, or user credentials. Use logging libraries such as `logging` with appropriate log levels and sanitization.
### CWE-502: Deserialization of Untrusted Data
**Summary:** Deserializing untrusted data can lead to arbitrary code execution or data tampering.
**Mitigation Rule:** Deserialization MUST only be performed on trusted data sources. Unsafe libraries such as `pickle` MUST NOT be used for deserialization of untrusted input.
### CWE-829: Inclusion of Functionality from Untrusted Control Sphere
**Summary:** Using dependencies or code from untrusted sources can introduce malicious functionality or vulnerabilities.
**Mitigation Rule:** Dependencies MUST be sourced from reputable package repositories such as PyPI. Verify the integrity and reputation of packages before use, and pin dependency versions to avoid supply chain attacks.

BIN
workout_plan_v2.xlsx Normal file

Binary file not shown.