This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Balancer is a web application designed to help prescribers choose suitable medications for patients with bipolar disorder. It's a Code for Philly project built with a PostgreSQL + Django REST Framework + React stack, running on Docker.
Live site: https://balancertestsite.com
- Docker Desktop
- Node.js and npm
- API keys for OpenAI and Anthropic (request from team)
# Clone the repository
git clone <repo-url>
# Install frontend dependencies
cd frontend
npm install
cd ..
# Configure environment variables
# Copy config/env/dev.env.example and fill in API keys:
# - OPENAI_API_KEY
# - ANTHROPIC_API_KEY
# - PINECONE_API_KEY (if needed)
# Start all services
docker compose up --build- Frontend: React + Vite dev server at http://localhost:3000
- Backend: Django REST Framework at http://localhost:8000
- Database: PostgreSQL at localhost:5433
- pgAdmin: Commented out by default (port 5050)
# Start all services
docker compose up --build
# Start in detached mode
docker compose up -d
# View logs
docker compose logs -f [service_name]
# Stop all services
docker compose down
# Rebuild a specific service
docker compose build [frontend|backend|db]
# Access Django shell in backend container
docker compose exec backend python manage.py shell
# Run Django migrations
docker compose exec backend python manage.py makemigrations
docker compose exec backend python manage.py migratecd frontend
# Start dev server (outside Docker)
npm run dev
# Build for production
npm run build
# Lint TypeScript/TSX files
npm run lint
# Preview production build
npm run previewcd server
# Create Django superuser (credentials in api/management/commands/createsu.py)
docker compose exec backend python manage.py createsuperuser
# Access Django admin
# Navigate to http://localhost:8000/admin
# Run database migrations
docker compose exec backend python manage.py makemigrations
docker compose exec backend python manage.py migrate
# Django shell
docker compose exec backend python manage.py shell- Main development branch:
develop - Production branch:
listOfMed(used for PRs) - Create feature branches from
develop - PRs should target
listOfMedbranch
Django uses dynamic URL importing (see server/balancer_backend/urls.py). API endpoints are organized by feature modules in server/api/views/:
conversations/- Patient conversation managementfeedback/- User feedbacklistMeds/- Medication catalogrisk/- Risk assessment endpointsuploadFile/- PDF document uploadsai_promptStorage/- AI prompt templatesai_settings/- AI configurationembeddings/- Vector embeddings for RAGmedRules/- Medication rules managementtext_extraction/- PDF text extractionassistant/- AI assistant endpoints
Each module contains:
views.pyorviews_*.py- API endpointsmodels.py- Django ORM modelsurls.py- URL patternsserializers.py- DRF serializers (if present)
- Uses JWT authentication with
rest_framework_simplejwt - Default: All endpoints require authentication (
IsAuthenticated) - To make an endpoint public, add to the view class:
from rest_framework.permissions import AllowAny class MyView(APIView): permission_classes = [AllowAny] authentication_classes = [] # Optional: disable auth entirely
- Auth endpoints via Djoser:
/auth/ - JWT token lifetime: 60 minutes (access), 1 day (refresh)
- Auto-generated using drf-spectacular (OpenAPI 3.0)
- Swagger UI:
http://localhost:8000/api/docs/— interactive API explorer - ReDoc:
http://localhost:8000/api/redoc/— readable reference docs - Raw schema:
http://localhost:8000/api/schema/ - Configuration in
SPECTACULAR_SETTINGSinsettings.py - Views use
@extend_schemadecorators andserializer_classattributes for schema generation - JWT auth is configured in the schema — use
JWT <token>(notBearer) in Swagger UI's Authorize dialog - To document a new endpoint: add
serializer_classto the view if it has one, or add@extend_schemawithinline_serializerfor views returning raw dicts
- Medication (
api.views.listMeds.models) - Medication catalog with benefits/risks - MedRule (
api.models.model_medRule) - Include/Exclude rules for medications based on patient history - MedRuleSource - Junction table linking MedRules → Embeddings → Medications
- Embeddings (
api.models.model_embeddings) - Vector embeddings from uploaded PDFs for RAG - UploadFile (
api.views.uploadFile.models) - Uploaded PDF documents with GUID references
The application uses embeddings from medical literature PDFs to provide evidence-based medication recommendations:
- PDFs uploaded via
uploadFile→ text extracted → chunked → embedded (OpenAI/Pinecone) - MedRules created linking medications to specific evidence (embeddings)
- API endpoints return recommendations with source citations (filename, page number, text excerpt)
src/components/- Reusable React components (Header, forms, etc.)src/pages/- Page-level componentssrc/routes/routes.tsx- React Router configurationsrc/services/- Redux store, actions, reducers, API clientssrc/contexts/- React Context providers (GlobalContext for app state)src/api/- API client functions using Axiossrc/utils/- Utility functions
- Redux for auth state and global application data
- Store:
src/services/store.tsx - Actions:
src/services/actions/ - Reducers:
src/services/reducers/
- Store:
- React Context (
GlobalContext) for UI state:showSummary- Display medication summaryenterNewPatient- New patient form stateisEditing- Form edit modeshowMetaPanel- Metadata panel visibility
Routes defined in src/routes/routes.tsx:
/- Medication Suggester (main tool)/medications- Medication List/about- About page/help- Help documentation/feedback- Feedback form/logout- Logout handler- Admin routes (superuser only):
/rulesmanager- Manage medication rules/ManageMeds- Manage medication database
- Tailwind CSS for utility-first styling
- PostCSS with nesting support
- Custom CSS in component directories (e.g.,
Header/header.css) - Fonts: Quicksand (branding), Satoshi (body text)
- pgvector extension enabled for vector similarity search
- Custom Dockerfile for PostgreSQL (
db/Dockerfile) - workaround for ARM64 compatibility - Database connection:
- Host:
db(Docker internal) orlocalhost:5433(external) - Credentials:
balancer/balancer(dev environment) - Database:
balancer_dev
- Host:
- Development:
config/env/dev.env(used by Docker Compose) - Frontend Production:
frontend/.env.production- Contains
VITE_API_BASE_URLfor production API endpoint
- Contains
- Never commit actual API keys - use
.env.exampleas template - Django
SECRET_KEYshould be a long random string in production (not "foo")
- Create view in appropriate
server/api/views/{module}/views.py - Add URL pattern to
server/api/views/{module}/urls.py - If new module, add to
urlslist inserver/balancer_backend/urls.py - Consider authentication requirements (add
permission_classesif needed)
MedRules use a many-to-many relationship with medications and embeddings:
rule_type: "INCLUDE" (beneficial) or "EXCLUDE" (contraindicated)history_type: Patient diagnosis state (e.g., "DIAGNOSIS_DEPRESSED", "DIAGNOSIS_MANIC")- Access sources via
MedRuleSourceintermediate model - API returns benefits/risks with source citations (filename, page, text, upload_file_guid)
Feature: Conditional PDF viewing/downloading based on authentication state
Behavior:
- Logged-in users: See "View PDF" button (blue) that opens
/drugSummarypage in new tab - Non-logged-in users: See "Download PDF" button (green) that directly downloads via
/v1/api/uploadFile/<guid>endpoint
Implementation Details:
- Backend:
upload_file_guidfield added to source_info inviews_riskWithSources.py(3 locations) - Frontend:
isAuthenticatedprop passed through component hierarchy:PatientManager(gets from Redux) →PatientSummary→MedicationTier→MedicationItem
- Download endpoint:
/v1/api/uploadFile/<guid>is public (AllowAny permission) - Fallback: If
upload_file_guidmissing from API, GUID is extracted fromlink_urlquery parameter - Route:
/drugSummary(camelCase) - fixed from inconsistent/drugsummaryusage
Files Modified:
- Backend:
server/api/views/risk/views_riskWithSources.py - Frontend:
frontend/src/pages/PatientManager/PatientManager.tsx,PatientSummary.tsx - Routes: Multiple files updated for consistent
/drugSummarycasing - Auth:
ProtectedRoute.tsxandLayout_V2_Main.tsxfixed for proper auth checking
- API client functions in
src/api/ - Use Axios with base URL from environment
- JWT tokens managed by Redux auth state
- Error handling should check for 401 (unauthorized) and redirect to login
Services use a custom network (192.168.0.0/24):
- db: 192.168.0.2
- backend: 192.168.0.3
- frontend: 192.168.0.5
- Services communicate using service names (e.g.,
http://backend:8000)
Limited test coverage currently. Example test:
server/api/views/uploadFile/test_title.py
To run tests:
docker compose exec backend python manage.py testNo test framework currently configured. Consider adding Jest/Vitest for future testing.
server/balancer_backend/settings.py- Django configuration (auth, database, CORS)server/balancer_backend/urls.py- Root URL configuration with dynamic importsfrontend/src/routes/routes.tsx- React Router configurationfrontend/src/services/store.tsx- Redux store setupdocker-compose.yml- Local development environmentconfig/env/dev.env.example- Environment variables template
- Python: Follow Django conventions, use class-based views (APIView)
- TypeScript: Use functional components with hooks, avoid default exports except for pages
- CSS: Prefer Tailwind utilities, use custom CSS only when necessary
- Git: Feature branches from
develop, PRs tolistOfMed - Code formatting: Prettier for frontend (with Tailwind plugin)