Add contributing guidelines to the repository

This commit is contained in:
SergeantPanda 2026-03-10 10:59:07 -05:00
parent 24c2fad138
commit 0516f4c857

230
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,230 @@
# Contributing to Dispatcharr
Thank you for your interest in contributing. Dispatcharr is a complex, production-oriented platform and we hold contributions to a high standard. Please read this guide in full before opening a pull request — it will save everyone time.
---
## Table of Contents
- [Before You Start](#before-you-start)
- [Project Overview](#project-overview)
- [Setting Up the Development Environment](#setting-up-the-development-environment)
- [Code Standards](#code-standards)
- [Writing Tests](#writing-tests)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [On AI-Assisted Code](#on-ai-assisted-code)
- [What We Will Decline](#what-we-will-decline)
---
## Before You Start
**Open an issue before writing code.** If you want to add a feature or fix a non-trivial bug, open a GitHub issue first. This lets us tell you whether it aligns with the project's direction, whether it's already being worked on, and how it should be approached — before you invest time writing code.
For small, obvious bug fixes (a typo, an off-by-one error, a missing validation) you can go straight to a PR.
---
## Project Overview
Understanding the architecture is a prerequisite for contributing. If you are not familiar with the following, take time to learn them before submitting changes:
| Layer | Technology |
| ----------- | ------------------------------------------------- |
| Backend | Python 3.13, Django 5, Django REST Framework |
| Async tasks | Celery 5 with Redis broker |
| Real-time | Django Channels (WebSockets), Redis channel layer |
| Database | PostgreSQL 17 |
| Frontend | React 19, Vite, Mantine UI, Zustand |
| API docs | drf-spectacular (OpenAPI) |
| Packaging | `uv`, `pyproject.toml`, Hatchling |
| Deployment | Docker, Nginx, uWSGI/Daphne |
### Key Django Apps
| App | Responsibility |
| --------------- | ----------------------------------------------------- |
| `apps/channels` | Core channel management |
| `apps/proxy` | Stream proxying, client management, failover |
| `apps/epg` | EPG ingestion, matching, XMLTV output |
| `apps/m3u` | M3U playlist parsing and management |
| `apps/output` | M3U, Xtream Codes, XMLTV export |
| `apps/hdhr` | HDHomeRun device emulation |
| `apps/vod` | VOD library with TMDB/IMDB metadata |
| `apps/ffmpeg` | FFmpeg stream profile management |
| `apps/plugins` | Plugin/event-hook system |
| `apps/accounts` | Auth, permissions, API keys |
| `core/` | Shared tasks, scheduling, utilities, Xtream Codes API |
Before touching any app, read its models, serializers, and views end-to-end so you understand what already exists.
---
## Setting Up the Development Environment
### Prerequisites
- Docker and Docker Compose
- Node.js 24+ (for frontend)
- Python 3.13+ and [`uv`](https://docs.astral.sh/uv/)
### Backend (Docker — recommended)
```bash
# Full stack (modular mode with separate containers)
docker compose -f docker/docker-compose.dev.yml up
# Or run Django directly against a local Redis/Postgres
uv sync
uv run python manage.py migrate
uv run python manage.py runserver
```
### Frontend
```bash
cd frontend
npm install
npm run dev # dev server with HMR (proxies API to Django)
npm run build # production build
npm run test # run Vitest test suite
```
The Vite dev server is configured to proxy `/api/` requests to the Django backend.
### Environment Variables
Copy the relevant `docker-compose.*.yml` as a reference for required environment variables. Key ones:
| Variable | Purpose |
| ----------------------- | ------------------------------------------------------------------------------------------- |
| `POSTGRES_*` | Database connection |
| `REDIS_*` | Redis broker / channel layer |
| `DJANGO_SECRET_KEY` | Django secret (auto-generated in Docker) |
| `DISPATCHARR_DEBUG` | Enables Django debug mode **and** starts debugpy for remote debugging (attach on port 5678) |
| `DISPATCHARR_LOG_LEVEL` | Log verbosity |
---
## Code Standards
### Backend (Python/Django)
- Follow [PEP 8](https://peps.python.org/pep-0008/). Use 4-space indentation.
- Follow Django conventions: fat models, thin views, business logic out of serializers.
- New API endpoints must use Django REST Framework. Include serializers — do not return raw dicts from views.
- New endpoints must be registered in the appropriate `api_urls.py` and must appear correctly in the OpenAPI schema (check via drf-spectacular).
- Database changes require a migration: `uv run python manage.py makemigrations <app>`. Migrations must be included in your PR.
- Celery tasks belong in `tasks.py` of the relevant app, or `core/tasks.py` for shared tasks. Tasks must be idempotent where possible.
- Do not introduce new top-level dependencies without discussion. Add them to `pyproject.toml` with a justification in your PR description.
### Frontend (React/JavaScript)
- Code must pass ESLint without errors: `npm run lint`
- Code must be formatted with Prettier: `npm run format`
- Use existing Mantine UI components. Do not introduce new UI libraries.
- State management uses Zustand. New global state belongs in a store under `frontend/src/store/`. Do not use React Context for app-level state.
- API calls belong in `frontend/src/api.js`. Do not make `fetch`/`axios` calls directly from components.
- Components should be functional. Avoid class components.
### General
- Do not leave debug logging, `console.log`, `print()`, or commented-out code in your PR.
- Do not reformat or refactor code outside the scope of your change. Noise in diffs makes review harder.
- Keep commits focused. One logical change per commit.
---
## Writing Tests
Untested code is significantly less likely to be merged.
### Backend
- Use Django's `TestCase` for unit/integration tests.
- Test files live at `apps/<app>/tests/`.
- Run the test suite with: `uv run python manage.py test`
### Frontend
- Use Vitest and React Testing Library.
- Test files live alongside what they test in `__tests__/` directories.
- Run with: `npm run test`
- Every new store should have a test file under `frontend/src/store/__tests__/`.
- Every new page should have a test file under `frontend/src/pages/__tests__/`.
---
## Submitting a Pull Request
### PR Checklist
Before opening your PR, verify each of the following yourself:
- [ ] I have read this entire document
- [ ] I opened (or was assigned to) a GitHub issue for this change before writing code
- [ ] I understand — line by line — every change in this PR
- [ ] Backend: migrations are included if models changed
- [ ] Backend: new endpoints are documented in the OpenAPI schema
- [ ] Frontend: ESLint and Prettier pass cleanly
- [ ] Tests are included for new functionality
- [ ] Existing tests still pass
- [ ] No debug artifacts are left in the code
- [ ] My PR targets the `dev` branch (or the branch specified in the issue)
### PR Description
A good PR description answers:
1. **What** does this change do?
2. **Why** is this change needed? (link to the issue)
3. **How** does it work? Describe any non-obvious technical decisions.
4. **How was it tested?** What did you run to verify this works?
One-line PR descriptions like _"fixed bug"_ or _"added feature"_ will be closed and asked to resubmit.
### Review Process
Maintainers review PRs as time allows. To keep the process moving:
- Respond to review comments promptly. Stale PRs (no activity for 30 days) may be closed.
- Do not force-push to a branch under review without flagging it in a comment.
- Keep your branch up to date with `dev` by rebasing, not merging `dev` into your branch.
---
## On AI-Assisted Code
We are aware that AI coding tools are capable of generating plausible-looking code quickly. We do not prohibit their use, but we require the following:
**You must understand every line of code you submit.**
AI tools frequently produce code that:
- Duplicates logic that already exists elsewhere in the codebase
- Ignores the established patterns for how the project is structured
- Introduces subtle bugs that are invisible without domain knowledge
- Passes superficial review but breaks edge cases in production
If you cannot explain, during code review, why a particular line of code is written the way it is — including the tradeoffs involved — the PR will not be merged. There are no exceptions.
Using an AI tool to help you understand the codebase, generate a first draft, or write boilerplate is fine. Submitting code you have not read and do not understand is not.
---
## What We Will Decline
To save your time and ours, the following types of PRs will be closed without extended review:
- **Undiscussed feature additions.** If there is no linked issue where the feature was agreed upon, we will close the PR and ask you to open one.
- **Large, unfocused diffs.** A PR that touches 20 files across 5 apps to "improve code quality" is almost never reviewable. Scope your changes.
- **Dependency bumps without justification.** Don't open a PR just to bump a library version unless you have identified a specific bug or security issue it resolves.
- **Cosmetic/style-only changes.** Reformatting files, renaming variables for preference, or reorganizing imports with no functional change.
- **Duplicate work.** Check open PRs and issues before starting. If someone is already working on it, coordinate with them.
- **Code the author cannot explain.** See [On AI-Assisted Code](#on-ai-assisted-code).
---
## Questions
If you are unsure whether a contribution is a good fit, join the [Discord](https://discord.gg/Sp45V5BcxU) and start a conversation, or comment on the relevant issue. We would rather have a five-minute conversation upfront than a 30-comment review thread on a PR that ultimately doesn't get merged.