Development Environment Setup
This guide covers setting up a local development environment for contributing to the OEC.sh platform. Follow these steps to get a fully functional development environment running on your machine.
Overview
OEC.sh uses a modern development stack:
| Component | Technology | Development Mode |
|---|---|---|
| Backend | FastAPI (Python 3.11) | Docker Compose |
| Frontend | Next.js 14 + TailAdmin | npm run dev (hot reload) |
| Database | PostgreSQL 15 | Docker container |
| Cache | Redis 7 | Docker container |
| Task Queue | ARQ | Docker container (Worker) |
Quick Start
Get up and running in under 5 minutes:
# 1. Clone the repository
git clone <repository-url>
cd 87-oecsh-pln
# 2. Setup virtual environment and install dependencies
make setup && source venv/bin/activate
# 3. Start backend services (database, redis, backend, worker)
docker compose -f docker-compose.prod.yml build backend
docker compose -f docker-compose.prod.yml up -d backend
# 4. Run database migrations
cd backend && alembic upgrade head && cd ..
# 5. Start frontend with hot reload
cd frontend && npm run devYour development environment is now running:
- Frontend: http://localhost:3000 (opens in a new tab)
- Backend API: http://localhost:8000 (opens in a new tab)
- API Docs: http://localhost:8000/docs (opens in a new tab)
Prerequisites
Before starting, ensure you have installed:
Required Software
| Software | Version | Installation |
|---|---|---|
| Python | 3.11+ | brew install [email protected] or system package manager |
| Node.js | 18+ LTS | brew install node or nodejs.org (opens in a new tab) |
| Docker | 24.0+ | docker.com/get-docker (opens in a new tab) |
| Docker Compose | 2.0+ | Included with Docker Desktop |
| Make | Any | Usually pre-installed on Linux/macOS |
| Git | 2.0+ | Pre-installed on most systems |
Verify Installation
# Check versions
python3 --version # Python 3.11.x
node --version # v18.x.x or higher
docker --version # Docker version 24.x.x
docker compose version # Docker Compose version v2.x.x
make --version # GNU Make 4.x
git --version # git version 2.x.xStep 1: Initial Setup
Clone Repository
git clone <repository-url>
cd 87-oecsh-plnSetup Virtual Environment
The make setup command handles Python virtual environment creation and dependency installation:
make setupThis command:
- Creates a Python virtual environment in
./venv - Installs backend dependencies from
requirements.txt - Installs development dependencies
Activate Virtual Environment
Important: Always activate the virtual environment before working on the backend:
source venv/bin/activateYou should see (venv) prefix in your terminal prompt.
Critical Rule: NEVER use system Python. Always work within the virtual environment.
Step 2: Environment Configuration
Environment File
OEC.sh uses .env.production for configuration. This file contains all environment variables for local development and production.
# Copy example if needed
cp .env.example .env.productionKey Environment Variables
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/oecsh
# Redis
REDIS_URL=redis://localhost:6379
# JWT Secret (generate a secure random string)
JWT_SECRET_KEY=your-secret-key-here
# Frontend URL
FRONTEND_URL=http://localhost:3000
# API URL
API_URL=http://localhost:8000Note: We are using .env.production for the current development work.
Step 3: Backend Development
Start Backend Services
The backend runs in Docker containers. Use Docker Compose to start all required services:
# Build backend image
docker compose -f docker-compose.prod.yml build backend
# Start backend and dependencies (postgres, redis, worker)
docker compose -f docker-compose.prod.yml up -d backendThis starts:
- PostgreSQL 15: Database on port 5432
- Redis 7: Cache/queue on port 6379
- Backend: FastAPI on port 8000
- Worker: ARQ background task processor
Verify Backend is Running
# Check container status
docker compose -f docker-compose.prod.yml ps
# View backend logs
docker compose -f docker-compose.prod.yml logs -f backend
# Test API endpoint
curl http://localhost:8000/api/v1/healthRebuild Backend After Code Changes
docker compose -f docker-compose.prod.yml build backend && \
docker compose -f docker-compose.prod.yml up -d backendImportant: After making backend code changes, you must rebuild and restart the container.
Step 4: Database Migrations
Run Migrations
Always run migrations before testing new database models:
cd backend && alembic upgrade headCreate New Migration
When you modify database models:
cd backend
alembic revision --autogenerate -m "Description of changes"Migration Best Practices
- Revision IDs: Must be 32 characters or less (alembic_version column limit)
- Column names: Check column names exist before referencing in migrations
- Field naming: Use
create_date(NOTcreated_at) forproject_environmentstable - Chain migrations: Set
down_revisionto previous migration ID
Step 5: Frontend Development
Install Dependencies
cd frontend
npm installStart Development Server
cd frontend && npm run devThis starts the Next.js development server with hot reload:
- URL: http://localhost:3000 (opens in a new tab)
- Hot Reload: Changes reflect instantly without page refresh
Critical Rule: NEVER rebuild Docker for frontend changes. Always use npm run dev for development.
Frontend Development Workflow
- Edit frontend code in
frontend/src/ - Changes automatically reflect in browser (hot reload)
- No restart or rebuild needed
Step 6: Running Tests
Backend Tests
Run the full test suite:
cd backend && pytest tests/ -vRun Specific Tests
# Run a specific test file
cd backend && pytest tests/test_environments.py -v
# Run tests matching a pattern
cd backend && pytest tests/ -k "test_create" -v
# Run with coverage
cd backend && pytest tests/ --cov=app --cov-report=htmlRBAC Security Tests
After any access rights changes, verify the RBAC matrix:
cd backend && pytest tests/security/test_rbac_matrix.py -vRBAC Test Users
For testing role-based access control, use these pre-configured test users:
Seed Test Users
Run the seed script to create test users:
docker exec oecsh-backend python /app/scripts/seed_test_users.pyTest Credentials
All test users belong to organization: rbac-test-org
| Role | Password | |
|---|---|---|
| [email protected] | Owner | TestUser123! |
| [email protected] | Admin | TestUser123! |
| [email protected] | Developer | TestUser123! |
| [email protected] | Viewer | TestUser123! |
Admin User
For full platform access:
| Password | |
|---|---|
| [email protected] | Admin123 |
Common Commands Reference
Quick Reference
# Setup
make setup && source venv/bin/activate
# Frontend (hot reload - use this for development)
cd frontend && npm run dev
# Backend (rebuild after changes)
docker compose -f docker-compose.prod.yml build backend && \
docker compose -f docker-compose.prod.yml up -d backend
# Database migrations
cd backend && alembic upgrade head
# Run tests
cd backend && pytest tests/ -v
# View logs
docker compose -f docker-compose.prod.yml logs -f backend
docker compose -f docker-compose.prod.yml logs -f worker
# Seed test users
docker exec oecsh-backend python /app/scripts/seed_test_users.pyDocker Commands
# Start all services
docker compose -f docker-compose.prod.yml up -d
# Stop all services
docker compose -f docker-compose.prod.yml down
# Restart a specific service
docker compose -f docker-compose.prod.yml restart backend
# View running containers
docker compose -f docker-compose.prod.yml ps
# Follow logs
docker compose -f docker-compose.prod.yml logs -f backend worker
# Execute command in container
docker exec -it oecsh-backend bashDevelopment Workflow
Typical Development Session
# 1. Start your session
source venv/bin/activate
# 2. Start backend services (if not running)
docker compose -f docker-compose.prod.yml up -d backend
# 3. Start frontend with hot reload
cd frontend && npm run dev
# 4. Make changes to code
# - Frontend changes: instant hot reload
# - Backend changes: rebuild required
# 5. Run tests before committing
cd backend && pytest tests/ -v
# 6. Commit when ready
git add -A && git commit -m "Description of changes"Backend Code Changes
When you modify backend code:
# Rebuild and restart backend
docker compose -f docker-compose.prod.yml build backend && \
docker compose -f docker-compose.prod.yml up -d backendDatabase Model Changes
When you modify SQLAlchemy models:
# 1. Create migration
cd backend && alembic revision --autogenerate -m "Add new field"
# 2. Apply migration
alembic upgrade head
# 3. Rebuild backend
docker compose -f docker-compose.prod.yml build backend && \
docker compose -f docker-compose.prod.yml up -d backendTroubleshooting
Virtual Environment Issues
Problem: ModuleNotFoundError or wrong Python version
Solution:
# Deactivate current venv
deactivate
# Remove old venv
rm -rf venv
# Recreate
make setup && source venv/bin/activateDatabase Connection Failed
Problem: Cannot connect to PostgreSQL
Solution:
# Check if postgres container is running
docker compose -f docker-compose.prod.yml ps postgres
# Restart postgres
docker compose -f docker-compose.prod.yml restart postgres
# Check postgres logs
docker compose -f docker-compose.prod.yml logs postgresPort Already in Use
Problem: Port 3000 or 8000 already in use
Solution:
# Find process using port
lsof -i :3000
lsof -i :8000
# Kill process
kill -9 <PID>Frontend Build Errors
Problem: npm install fails or build errors
Solution:
cd frontend
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Clear Next.js cache
rm -rf .next
npm run devBackend Container Won't Start
Problem: Backend container exits immediately
Solution:
# View error logs
docker compose -f docker-compose.prod.yml logs backend
# Common issues:
# - Missing environment variables
# - Database migration needed
# - Port conflict
# Fix and rebuild
docker compose -f docker-compose.prod.yml build backend
docker compose -f docker-compose.prod.yml up -d backendMigration Errors
Problem: Alembic migration fails
Solution:
# Check current migration status
cd backend && alembic current
# View migration history
alembic history
# If needed, reset to specific revision
alembic downgrade <revision_id>
alembic upgrade headCode Standards
Logging
Every function must include logging:
import logging
logger = logging.getLogger(__name__)
async def my_function():
logger.info("Starting operation", extra={"key": "value"})
try:
# ... code
logger.info("Operation completed successfully")
except Exception as e:
logger.error(f"Operation failed: {e}", exc_info=True)
raiseEnum Rules
Follow the 7 Golden Rules for enums (see backend/docs/ENUM_MEMORY_AND_RULES.md):
- Lowercase values:
PENDING = "pending" - Model = Schema values identical
- Use
values_callablein SQLEnum - No hardcoded strings
- Cast in migrations:
status::text - Check
hasattrbefore.value - Verify PostgreSQL types
# Correct pattern
class Status(enum.Enum):
PENDING = "pending"
ACTIVE = "active"
status = Column(SQLEnum(Status, values_callable=lambda obj: [e.value for e in obj]))
value = data.status.value if hasattr(data.status, "value") else data.statusField Mappings
Be aware of field name differences between layers:
| Database | Schema/API |
|---|---|
git_repo_url | repository_url |
git_branch | default_branch |
create_date | created_at (NOTE: NOT in project_environments table!) |
Next Steps
After setting up your development environment:
- Read the Architecture Guide - Understand the codebase structure
- Review RBAC Documentation - Learn about the permission system
- Check Open Issues - Find something to work on
- Run Full Test Suite - Ensure everything works before making changes
- Review PR Guidelines - Understand the contribution process
Related Documentation
- Introduction to OEC.SH - Platform overview
- API Reference - REST API documentation
- RBAC Permissions - Access control system
Last Updated: January 2026 Document Version: 1.0 Estimated Reading Time: 15 minutes