BoilerplateHub

Django SaaS AGENTS.md Template

For a monolithic Django SaaS with custom apps, Django REST Framework endpoints, Celery for background work, and Stripe subscriptions. It assumes a settings module split by environment and templates rendered server side alongside an API. Use it when Django conventions should be enforced rather than reinvented.

DjangoPythonPostgreSQLCeleryStripe
AGENTS.md
Download
# AGENTS.md

This is a subscription SaaS built as a Django monolith with a REST API, background jobs, and Stripe billing.

## Project

Stack: Python 3.12, Django 5, Django REST Framework, PostgreSQL, Celery with Redis, Stripe, pytest-django, ruff.

Layout:

- `config/settings/base.py`, `config/settings/dev.py`, `config/settings/prod.py`
- `config/urls.py` root URL configuration
- `apps/accounts/` custom user model, authentication, teams
- `apps/billing/` Stripe customers, subscriptions, webhook handling
- `apps/core/` shared abstract models, mixins, and utilities
- `apps/<feature>/` one Django app per bounded feature
- Each app: `models.py`, `views.py`, `serializers.py`, `services.py`, `tasks.py`, `urls.py`, `admin.py`, `migrations/`
- `templates/` server rendered pages, `static/` assets

Entry points: `manage.py`, `config/settings/base.py`, `config/urls.py`, `apps/billing/webhooks.py`.

## Commands

```bash
uv sync                                        # install dependencies
uv run python manage.py runserver              # dev server on :8000
uv run python manage.py makemigrations         # create migrations
uv run python manage.py migrate                # apply migrations
uv run python manage.py showmigrations         # inspect state
uv run python manage.py shell_plus             # interactive shell
uv run python manage.py createsuperuser
uv run python manage.py collectstatic --noinput
uv run pytest                                  # test suite
uv run pytest apps/billing -k webhook          # one app or test
uv run ruff check . && uv run ruff format .
uv run celery -A config worker -l info         # background worker
uv run celery -A config beat -l info           # scheduled jobs
```

`DJANGO_SETTINGS_MODULE` defaults to `config.settings.dev` locally.

## Code style

- Business logic lives in `services.py`, not in views and not in serializers.
- Views are thin: permission check, deserialize, call a service, return a response.
- Query in the view or service, never in a template. Use `select_related` and `prefetch_related` for every relation you render.
- Custom managers and querysets for reusable filters. No copy pasted `filter()` chains.
- Model methods that mutate state wrap their writes in `transaction.atomic`.
- Use `get_user_model()`, never import the user model directly.
- Money is a `DecimalField` with explicit precision, never a float.
- Signals are avoided. If a side effect matters, call it explicitly from a service.
- Type hints on service functions. Line length 100, enforced by ruff.
- Every `TextChoices` and `IntegerChoices` is defined on the model, not as loose constants.

## Boundaries

Do not touch without explicit instruction:

- Existing files in any `migrations/` directory. Never edit, squash, or delete a migration that has been applied.
- `config/settings/prod.py` and any environment specific credential.
- `uv.lock`, `.env`, `.github/workflows/`, deployment manifests.
- `apps/billing/webhooks.py` and Stripe price configuration.

Needs human review: data migrations, changes to permission classes, anything that touches subscription state, and any change to the custom user model.

Generate migrations when models change, show the resulting file, and stop before applying to anything but the local database.

## Testing

- `uv run pytest` runs the suite, `uv run pytest apps/<app>` runs one app.
- Required tests: permission classes, service functions, Celery tasks, and every billing state transition.
- Use `pytest.mark.django_db` and the factories in `apps/<app>/tests/factories.py`. Do not add JSON fixtures.
- API tests go through `APIClient` and assert status code and response shape.
- Celery tasks are tested by calling the function directly, with `CELERY_TASK_ALWAYS_EAGER` reserved for integration tests.
- A bug fix ships with a failing-first regression test.

## Git workflow

- Branch from `main`: `feat/short-description`, `fix/short-description`.
- Conventional commits with the app as scope: `feat(billing): handle trial expiry`.
- Before creating a migration, rebase on `main` so the revision ordering stays linear. If two migrations collide, regenerate rather than hand merging.
- Code and its migration ship in the same commit.
- PR description lists migrations, new settings, and any manual step needed at deploy.

What each section does

Project

Django spreads a feature across models, views, serializers, forms, and templates, so an agent needs the app boundaries written down. Naming which app owns which concept keeps new code from landing in a catch all module. The settings split is worth stating because it determines what runs where.

Commands

Almost everything in Django goes through manage.py, and the exact invocation differs by project. Listing migration, test, and shell commands means the agent verifies work rather than describing it. Celery commands belong here too since background tasks are otherwise invisible locally.

Code style

Django has strong conventions that an agent will violate in predictable ways: fat views, queries in templates, and N+1 lookups. Concrete rules about where logic lives and how querysets are built are checkable in review. This section is where the project decides between fat models and a service layer.

Boundaries

Django migrations are stateful and shared, so an edited or deleted migration breaks every other environment. Settings modules and billing code are the other places where an autonomous change has outsized consequences. Be explicit that data migrations need a person.

Testing

Django tests are slow enough that an agent needs to know how to run a subset or it will skip testing entirely. Stating which layers must have tests focuses effort on permissions, billing, and tasks. Fixture strategy should be named so tests stay consistent.

Git workflow

Because migrations are ordered, two branches creating migrations at once causes conflicts that are easy to resolve wrongly. Saying so upfront turns it into a routine check. Standard branch and commit conventions cover the rest.

Which agents read this file?

Claude Code looks for CLAUDE.md. Most other agents and editors read AGENTS.md. Rather than maintaining both and letting them drift, keep one real file and symlink the other:

ln -s AGENTS.md CLAUDE.md
git add AGENTS.md CLAUDE.md

Git stores the symlink, so it survives cloning on macOS and Linux. On Windows it needs developer mode or a stub file that references the real one. The full comparison is in CLAUDE.md vs AGENTS.md.

Other templates

Reviews

Leave a comment

Your rating (optional)

0/2000