From 236a28bb3dc2b3df303d1ee2cd8323eb31820e53 Mon Sep 17 00:00:00 2001 From: Bernard Siebens Date: Sun, 17 May 2026 23:36:08 +0200 Subject: [PATCH] New file for using Claude code --- CLAUDE.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..67f5c53 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,76 @@ +# 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 `"y"` (years) or `"m"` (months), parsed in `Season._add_months()`. \ No newline at end of file