Backend Setup¶
Prerequisites¶
- Python 3.12+
- Poetry
- Google Cloud SDK (
gcloudCLI) - Docker (optional, for containerized development)
Initial Setup¶
1. Authenticate with Google Cloud¶
# Login to GCP
gcloud auth login
# Set up application default credentials
gcloud auth application-default login
# Verify your account
gcloud config get-value account
2. Grant Secret Manager Access¶
Required Step
Before running the backend, you must grant yourself access to environment secrets.
cd backend
# Run the secret setup (one-time)
just setup-secrets
# Verify you have access to all secrets
just test-secrets
This grants access to:
rose-env-testrose-env-stagingrose-env-productionrose-env-development
3. Install Dependencies¶
Running the Backend¶
Option A: Local Development (Recommended)¶
Best for daily development work:
cd backend
# Download environment from Secret Manager
just download-env staging
# Start the server
just dev staging
Option B: Docker Mode¶
Emulates Cloud Run environment:
cd backend
# Requires GCP project configured
gcloud config set project YOUR_PROJECT_ID
# Run in Docker
just run-docker-search staging
Comparison¶
| Feature | Local (just dev) |
Docker (just run-docker-search) |
|---|---|---|
| Environment Source | .env.<environment> file |
Secret Manager (direct) |
| GCP Project Required | No | Yes |
| Use Case | Daily development | Test Cloud Run locally |
| Startup Time | Fast | Slower (builds image) |
Environment Management¶
Download Environment¶
cd backend
just download-env staging # Downloads to .env.staging
just download-env production # Downloads to .env.production
Upload Environment¶
cd backend
just upload-env staging # Uploads .env.staging
just upload-env production # Uploads .env.production
Testing¶
Test Philosophy¶
Never Skip Tests
Tests must never use pytest.skip() to avoid setup complexity.
- Unit tests: Mock all external dependencies
- Integration tests: Use real credentials from
.env.test
Running Tests¶
cd backend
# All tests
poetry run pytest
# By marker
poetry run pytest -m unit # Unit tests only
poetry run pytest -m integration # Integration tests
# Specific file or test
poetry run pytest tests/test_module.py
poetry run pytest tests/test_module.py::test_function
# With verbose output
poetry run pytest -v -s
Test Markers¶
| Marker | Purpose | Requirements |
|---|---|---|
@pytest.mark.unit |
Unit tests with mocks | None |
@pytest.mark.integration |
Real service tests | .env.test credentials |
@pytest.mark.llm_integration |
Real LLM API calls | LLM API keys |
@pytest.mark.redis |
Redis tests | REDIS_URL |
@pytest.mark.neo4j |
Neo4j tests | Neo4j instance |
@pytest.mark.asyncio |
Async tests | Required for async def |
Type Checking¶
Important
Due to the monorepo structure, mypy must be run with MYPYPATH set.
cd backend
# Check a specific file in ixchat
MYPYPATH=packages/ixchat poetry run mypy packages/ixchat/ixchat/path/to/file.py
# Check entire ixchat package
MYPYPATH=packages/ixchat poetry run mypy packages/ixchat/
Release Management¶
Production Release¶
cd backend
# Release to production (default)
just release
# Release to multiple environments
just release "production staging"
Release Process:
- Validates clean git working directory
- Bumps patch version in
/version.json - Prompts for confirmation
- Commits version bump
- Creates git tag:
vX.Y.Z - Builds and deploys Docker images
- Pushes commits and tags
- Sends Slack notification
Troubleshooting¶
"Permission denied accessing Secret Manager"¶
"IX_ENVIRONMENT environment variable is not set"¶
Use justfile commands which handle this automatically:
Docker build fails with "version.json not found"¶
Run commands from the backend/ directory. The justfile automatically copies version.json from the repository root.
Docker mode shows "GCP_PROJECT_ID is not configured"¶
# Check current project
gcloud config get-value project
# Set your project
gcloud config set project YOUR_PROJECT_ID
Tip
For local development without Docker complexity, use just dev staging instead.