Skip to content

Commit 3c21e36

Browse files
committed
πŸ“ Docs: Add CLAUDE.md for AI-assisted development guidance
Add a `CLAUDE.md` file to provide structured context for AI-assisted development sessions using Claude Code. This file documents the project architecture, build commands, data flow, CI/CD pipeline, and git commit conventions so that each session starts with a shared understanding of the codebase rather than re-exploring from scratch. AI tools are used in this project to accelerate modernization work that would otherwise require significant time investment β€” updating a decade- old Flask stack, converting template engines, and building CI/CD pipelines. `CLAUDE.md` ensures this assistance is focused and productive by defining the scope and conventions of the project upfront. All AI- assisted commits are clearly labeled with an "Assisted-by" trailer. Assisted-by: Claude Opus 4.6 (1M context) Signed-off-by: Justin Wheeler <git@jwheel.org>
1 parent a1df89a commit 3c21e36

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

β€ŽCLAUDE.mdβ€Ž

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
HFLOSSK is the Humanitarian Free/Open Source Software Course website for RIT, built with Flask and Mako templates. It serves course materials (lectures, homework, quizzes) and tracks student participation via YAML files and RSS blog feeds. There is no database β€” all data is file-based.
8+
9+
## Commands
10+
11+
### Setup (Fedora Linux 43)
12+
```bash
13+
sudo dnf install python3 python3-pip git
14+
git clone git@github.com:FOSSRIT/hflossk.git
15+
cd hflossk
16+
python3 -m venv venv
17+
source venv/bin/activate
18+
pip install -e .
19+
```
20+
21+
### Run locally
22+
```bash
23+
python app.py
24+
# Serves at http://127.0.0.1:5000/ in debug mode
25+
```
26+
27+
### Run tests
28+
```bash
29+
pip install -e ".[test]"
30+
pytest # Run tests only
31+
pytest --tb=short # Shorter traceback output
32+
ruff check . # Lint only
33+
```
34+
35+
### Run full test suite via tox
36+
```bash
37+
pip install tox
38+
tox # Tests (py314) + lint
39+
tox -e lint # Lint only
40+
tox -e cover # Tests with coverage
41+
```
42+
43+
### Freeze static site
44+
```bash
45+
python freeze.py
46+
# Generates static HTML in build/
47+
```
48+
49+
## Architecture
50+
51+
### Entry Point
52+
`app.py` imports the Flask app from `hflossk/site.py` and runs the Flask dev server in debug mode. For production, use `gunicorn hflossk.site:app`.
53+
54+
### Template Engine: Mako (not Jinja2)
55+
Templates use `.mak` extension and Mako syntax (`${variable}`, `<%inherit>`, `<%def>`, `% for`). The Flask-Mako extension bridges Flask and Mako. All templates live in `hflossk/templates/`.
56+
57+
### Core Modules
58+
- **`hflossk/site.py`** β€” Flask app creation, route definitions, context processor that injects `site.yaml` config into all templates. Gravatar/Libravatar helper. Routes for pages, syllabus, blog JSON endpoint, participant profiles, resources.
59+
- **`hflossk/blueprints.py`** β€” Blueprints for `/assignments/` (homework), `/lectures/`, `/quizzes/`. Each dynamically discovers and serves templates from its subdirectory.
60+
- **`hflossk/participants.py`** β€” Blueprint for `/participants/`, `/blogs/`, `/checkblogs/`. Walks `scripts/people/<year>/<term>/*.yaml` to build student roster. Calculates expected blog post counts based on elapsed course weeks.
61+
- **`hflossk/util.py`** β€” RSS feed parsing via feedparser. Counts blog posts since course start date.
62+
63+
### Data Flow
64+
1. **Course config**: `hflossk/site.yaml` (instructor, dates, location) and `hflossk/schedule.yaml` (weekly topics, assignments, due dates) are loaded at request time and injected into templates.
65+
2. **Student data**: `scripts/people/<year>/<term>/<username>.yaml` β€” each file has required keys (`blog`, `feed`, `forges`, `irc`, `name`, `rit_dce`) and optional `hw` dict mapping assignment names to blog post URLs.
66+
3. **Blog tracking**: `/blog/<username>` endpoint parses student RSS feeds and returns JSON post count. Used via AJAX in the participants page.
67+
68+
### Content as Templates
69+
Course content (lectures, homework, quizzes) are Mako template files in `hflossk/templates/hw/`, `hflossk/templates/lectures/`, `hflossk/templates/quiz/`. They inherit from `master.mak`.
70+
71+
### Static Assets
72+
`hflossk/static/` contains Bootstrap CSS/JS, course PDFs (`books/`), slide decks (`decks/`), and challenge descriptions (`challenges/`).
73+
74+
### YAML Validation Tests
75+
`hflossk/tests/test_yaml.py` validates that all student YAML files contain required fields and conform to expected schema. This is the primary test coverage.
76+
77+
## CI/CD
78+
79+
- **CI** (`.github/workflows/ci.yml`): Runs on all branches/PRs in a Fedora 43 minimal container. Installs deps, lints with ruff, runs pytest.
80+
- **Preview** (part of CI): For non-main branches, freezes the site and uploads a downloadable artifact (retained 7 days).
81+
- **Deploy** (`.github/workflows/deploy.yml`): On push to `main`, freezes the site via `freeze.py` and deploys to GitHub Pages.
82+
- **Static site generation**: `freeze.py` uses Frozen-Flask to crawl the app and generate static HTML. Dynamic routes like `/blog/<username>` (live RSS parsing) are excluded.
83+
84+
## Key Constraints
85+
- Flask-Mako pins the project to Mako templating; migration to Jinja2 would require rewriting 30+ template files
86+
- No database or ORM β€” all persistence is YAML files in the repo
87+
- Python 3.14 on Fedora 43 is the target runtime
88+
89+
## Git Commit Conventions
90+
- Subject line: emoji prefix + component prefix (e.g., `πŸ”§ App:`, `πŸ“ Docs:`, `πŸš€ CI:`, `πŸ› Fix:`)
91+
- Trailer: `Assisted-by: Claude Opus 4.6 (1M context)` for AI-assisted commits
92+
- Trailer: `Signed-off-by:` (always last, via `--signoff`)
93+
- GPG signed (via `-S`)

0 commit comments

Comments
Β (0)