Setup
Prerequisites
- Python 3.12+
- Docker
- Git
- uv (Python package manager)
First time setup
Code quality
Pre-commit hooks run automatically on every commit. They check formatting, linting, type hints, and security.What gets checked
| Check | Tool | Behavior |
|---|---|---|
| Formatting | Ruff | Auto-formats code |
| Linting | Ruff | Code quality rules |
| Type checking | ty | Validates type hints (CI only) |
| Security | Bandit | Scans for vulnerabilities |
| Commit message | Hook | Enforces conventional format |
Commands
Commit messages
Required format:type(scope): description
Types
| Type | When to use |
|---|---|
feat | New feature |
fix | Bug fix |
docs | Documentation |
style | Formatting only |
refactor | Code restructure |
perf | Performance improvement |
test | Tests |
chore | Maintenance |
ci | CI/CD changes |
Scope (optional)
Specify the affected area:api, auth, db, graph, tests, docs, ci.
What happens when you commit
Development workflow
- CLI (recommended)
- Docker Compose
- Manual
http://localhost:8000/docs to see the API.
Migrations run automatically on server startup (
aegra dev, Docker, or manual). You only need manual migration commands when creating new migrations or troubleshooting.Database migrations
Aegra uses Alembic for database migrations. Migrations apply automatically on server startup — you only need these commands when creating or debugging migrations.Making database changes
- Edit ORM models in
libs/aegra-api/src/aegra_api/core/orm.py - Generate a migration:
uv run --package aegra-api alembic revision --autogenerate -m "Description" - Review the generated file in
libs/aegra-api/alembic/versions/ - Restart the server — migrations apply automatically
Testing migrations
Running tests
Test levels
Every feature needs tests at all applicable levels:| Level | Location | What it tests |
|---|---|---|
| Unit | tests/unit/ | Isolated functions with mocked dependencies |
| Integration | tests/integration/ | HTTP requests via FastAPI TestClient with mocked DB |
| E2E | tests/e2e/ | Real server + real database via LangGraph SDK |
LangGraph service architecture
TheLangGraphService manages graph loading, caching, and execution.
Design principles
- Cache base graphs, not execution instances — compiled graph structure (without checkpointer/store) is cached for fast loading
- Fresh copies per-request — each execution gets a fresh graph copy with checkpointer/store injected
- Thread-safe by design — no locks needed because cached state is immutable
Usage patterns
For graph execution (runs, state operations):Why this pattern
| With locks (old) | Context manager (current) |
|---|---|
| Single cached instance with checkpointer | Fresh copy per request |
| Needed locks for concurrent access | Thread-safe by design |
| Potential race conditions | No race conditions possible |
| Complex error handling | Simple, predictable behavior |
Pull request checklist
Before creating a PR:- Git hooks installed (
make setup-hooks) - All commits follow the conventional format
- Tests pass (
make test) - Code formatted (
make format) - No linting errors (
make lint) - PR title follows format:
type: description -
make ci-checkpasses
Troubleshooting
Common commit hook failures
Commit message format invalid
Commit message format invalid
Ruff formatting failed
Ruff formatting failed
Type checking failed
Type checking failed
Common database issues
| Problem | Solution |
|---|---|
| Can’t connect to database | docker compose up postgres -d |
| ”No such revision” error | uv run --package aegra-api alembic current to check state |
| Incompatible DB version | See PostgreSQL migration guide |
| Database broken | alembic downgrade base then alembic upgrade head (loses data) |
Get help
- GitHub — Open an issue for bugs or feature requests.
- Discord — Join the community for questions and discussion.