Backend Contributing
Backend issue, pull request, and coding standards.
Thanks for your interest in contributing. This guide covers issues, pull requests, and the coding standards we follow.
The canonical online version of this guide is available at https://github.com/cmudco/dare-backend/blob/main/CONTRIBUTING.md.
Filing issues
Before opening an issue:
- Search the repository's existing issues to avoid duplicates.
- Verify the bug reproduces against the latest
dev. - Gather: environment (OS, Python version), reproduction steps, expected vs. actual behaviour, relevant logs.
Bug reports
Include:
- Environment — OS, Python version, deployment path (Docker / bare-metal), browser if frontend-related.
- Steps to reproduce — minimal, numbered.
- Expected behaviour.
- Actual behaviour — including stack traces or error responses (redact secrets).
- Severity — does this block use, or is it a minor annoyance?
Feature requests
Include:
- The user-facing problem you're trying to solve (not the implementation you have in mind).
- Who is affected.
- Any constraints or non-goals.
Security issues
Do not open public issues for security vulnerabilities. See SECURITY.md for the disclosure process.
Pull requests
Before opening a PR
-
Fork the repository, sync the latest
dev, and create a feature branch fromdev:git checkout dev git pull --ff-only origin dev git checkout -b your-name/feature/short-descriptionNaming:
<author>/<feature|fix|refactor|docs>/<short-description>. -
Run the full local check suite:
black --check . isort -c . python manage.py test -
If your change touches the database, generate migrations and commit them:
python manage.py makemigrations -
If your change touches the API, regenerate the OpenAPI schema if applicable.
PR template
Each PR should include:
- What — one-paragraph summary.
- Why — motivation; link to the issue if there is one (
Closes #123). - How — high-level approach. Call out non-obvious decisions.
- Testing — how you verified the change. New tests added? Manual repro steps?
- Screenshots / recordings — for any user-facing or API-shape change.
- Migration notes — if backwards-incompatible.
Review and merge
- At least one approving review from a maintainer.
- All CI checks green (lint, tests).
- Squash-merge by default. The squashed commit message becomes part of release notes — make it descriptive.
- Maintainers may rebase on
devbefore merging.
Coding standards
Python style
- Formatter: Black (line length 88). Run
black .before committing. - Import order: isort. Run
isort .. - Type hints are encouraged on new code, especially in
core/services/and any module exposing a public surface. - Docstrings on services and complex methods. One-line for trivial functions; numpydoc / Google style for anything heavier.
Django conventions
- Models inherit from
BaseModel(providescreated_at,updated_at,is_active,is_deleted). - Use
Model.active_objectsfor default-filtered querysets;Model.objectsfor unfiltered. - Constants belong in per-app
constants.pyfiles usingTextChoicesorIntegerChoices. - Wrap user-facing strings with
gettext_lazy as _. Do not translate logged exceptions or developer-facing error messages. - Keep views thin; push business logic into
core/services/or model methods.
REST API
- Inherit from
viewsets.ModelViewSetfor standard CRUD. - Always declare
permission_classes. Default to[IsAuthenticated]. - Filter querysets by user in
get_queryset()for any user-owned resource. - Use serializer field separation for read vs. write (see docs/code-standards.md and docs/serialization.md).
Background jobs
- Anything blocking, slow, or external goes through Django RQ.
- Decorate with
@job('default'). - Idempotent where possible — workers may retry on failure.
- Log liberally; failures are inspected via
rqstatsand the worker log.
Tests
- Use Django's
TestCasefor DB-dependent tests,SimpleTestCaseotherwise. - Mock external services (LLM APIs, vector stores, email) — never hit them in tests.
- Cover permission boundaries: a user should not be able to read another user's data.
- Async consumer tests use
ChannelsLiveServerTestCaseorpytest-asyncio.
Commit messages
Conventional-ish: <type>: <summary> where type is one of feat, fix, refactor, docs, test, chore. Keep the summary under 70 chars; use the body for context and rationale.
Example:
feat: refresh conversation summaries in the background
Queues a summary refresh after every fifth completed response.
Closes #482.Code review etiquette
- Review for correctness, then design, then style. Style nits are last priority.
- Suggest, don't demand —
nit:,consider:, andblocking:prefixes help calibrate. - Approve when you'd be comfortable shipping the change as-is.
Using AI coding agents
This repo ships shared configuration for AI coding agents, so an agent you point at a fresh clone already knows how to run the backend, start workers, and check a change before you open a PR.
| File | What it is |
|---|---|
AGENTS.md | Project instructions — architecture, conventions, patterns. Read by Codex and other tools following the AGENTS.md convention. |
CLAUDE.md | Imports AGENTS.md, plus any Claude Code-specific notes. |
.agents/skills/<name>/SKILL.md | Task procedures — run-backend, run-workers, check. |
.claude/skills/<name> | Symlinks to the above, because Claude Code scans a different path. |
Invoke a skill by name — /run-backend in Claude Code, $run-backend in Codex — or just describe
the task and let the agent load the matching skill on its own.
To add or change a skill, edit the file under .agents/skills/; the .claude/skills/ symlink
needs no change. See .agents/README.md for the layout, how to add a new
skill, and the Windows symlink caveat.
Treat these files like code: they are reviewed in PRs, and a stale skill is worse than no skill. If you change how the backend is run, built, or tested, update the matching skill in the same PR.
Getting help
- Stuck? Open a draft PR and ask in the description — easier than hashing things out in chat.
- For larger architectural changes, file an issue with a design sketch before writing code.