Developer guide
This guide covers the supported repository workflow. Architecture decisions live in
docs/adr/; domain language and boundaries live in CONTEXT.md.
Requirements
- Python 3.13+
- Django 5.2 through 6.0
uvfor dependency and environment management- Git
justfor canonical repository recipes- PostgreSQL when exercising production behavior; SQLite is sufficient for local tests
Local setup
git clone https://github.com/justprosound/django-micboard.gitcd django-micboarduv sync --locked --all-extrasuv run --no-sync prek install -f --prepare-hooks --hook-type pre-commitThe root manage.py loads example_project.settings and uses SQLite by default:
uv run --no-sync python manage.py migrateuv run --no-sync python manage.py runserverOr run the bootstrap script:
./start-dev.sh./start-dev.sh --check-onlyDocker is optional and no Docker demo tree is required for local development.
Repository layout
django-micboard/├── micboard/│ ├── admin/ # Thin Django admin adapters│ ├── integrations/ # Manufacturer transports and plugins│ ├── management/commands/ # Thin management-command adapters│ ├── models/ # Domain-grouped persistence models│ ├── services/ # Business logic and orchestration│ ├── tasks/ # Native Huey wrappers│ ├── views/ # HTML/HTMX request adapters│ └── websockets/ # Authenticated Channels routing/consumer├── example_project/ # Development host project├── tests/ # Pytest suite, factories, and settings├── docs/ # Documentation site content (Astro Starlight)├── manage.py # Root example-project entry point├── Justfile # Canonical development recipes└── pyproject.toml # Package and tool configurationArchitecture rules
- Put business logic in a domain service, not in admin, views, tasks, serializers, or commands.
- Pass structured data with Pydantic v2 DTOs and keep public service APIs typed.
- Tasks carry serializable identifiers/DTO data and delegate to services.
- Scope querysets at the boundary; tenant isolation must fail closed.
- Use
select_related/prefetch_relatedintentionally on hot query paths. - Use
httpxfor manufacturer transport and close direct clients promptly. - Use native Huey through
huey.contrib.djhuey; do not introduce another task queue. - Update call sites directly when moving APIs; do not add compatibility re-export modules.
Review .github/copilot-instructions.md before changing architecture.
Testing
Run all tests:
just testFocused examples:
uv run --no-sync pytest tests/test_lifecycle_hooks.py -vuv run --no-sync pytest \ tests/test_lifecycle_hooks.py::TestStatusTransitionValidation::test_valid_transition_discovered_to_onlineuv run --no-sync pytest tests/admin/ -vuv run --no-sync pytest tests/ -k "shure or sennheiser"Coverage gate and inventory:
just coverageTest layout:
tests/admin/: end-to-end admin smoke flowstests/services/: domain-service unit/integration coveragetests/test_*security.py: authorization and authenticated-transport boundariestests/test_huey_*.py: native Huey configuration and task wrapperstests/factories/: reusable model factories
Add a regression test for each bug. For DB code, test rollback/on-commit behavior and tenant scope where relevant.
Quality gates
just lintjust prekuv run --no-sync bandit -r micboard -lluv run --no-sync python manage.py checkjust lint checks Ruff formatting, Ruff rules, and mypy. Prek additionally checks file
syntax, migration drift, and generated migration integrity.
Apply formatting deliberately:
uv run --no-sync ruff check . --fixuv run --no-sync ruff format .Migrations
Never edit or delete existing files in micboard/migrations/. When an approved model change
requires schema work, generate the new file through Django:
uv run --no-sync python manage.py makemigrations micboard micboard_multitenancyThen inspect operations and SQL, and test clean/existing databases. Check drift without writing:
uv run --no-sync python manage.py makemigrations \ micboard micboard_multitenancy --check --dry-runProduction hosts use django-safemigrate according to their deployment process.
Native Huey
Queued work requires huey.contrib.djhuey in INSTALLED_APPS and a dictionary at
settings.HUEY. Run the consumer with:
uv run --no-sync python manage.py run_hueyKeep network I/O outside long DB transactions. Task functions must delegate business behavior to services and accept explicit IDs rather than model instances.
Documentation
Use the manufacturer plugin development guide when adding or extending a vendor integration. It documents the live registry, base classes, transport, discovery, streaming, security, native Huey, and test boundaries.
just docs # build the site into site/just serve-docs # serve it on http://localhost:9000 with hot reloadAdd a module to PAGES in scripts/generate_api_docs.py when a new public surface should
appear in the API reference, then run just docs-api to regenerate the committed Markdown.
Update README.md for user-facing behavior and CHANGELOG.md under [Unreleased]. Keep commands,
paths, setting names, and optional dependencies aligned with repository code.
Packaging
Build and validate the distributable artifacts:
just wheelThe validation script installs the built wheel in an isolated uv-managed environment and checks that reusable-app resources are present.
Contribution workflow
- Create a focused branch.
- Implement the smallest contract-preserving change.
- Add or update tests and documentation.
- Run
just lint, relevant tests, andjust prek. - Use a Conventional Commit message.
- Open a PR describing behavior, risk, verification, and linked issues.
See CONTRIBUTING.md for the complete policy.
Support
django-micboard is licensed under AGPL-3.0-or-later.
