# Development Process — Test-Develop-Debug ## Local Environment - Python 3.12 via NixOS, virtualenv at `.venv/` - Always use `.venv/bin/python` or activate with `source .venv/bin/activate` before running Python commands - When running `pytest`, `ruff`, or any Python tool, use the `.venv` — e.g. `python -m pytest` (not bare `pytest` which may resolve to system Python) - Node.js 24 available for frontend work; `frontend/` has its own `node_modules/` ## Workflow 1. Write or update tests for the target behavior 2. Implement the minimal code to pass 3. Debug failures, fix, re-run 4. Commit and push after each phase completes 5. GitHub Actions CI automatically builds container images and pushes to GHCR 6. Deploy to cluster via Helm or `kubectl apply` ## Testing - Use `pytest` with `pytest-asyncio` for async code - Tests live in the top-level `tests/` directory - Run tests with `python -m pytest tests/ -x --tb=short -q` - Focus on core logic, not mocking infrastructure ## CI/CD — GitHub Actions - Workflow file: `.github/workflows/build.yml` - Triggers on push to `main` and PRs - Jobs: - `lint-and-test`: runs ruff lint + pytest on ubuntu with Python 3.12 - `build-services`: matrix build of all Python services via `docker/Dockerfile`, pushes to GHCR with `:` and `:latest` tags - `build-dashboard`: builds `frontend/Dockerfile` separately, pushes `dashboard` image to GHCR - CI handles image building and pushing — do NOT manually `docker push` unless CI is broken or you need to bypass it - After pushing to `main`, wait for CI to complete before deploying (check GitHub Actions status) - If you need to build locally for testing: `make build` or `docker build` directly, but let CI do the GHCR push ## Deploy - Helm chart at `infra/helm/stonks-oracle/` - Deploy: `helm upgrade --install stonks-oracle infra/helm/stonks-oracle -n stonks-oracle` - Alternative raw manifests: `kubectl apply -f infra/k8s/` - To restart a deployment after CI pushes new images: `kubectl rollout restart deployment/ -n stonks-oracle` ## Git Conventions - Commit after each completed phase task - Commit message format: `phase N: short description` - Push to `main` branch triggers CI ## Code Style - Python 3.12, type hints everywhere - Pydantic for data validation - FastAPI for HTTP services - asyncio + asyncpg/aioredis for async I/O - Minimal dependencies, prefer stdlib where possible - Frontend: React 19, TypeScript strict mode, Tailwind CSS, TanStack Router/Query ## Documentation - Do NOT create large summary/success markdown files after each step - Keep notes short, concise, and organized under `docs/notes/` - Name note files to match the task they relate to (e.g. `docs/notes/phase0-k8s-manifests.md`) - If a note isn't useful for future reference, don't write it