Files
TeamForge/CLAUDE.md

76 lines
2.9 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Install dependencies
uv sync
# Database setup
python manage.py migrate
python manage.py createsuperuser
# Run dev server (two terminals needed, or use honcho)
python manage.py runserver
python manage.py tailwind start # separate terminal
# Run all tests
python manage.py test
# Run tests for a single app
python manage.py test members
python manage.py test teams
# Coverage
coverage run --source='.' manage.py test && coverage report
# Lint / format (line length 250)
ruff check .
ruff format .
```
## Architecture
TeamForge is a Django 6 club management app (members + teams). Key libraries:
- **HTMX** + **django-htmx**: dynamic interactions without a SPA
- **Tailwind CSS 4 + DaisyUI 5**: styling via `python manage.py tailwind start`
- **django-waffle**: feature flags (`TF_TEAMS`, `TF_ACTIVITIES`, `TF_MASS_UPLOAD`)
- **django-constance**: database-backed config (club name, logo, season defaults)
- **django-rules**: object-level permissions (predicates in `members/rules.py`)
- **django-filter**: URL-driven queryset filtering
### Apps
| App | Responsibility |
|-----|----------------|
| `members` | Member CRUD, CSV bulk import, permissions |
| `teams` | Season model and date-range logic |
| `backend` | Dashboard, configuration view |
| `theme` | Tailwind source, custom template tags |
### HTMX pattern
`HTMXViewMixin` (in `backend/views.py`) is the core convention: views render a full page for normal requests and a named partial for HTMX requests. Partials use django-partials syntax (`template.html#partial_name`). The mixin also injects `HX-Push-Url` and `HX-Trigger` response headers — the trigger drives client-side menu highlighting via a JS event listener.
### Members app details
- Every new `User` automatically gets a `Member` profile via a `post_save` signal.
- Deleting a member deactivates the `User` (`is_active=False`) — no hard deletes.
- `Member.create()` is the canonical way to create a member + user together.
- `MemberManager` always `select_related("user")`.
- Permissions are two-tier: Django model permissions + rules predicates (`is_member_manager`).
### Feature flags
New features should be gated with a `django-waffle` Switch. `WAFFLE_CREATE_MISSING_FLAGS = True` so flags don't need to be pre-created in migrations. Check flags in views with `waffle.switch_is_active("FLAG_NAME")` and in templates with `{% waffle_switch "FLAG_NAME" %}`.
### Configuration
Runtime config (club name, logo, season month/day/duration) lives in `django-constance` and is editable via `/backend/configuration/` (superuser only). Access values with `from constance import config; config.TF_CLUB_NAME`.
### Season duration format
`TF_DEFAULT_SEASON_DURATION` uses the custom format `"<n>y"` (years) or `"<n>m"` (months), parsed in `Season._add_months()`.