# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What This Is

`wagtail-donate` is a pluggable Wagtail/Django app for handling donations. It is distributed as a Python package (not a standalone project) and integrates into host Wagtail sites. It supports one-time donations, recurring donations, and fundraising pay-ins via Braintree (cards) and GoCardless (direct debit/bank transfer).

## Commands

### Python Testing

```bash
# Run full test matrix (multiple Python/Django/Wagtail versions)
tox

# Run a specific environment
tox -e py312-dj52-wagtail73

# Run tests directly (faster for development)
pip install -e .[testing]
DJANGO_SETTINGS_MODULE=wagtaildonate.tests.settings django-admin test wagtaildonate

# Run a single test module
DJANGO_SETTINGS_MODULE=wagtaildonate.tests.settings django-admin test wagtaildonate.tests.test_models
```

### Python Linting

```bash
tox -e black    # Check formatting
tox -e isort    # Check import ordering
tox -e flake8   # Lint
```

### Frontend

```bash
npm ci              # Install dependencies (use ci not install)
npm start           # Webpack watch + browser-sync for development
npm run build       # Production webpack build
npm run test        # Jest tests
npm run test:watch  # Jest in watch mode
npm run lint        # ESLint + Prettier check
npm run format      # Auto-format JS/TS
npm run storybook   # Component development at port 9001
```

## Architecture

### Package Structure

The entire app lives under `wagtaildonate/`. Key subdirectories:

- `models/` — Core data models (see below)
- `payment_methods/` — Payment provider implementations (`braintree.py`, `gocardless.py`)
- `api/` — DRF views and serializers for the checkout API
- `admin_views/` — Custom Wagtail admin views (export, pay-in event management)
- `wagtail_hooks/` — Wagtail hook registrations for admin integration
- `address_lookups/` — Pluggable address lookup integrations
- `static_src/` — TypeScript/React source; compiled output goes to `static/`
- `tests/` — Full test suite with a self-contained Django settings file

### Models

Models use an abstract base pattern so host projects can extend them:

- `BaseDonation` → `SingleDonation` / `RecurringDonation` — One-time and monthly donations
- `PayIn` — Fundraising/pay-in transactions linked to campaign pages
- `OptIns` mixin — Consent tracking (SMS, phone, post, email)
- `GiftAid` mixin — UK Gift Aid declarations
- `DonationExportLog` — Audit log for data exports

Page models (`pages.py`) are also abstract: `AbstractDonationPage`, `AbstractDonationLandingPage`, `AbstractDonationCampaignPage`, `AbstractDonationFundraisingPayInPage`. Host projects subclass these to add their own fields.

### Payment Method Framework

`PaymentMethod` base class (`payment_methods/base.py`) defines the interface. Each provider implements:
- `get_payment_form()` — Returns the payment form for the frontend
- `validate_transaction()` — Validates incoming payment data
- `get_client_token()` — Provides a client-side auth token

Constants on the base class: `FREQUENCY_SINGLE`, `FREQUENCY_MONTHLY`, `FREQUENCY_PAYIN`.

### API Flow

The frontend React/Redux app (`static_src/`) POSTs to the DRF API (`api/views/donations.py`). The API serializers (`api/serializers/`) are split by provider (braintree, gocardless) and donation type.

Configuration for the frontend is served by `api/views/configuration.py`, reading from `WAGTAIL_DONATE` settings via `configuration.py`.

### Configuration

Host projects configure the app via `settings.py`:

```python
WAGTAIL_DONATE = {
    "PAYMENT_METHODS": [],  # list of enabled payment method classes
    "SINGLE_DONATION_MODEL": "wagtaildonate.SingleDonation",
    "RECURRING_DONATION_MODEL": "wagtaildonate.RecurringDonation",
    "PAY_IN_MODEL": "wagtaildonate.PayIn",
    "MINIMUM_AMOUNT_PER_FREQUENCY": {"single": "1.00", "monthly": "1.00"},
    "MAXIMUM_AMOUNT_PER_FREQUENCY": {"single": "10000", "monthly": "10000"},
    "DONATION_EXPORT_ENABLED": True,
    "PAY_IN_EVENTS_ENABLED": True,
    "RECAPTCHA_PUBLIC_KEY": "",
    # ... address lookup, phone/email requirements, etc.
}
```

The `settings.py` module within the app exposes helpers that read from this dict with defaults.

### Test Settings

`wagtaildonate/tests/settings.py` is the self-contained Django settings file used for running tests. It defines a minimal host project setup. Use `DJANGO_SETTINGS_MODULE=wagtaildonate.tests.settings` for any `django-admin` commands during development.

### CI

GitLab CI (`.gitlab-ci.yml`) runs: static asset build → lint (frontend + Python) → test matrix → deploy to PyPI on version tags → MkDocs docs build. No Docker is involved in the test pipeline.
