Developer Manual¶
This manual covers the architecture, build pipeline, and development workflow for contributors and anyone extending Comaney.
Stack¶
| Layer | Technology |
|---|---|
| Language | Python 3.12 |
| Web framework | Django 5 |
| WSGI server | Gunicorn |
| Database | MariaDB via mysqlclient |
| Static files | WhiteNoise (served from Gunicorn, no separate web server needed) |
| Frontend | Alpine.js v3, Chart.js, CodeMirror 6 |
| CSS | SCSS compiled to CSS |
| JS bundling | esbuild |
| Container | Docker (linux/amd64) |
Python dependencies¶
All runtime dependencies are in requirements.txt:
| Package | Purpose |
|---|---|
Django |
Web framework |
gunicorn |
Production WSGI server |
mysqlclient |
MariaDB driver |
whitenoise |
Static file serving |
PyYAML |
Dashboard card YAML parsing |
anthropic |
AI express creation |
Pillow |
Receipt image processing |
pyotp + qrcode |
TOTP two-factor authentication |
Markdown |
Dynamic public page rendering |
Dev setup¶
The development stack runs MariaDB and the web app in Docker. You need Python locally only to run the test suite.
Prerequisites: Docker with Compose, Python 3.12 (for tests).
# Clone the repo
git clone ...
cd Comaney
# Create a .env file (see Admin Manual for env vars; for dev most defaults work)
cp .env.example .env
# Start the stack (database, mailpit, and the web app)
docker compose up
# App: http://localhost:8080
# Mailpit (outgoing email capture): http://localhost:8030
On first start, Django runs migrate automatically. To create a superuser:
Building frontend assets (CSS and JS) is a separate step. See Building Assets. You need to build the frontend assets to have a working development instance.
Key conventions¶
- Never use
request.useror@login_required. Comaney has its own user model (FeUser) and session auth. Use@feuser_requiredinstead, which setsrequest.feuser. - Always create expenses via
create_expense()inbudget/expense_factory.py, notExpense()directly. The factory handles M2M tags and post-save setup. - CSS custom properties only for theme colours. Do not replace them with SCSS
$variables: CSS custom properties are needed for dynamic light/dark switching at runtime. - Tests are mandatory for all functional features. See Testing.