feat(refactor): convert from monolithic to hybrid

This commit is contained in:
jetli 2025-06-22 11:41:54 -07:00
parent 58595f2b4e
commit eb44c8ca1b
2 changed files with 1343 additions and 0 deletions

View File

@ -0,0 +1,398 @@
# DevBox Architecture Proposal: CLI + Microservices
## Overview
Transform DevBox from a monolithic CLI into a lightweight client that communicates with dedicated microservices for advanced features, providing better security, maintainability, and role-based access control.
## Current Problem
- **Security Risk**: All implementation exposed in downloadable CLI
- **Maintenance Burden**: Updates require CLI redistribution
- **No Access Control**: Anyone with CLI has access to all features
- **Scalability Issues**: CLI handles everything locally
- **Privacy Concerns**: Sensitive operations happen on client machines
## Proposed Solution
### Architecture Overview
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ DevBox CLI │ │ DevBox API │ │ Microservices │
│ (Lightweight) │◄──►│ Gateway │◄──►│ (Internal) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Local Setup │ │ Authentication │ │ Code Review │
│ Basic Commands │ │ Authorization │ │ CI/CD Pipeline │
│ Docker Mgmt │ │ Rate Limiting │ │ AI Services │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
## Component Breakdown
### 1. DevBox CLI (Lightweight Client)
**Responsibilities:**
- Basic local environment setup
- Docker container management
- Simple service start/stop/status
- API communication for advanced features
- Local configuration management
**Features:**
```bash
# Basic local operations (stay in CLI)
devbox init # Local environment setup
devbox start/stop/status # Container management
devbox deinit # Cleanup
# Advanced features (delegate to microservices)
devbox review --component=chat # → Code Review Service
devbox package --component=chat # → CI/CD Service
devbox deploy --env=staging # → Deployment Service
devbox ai --prompt="..." # → AI Service
```
### 2. DevBox API Gateway
**Responsibilities:**
- Authentication & Authorization
- Rate limiting
- Request routing
- API versioning
- Logging & monitoring
- SSL termination
**Authentication Flow:**
```
1. CLI authenticates with API Gateway
2. Gateway validates credentials
3. Gateway checks permissions for requested feature
4. Gateway routes request to appropriate microservice
5. Microservice processes request and returns result
```
### 3. Microservices Architecture
#### A. Code Review Service
- **Purpose**: OpenAI-powered code reviews
- **Endpoints**: `/api/v1/review/analyze`, `/api/v1/review/reports`
- **Permissions**: `code_review:read`, `code_review:write`
- **Features**:
- File analysis
- Report generation
- Historical tracking
- Team collaboration
#### B. CI/CD Pipeline Service
- **Purpose**: Build, test, and deployment automation
- **Endpoints**: `/api/v1/cicd/build`, `/api/v1/cicd/deploy`, `/api/v1/cicd/status`
- **Permissions**: `cicd:build`, `cicd:deploy`, `cicd:read`
- **Features**:
- Docker image building
- Integration testing
- Deployment management
- Pipeline orchestration
#### C. AI Services
- **Purpose**: AI-powered development assistance
- **Endpoints**: `/api/v1/ai/chat`, `/api/v1/ai/generate`, `/api/v1/ai/analyze`
- **Permissions**: `ai:chat`, `ai:generate`, `ai:analyze`
- **Features**:
- Code generation
- Documentation assistance
- Bug analysis
- Performance optimization
#### D. Authentication Service
- **Purpose**: User management and authentication
- **Endpoints**: `/api/v1/auth/login`, `/api/v1/auth/refresh`, `/api/v1/auth/permissions`
- **Features**:
- JWT token management
- Role-based access control
- Permission management
- Session handling
## Implementation Strategy
### Phase 1: CLI Refactoring
#### 1.1 Extract Core Features
```bash
# Keep in CLI (local operations)
- Environment setup (Docker, networking)
- Container management (start/stop/status)
- Basic configuration
- Local file operations
# Move to microservices
- Code review (OpenAI integration)
- CI/CD operations
- AI-powered features
- Deployment management
```
#### 1.2 Add API Communication Layer
```bash
# New CLI structure
devbox/
├── core/ # Local operations
├── api/ # API communication
├── auth/ # Authentication handling
├── config/ # Configuration management
└── commands/ # Command implementations
```
#### 1.3 Implement Authentication
```bash
# Authentication flow
devbox auth login --username=user --password=pass
devbox auth status
devbox auth logout
devbox auth refresh
```
### Phase 2: Microservices Development
#### 2.1 API Gateway
```yaml
# docker-compose.yml for development
version: '3.8'
services:
api-gateway:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./gateway/nginx.conf:/etc/nginx/nginx.conf
- ./gateway/ssl:/etc/nginx/ssl
depends_on:
- auth-service
- review-service
- cicd-service
- ai-service
auth-service:
build: ./services/auth
environment:
- JWT_SECRET=your-secret-key
- DATABASE_URL=postgresql://user:pass@db:5432/devbox
review-service:
build: ./services/review
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- REDIS_URL=redis://redis:6379
cicd-service:
build: ./services/cicd
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
- JENKINS_URL=${JENKINS_URL}
ai-service:
build: ./services/ai
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
```
#### 2.2 Service Communication
```bash
# CLI API calls
curl -X POST "https://api.devbox.com/v1/review/analyze" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"component": "chat",
"files": ["src/main.py", "src/utils.py"],
"options": {
"severity": ["critical", "warning"],
"include_suggestions": true
}
}'
```
### Phase 3: Role-Based Access Control
#### 3.1 Permission System
```yaml
# permissions.yaml
roles:
developer:
permissions:
- code_review:read
- cicd:build
- ai:chat
- ai:analyze
senior_developer:
permissions:
- code_review:read
- code_review:write
- cicd:build
- cicd:deploy
- ai:chat
- ai:analyze
- ai:generate
devops:
permissions:
- cicd:build
- cicd:deploy
- cicd:admin
- deployment:read
- deployment:write
admin:
permissions:
- "*" # All permissions
```
#### 3.2 Feature Access Control
```bash
# CLI checks permissions before making API calls
devbox review --component=chat
# CLI checks: user has 'code_review:read' permission
# If yes: proceed with API call
# If no: show permission denied error
devbox deploy --environment=production
# CLI checks: user has 'cicd:deploy' permission
# If yes: proceed with deployment
# If no: show permission denied error
```
## Security Benefits
### 1. **Code Protection**
- Sensitive implementation hidden in microservices
- CLI only contains basic setup and API communication
- No exposure of AI prompts, CI/CD logic, or security configurations
### 2. **Access Control**
- Role-based permissions for different features
- Authentication required for advanced operations
- Audit trails for all API calls
- Rate limiting to prevent abuse
### 3. **Data Privacy**
- Sensitive data processed on secure servers
- No local storage of API keys or credentials
- Encrypted communication between CLI and services
- Compliance with data protection regulations
## Maintenance Benefits
### 1. **Independent Updates**
- Microservices can be updated independently
- CLI updates only needed for basic functionality
- Feature rollouts without CLI redistribution
- A/B testing capabilities
### 2. **Scalability**
- Services can be scaled independently
- Load balancing across multiple instances
- Geographic distribution for better performance
- Resource optimization based on usage patterns
### 3. **Monitoring & Analytics**
- Centralized logging and monitoring
- Usage analytics and insights
- Performance metrics for each service
- Error tracking and alerting
## Migration Strategy
### Step 1: CLI Refactoring (Week 1-2)
```bash
# 1. Extract API communication layer
# 2. Add authentication handling
# 3. Implement permission checking
# 4. Create service stubs for testing
```
### Step 2: Basic Microservices (Week 3-4)
```bash
# 1. Set up API Gateway
# 2. Implement Authentication Service
# 3. Create Code Review Service
# 4. Add basic CI/CD Service
```
### Step 3: Advanced Features (Week 5-6)
```bash
# 1. Implement AI Services
# 2. Add comprehensive RBAC
# 3. Set up monitoring and logging
# 4. Performance optimization
```
### Step 4: Production Deployment (Week 7-8)
```bash
# 1. Security hardening
# 2. Load testing
# 3. Documentation updates
# 4. User training and migration
```
## CLI Commands After Migration
### Basic Commands (Local)
```bash
devbox init # Local environment setup
devbox start --component=chat # Start local containers
devbox stop --component=chat # Stop local containers
devbox status # Show local status
devbox deinit # Cleanup local environment
```
### Authentication Commands
```bash
devbox auth login # Authenticate with DevBox API
devbox auth status # Show authentication status
devbox auth logout # Logout from DevBox API
devbox auth refresh # Refresh authentication token
```
### Advanced Commands (API-based)
```bash
devbox review --component=chat # AI-powered code review
devbox package --component=chat # Build and package code
devbox deploy --env=staging # Deploy to environment
devbox ai --prompt="..." # AI assistance
devbox pipeline --action=build # CI/CD pipeline operations
```
### Configuration Commands
```bash
devbox config set api.url=https://api.devbox.com
devbox config set auth.token=your-token
devbox config show # Show current configuration
devbox config reset # Reset to defaults
```
## Benefits Summary
### For Platform Developers
- **Security**: Sensitive code protected in microservices
- **Control**: Role-based access to features
- **Analytics**: Usage insights and monitoring
- **Scalability**: Independent service scaling
### For End Users
- **Privacy**: Secure processing of sensitive data
- **Performance**: Optimized service delivery
- **Reliability**: Centralized monitoring and support
- **Features**: Access to advanced AI and CI/CD capabilities
### For Maintenance
- **Updates**: Independent service updates
- **Monitoring**: Centralized logging and alerting
- **Support**: Better error tracking and resolution
- **Compliance**: Audit trails and security controls
This architecture provides the perfect balance between functionality, security, and maintainability while enabling future growth and feature expansion.

View File

@ -0,0 +1,945 @@
# DevBox Implementation Plan: CLI to Microservices
## Phase 1: CLI Refactoring
### 1.1 New CLI Structure
```
devbox/
├── core/ # Local operations only
│ ├── docker.sh # Docker management
│ ├── network.sh # Network setup
│ ├── validation.sh # Environment validation
│ └── utils.sh # Common utilities
├── api/ # API communication
│ ├── client.sh # HTTP client wrapper
│ ├── auth.sh # Authentication handling
│ ├── review.sh # Code review API calls
│ ├── cicd.sh # CI/CD API calls
│ └── ai.sh # AI service API calls
├── auth/ # Authentication management
│ ├── login.sh # Login functionality
│ ├── token.sh # Token management
│ └── permissions.sh # Permission checking
├── config/ # Configuration management
│ ├── settings.sh # Settings management
│ ├── profiles.sh # Profile management
│ └── defaults.sh # Default configurations
└── commands/ # Command implementations
├── init.sh # Local init command
├── start.sh # Local start command
├── review.sh # Review command (API-based)
├── package.sh # Package command (API-based)
└── deploy.sh # Deploy command (API-based)
```
### 1.2 API Client Implementation
```bash
# api/client.sh
#!/usr/bin/env bash
# API client configuration
API_BASE_URL="${DEVBOX_API_URL:-https://api.devbox.com}"
API_VERSION="v1"
API_TIMEOUT=30
# HTTP client with authentication
api_request() {
local method="$1"
local endpoint="$2"
local data="$3"
local token="$4"
local url="${API_BASE_URL}/api/${API_VERSION}${endpoint}"
local headers=(
"Content-Type: application/json"
"User-Agent: DevBox-CLI/1.0"
)
if [[ -n "$token" ]]; then
headers+=("Authorization: Bearer $token")
fi
local curl_opts=(
"-X" "$method"
"-H" "${headers[0]}"
"-H" "${headers[1]}"
"--connect-timeout" "$API_TIMEOUT"
"--max-time" "$API_TIMEOUT"
"-s"
)
if [[ -n "$token" ]]; then
curl_opts+=("-H" "${headers[2]}")
fi
if [[ -n "$data" ]]; then
curl_opts+=("-d" "$data")
fi
curl "${curl_opts[@]}" "$url"
}
# API response handling
handle_api_response() {
local response="$1"
local expected_status="$2"
if [[ -z "$response" ]]; then
log_error "No response from API"
return 1
fi
local status=$(echo "$response" | jq -r '.status // .error // "unknown"')
local message=$(echo "$response" | jq -r '.message // .error // "Unknown error"')
if [[ "$status" == "$expected_status" ]] || [[ "$status" == "success" ]]; then
echo "$response"
return 0
else
log_error "API Error: $message"
return 1
fi
}
```
### 1.3 Authentication Implementation
```bash
# auth/login.sh
#!/usr/bin/env bash
devbox_auth_login() {
local username="$1"
local password="$2"
local api_key="$3"
log_info "Authenticating with DevBox API..."
# Prepare login payload
local login_data=$(cat << EOF
{
"username": "$username",
"password": "$password",
"api_key": "$api_key"
}
EOF
)
# Make login request
local response=$(api_request "POST" "/auth/login" "$login_data")
if handle_api_response "$response" "success"; then
local token=$(echo "$response" | jq -r '.token')
local refresh_token=$(echo "$response" | jq -r '.refresh_token')
local permissions=$(echo "$response" | jq -r '.permissions')
# Store tokens securely
store_auth_tokens "$token" "$refresh_token"
store_permissions "$permissions"
log_info "Authentication successful"
return 0
else
return 1
fi
}
# auth/token.sh
#!/usr/bin/env bash
store_auth_tokens() {
local token="$1"
local refresh_token="$2"
# Store in secure location
local config_dir="$HOME/.devbox"
mkdir -p "$config_dir"
# Encrypt tokens before storing
echo "$token" | openssl enc -aes-256-cbc -salt -out "$config_dir/.token" -pass pass:"$DEVBOX_ENCRYPTION_KEY"
echo "$refresh_token" | openssl enc -aes-256-cbc -salt -out "$config_dir/.refresh_token" -pass pass:"$DEVBOX_ENCRYPTION_KEY"
# Set file permissions
chmod 600 "$config_dir/.token" "$config_dir/.refresh_token"
}
get_auth_token() {
local config_dir="$HOME/.devbox"
if [[ -f "$config_dir/.token" ]]; then
openssl enc -aes-256-cbc -d -in "$config_dir/.token" -pass pass:"$DEVBOX_ENCRYPTION_KEY" 2>/dev/null
fi
}
refresh_auth_token() {
local refresh_token=$(openssl enc -aes-256-cbc -d -in "$HOME/.devbox/.refresh_token" -pass pass:"$DEVBOX_ENCRYPTION_KEY" 2>/dev/null)
if [[ -n "$refresh_token" ]]; then
local refresh_data=$(cat << EOF
{
"refresh_token": "$refresh_token"
}
EOF
)
local response=$(api_request "POST" "/auth/refresh" "$refresh_data")
if handle_api_response "$response" "success"; then
local new_token=$(echo "$response" | jq -r '.token')
local new_refresh_token=$(echo "$response" | jq -r '.refresh_token')
store_auth_tokens "$new_token" "$new_refresh_token"
return 0
fi
fi
return 1
}
```
### 1.4 Permission Checking
```bash
# auth/permissions.sh
#!/usr/bin/env bash
check_permission() {
local required_permission="$1"
local user_permissions="$2"
# Check if user has wildcard permission
if [[ "$user_permissions" == *"*"* ]]; then
return 0
fi
# Check specific permission
if [[ "$user_permissions" == *"$required_permission"* ]]; then
return 0
fi
return 1
}
require_permission() {
local permission="$1"
local operation="$2"
local user_permissions=$(get_user_permissions)
if ! check_permission "$permission" "$user_permissions"; then
log_error "Permission denied: $permission required for $operation"
log_error "Contact your administrator to request access"
return 1
fi
return 0
}
get_user_permissions() {
local config_dir="$HOME/.devbox"
if [[ -f "$config_dir/.permissions" ]]; then
cat "$config_dir/.permissions"
fi
}
```
### 1.5 API-based Commands
```bash
# commands/review.sh
#!/usr/bin/env bash
devbox_review_command() {
local component="$1"
local options="$2"
log_info "Starting code review for $component..."
# Check permissions
if ! require_permission "code_review:read" "code review"; then
exit 1
fi
# Get authentication token
local token=$(get_auth_token)
if [[ -z "$token" ]]; then
log_error "Not authenticated. Run 'devbox auth login' first."
exit 1
fi
# Prepare review request
local review_data=$(prepare_review_data "$component" "$options")
# Make API request
local response=$(api_request "POST" "/review/analyze" "$review_data" "$token")
if handle_api_response "$response" "success"; then
local report_url=$(echo "$response" | jq -r '.report_url')
local report_id=$(echo "$response" | jq -r '.report_id')
log_info "Code review completed successfully"
log_info "Report ID: $report_id"
log_info "View report at: $report_url"
# Open report in browser if possible
if command -v xdg-open &>/dev/null; then
xdg-open "$report_url"
elif command -v open &>/dev/null; then
open "$report_url"
fi
return 0
else
return 1
fi
}
prepare_review_data() {
local component="$1"
local options="$2"
# Get changed files
local changed_files=$(get_changed_files "$component")
# Prepare file contents
local files_data="[]"
while IFS= read -r file; do
if [[ -f "$file" ]]; then
local content=$(cat "$file" | jq -R -s .)
local file_info=$(cat << EOF
{
"path": "$file",
"content": $content
}
EOF
)
files_data=$(echo "$files_data" | jq ". += [$file_info]")
fi
done <<< "$changed_files"
# Create review request
cat << EOF
{
"component": "$component",
"files": $files_data,
"options": $options
}
EOF
}
```
## Phase 2: Microservices Implementation
### 2.1 API Gateway (Nginx)
```nginx
# gateway/nginx.conf
events {
worker_connections 1024;
}
http {
upstream auth_service {
server auth-service:8001;
}
upstream review_service {
server review-service:8002;
}
upstream cicd_service {
server cicd-service:8003;
}
upstream ai_service {
server ai-service:8004;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
listen 80;
server_name api.devbox.com;
# SSL configuration (for production)
# listen 443 ssl;
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# Rate limiting
limit_req zone=api burst=20 nodelay;
# Authentication endpoints
location /api/v1/auth/ {
proxy_pass http://auth_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Code review endpoints
location /api/v1/review/ {
auth_request /auth/validate;
proxy_pass http://review_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# CI/CD endpoints
location /api/v1/cicd/ {
auth_request /auth/validate;
proxy_pass http://cicd_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# AI service endpoints
location /api/v1/ai/ {
auth_request /auth/validate;
proxy_pass http://ai_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Authentication validation
location = /auth/validate {
internal;
proxy_pass http://auth_service/api/v1/auth/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
}
```
### 2.2 Authentication Service (Python/FastAPI)
```python
# services/auth/main.py
from fastapi import FastAPI, HTTPException, Depends, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel
import jwt
import datetime
from typing import List, Optional
import redis
import os
app = FastAPI(title="DevBox Auth Service")
security = HTTPBearer()
# Configuration
JWT_SECRET = os.getenv("JWT_SECRET", "your-secret-key")
JWT_ALGORITHM = "HS256"
JWT_EXPIRY = 3600 # 1 hour
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379")
# Redis connection
redis_client = redis.from_url(REDIS_URL)
# Models
class LoginRequest(BaseModel):
username: str
password: str
api_key: Optional[str] = None
class TokenResponse(BaseModel):
token: str
refresh_token: str
permissions: List[str]
expires_in: int
class PermissionCheck(BaseModel):
permission: str
user_id: str
# Permission definitions
PERMISSIONS = {
"developer": [
"code_review:read",
"cicd:build",
"ai:chat",
"ai:analyze"
],
"senior_developer": [
"code_review:read",
"code_review:write",
"cicd:build",
"cicd:deploy",
"ai:chat",
"ai:analyze",
"ai:generate"
],
"devops": [
"cicd:build",
"cicd:deploy",
"cicd:admin",
"deployment:read",
"deployment:write"
],
"admin": ["*"]
}
@app.post("/api/v1/auth/login", response_model=TokenResponse)
async def login(request: LoginRequest):
# Validate credentials (implement your authentication logic)
if not validate_credentials(request.username, request.password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials"
)
# Get user role and permissions
user_role = get_user_role(request.username)
permissions = PERMISSIONS.get(user_role, [])
# Generate tokens
token = create_access_token(request.username, permissions)
refresh_token = create_refresh_token(request.username)
# Store refresh token in Redis
redis_client.setex(
f"refresh_token:{request.username}",
JWT_EXPIRY * 24, # 24 hours
refresh_token
)
return TokenResponse(
token=token,
refresh_token=refresh_token,
permissions=permissions,
expires_in=JWT_EXPIRY
)
@app.post("/api/v1/auth/refresh")
async def refresh_token(refresh_token: str):
try:
payload = jwt.decode(refresh_token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
username = payload.get("sub")
# Verify refresh token in Redis
stored_token = redis_client.get(f"refresh_token:{username}")
if not stored_token or stored_token.decode() != refresh_token:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid refresh token"
)
# Generate new tokens
user_role = get_user_role(username)
permissions = PERMISSIONS.get(user_role, [])
new_token = create_access_token(username, permissions)
new_refresh_token = create_refresh_token(username)
# Update stored refresh token
redis_client.setex(
f"refresh_token:{username}",
JWT_EXPIRY * 24,
new_refresh_token
)
return {
"token": new_token,
"refresh_token": new_refresh_token,
"expires_in": JWT_EXPIRY
}
except jwt.ExpiredSignatureError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Refresh token expired"
)
except jwt.InvalidTokenError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid refresh token"
)
@app.get("/api/v1/auth/validate")
async def validate_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
try:
payload = jwt.decode(credentials.credentials, JWT_SECRET, algorithms=[JWT_ALGORITHM])
username = payload.get("sub")
permissions = payload.get("permissions", [])
if not username:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
)
return {
"user_id": username,
"permissions": permissions,
"valid": True
}
except jwt.ExpiredSignatureError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token expired"
)
except jwt.InvalidTokenError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
)
def create_access_token(username: str, permissions: List[str]) -> str:
payload = {
"sub": username,
"permissions": permissions,
"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=JWT_EXPIRY),
"iat": datetime.datetime.utcnow()
}
return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
def create_refresh_token(username: str) -> str:
payload = {
"sub": username,
"type": "refresh",
"exp": datetime.datetime.utcnow() + datetime.timedelta(days=1),
"iat": datetime.datetime.utcnow()
}
return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
def validate_credentials(username: str, password: str) -> bool:
# Implement your authentication logic here
# This could be database lookup, LDAP, etc.
return True # Placeholder
def get_user_role(username: str) -> str:
# Implement role lookup logic
return "developer" # Placeholder
```
### 2.3 Code Review Service (Python/FastAPI)
```python
# services/review/main.py
from fastapi import FastAPI, HTTPException, Depends, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel
import openai
import redis
import json
import os
from typing import List, Dict, Any
import uuid
from datetime import datetime
app = FastAPI(title="DevBox Code Review Service")
security = HTTPBearer()
# Configuration
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379")
# Initialize OpenAI
openai.api_key = OPENAI_API_KEY
# Redis connection
redis_client = redis.from_url(REDIS_URL)
# Models
class FileContent(BaseModel):
path: str
content: str
class ReviewRequest(BaseModel):
component: str
files: List[FileContent]
options: Dict[str, Any]
class ReviewResponse(BaseModel):
report_id: str
report_url: str
status: str
@app.post("/api/v1/review/analyze", response_model=ReviewResponse)
async def analyze_code(
request: ReviewRequest,
credentials: HTTPAuthorizationCredentials = Depends(security)
):
# Validate permissions
if not has_permission(credentials.credentials, "code_review:read"):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Permission denied: code_review:read required"
)
# Generate report ID
report_id = str(uuid.uuid4())
# Prepare files content for OpenAI
files_content = ""
for file in request.files:
files_content += f"\n\n=== File: {file.path} ===\n"
files_content += file.content
# Generate review prompt
prompt = generate_review_prompt(request.component, files_content)
try:
# Call OpenAI API
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "user", "content": prompt}
],
max_tokens=4000,
temperature=0.1
)
review_content = response.choices[0].message.content
# Parse and structure the review
structured_review = parse_review_content(review_content, request.component)
# Store review in Redis
review_data = {
"report_id": report_id,
"component": request.component,
"review": structured_review,
"timestamp": datetime.utcnow().isoformat(),
"files_analyzed": len(request.files)
}
redis_client.setex(
f"review:{report_id}",
86400, # 24 hours
json.dumps(review_data)
)
# Generate report URL
report_url = f"https://api.devbox.com/reports/{report_id}"
return ReviewResponse(
report_id=report_id,
report_url=report_url,
status="completed"
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Review failed: {str(e)}"
)
@app.get("/api/v1/review/reports/{report_id}")
async def get_report(
report_id: str,
credentials: HTTPAuthorizationCredentials = Depends(security)
):
# Validate permissions
if not has_permission(credentials.credentials, "code_review:read"):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Permission denied: code_review:read required"
)
# Get report from Redis
report_data = redis_client.get(f"review:{report_id}")
if not report_data:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Report not found"
)
return json.loads(report_data)
def generate_review_prompt(component: str, files_content: str) -> str:
return f"""
You are an expert code reviewer with deep knowledge of software engineering best practices, security, performance, and maintainability. Please review the following code changes for the {component} component.
**Review Guidelines:**
1. **Security**: Identify potential security vulnerabilities, input validation issues, authentication/authorization problems
2. **Performance**: Look for inefficient algorithms, memory leaks, database query issues, scalability concerns
3. **Code Quality**: Check for code smells, maintainability issues, readability problems, naming conventions
4. **Best Practices**: Verify adherence to language-specific best practices, design patterns, SOLID principles
5. **Error Handling**: Assess error handling, exception management, logging practices
6. **Testing**: Evaluate test coverage, test quality, mocking practices
7. **Documentation**: Check for proper documentation, comments, API documentation
**Review Format:**
For each issue found, provide:
- **Severity**: CRITICAL, WARNING, INFO, or SUGGESTION
- **Title**: Brief description of the issue
- **Description**: Detailed explanation of the problem
- **Line Number**: Specific line where the issue occurs (if applicable)
- **Code Snippet**: Relevant code section (if applicable)
- **Suggestion**: Specific recommendation for improvement
**Code to Review:**
{files_content}
Please provide a comprehensive review focusing on the most important issues first. Be specific and actionable in your recommendations.
"""
def parse_review_content(content: str, component: str) -> Dict[str, Any]:
# This is a simplified parser - you might want to enhance it
return {
"component": component,
"raw_content": content,
"issues": [], # Parse structured issues from content
"summary": {
"critical_issues": 0,
"warnings": 0,
"suggestions": 0
}
}
def has_permission(token: str, required_permission: str) -> bool:
# Implement permission checking logic
# This would decode the JWT and check permissions
return True # Placeholder
```
## Phase 3: Migration Script
```bash
# migration/migrate.sh
#!/usr/bin/env bash
migrate_to_microservices() {
log_info "Starting DevBox migration to microservices architecture..."
# Backup current CLI
backup_current_cli
# Install new lightweight CLI
install_new_cli
# Migrate configuration
migrate_configuration
# Test new setup
test_new_setup
log_info "Migration completed successfully!"
}
backup_current_cli() {
local backup_dir="$HOME/.devbox/backup/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
log_info "Backing up current CLI to $backup_dir"
# Copy current CLI files
cp -r /usr/local/bin/devbox "$backup_dir/"
cp -r "$HOME/.devbox" "$backup_dir/config"
log_info "Backup completed"
}
install_new_cli() {
log_info "Installing new lightweight CLI..."
# Download new CLI
curl -L -o /tmp/devbox-new "https://api.devbox.com/download/cli/latest"
chmod +x /tmp/devbox-new
# Install new CLI
sudo mv /tmp/devbox-new /usr/local/bin/devbox
log_info "New CLI installed"
}
migrate_configuration() {
log_info "Migrating configuration..."
local old_config="$HOME/.devbox"
local new_config="$HOME/.devbox-v2"
# Create new config structure
mkdir -p "$new_config"
# Migrate basic settings
if [[ -f "$old_config/config.yaml" ]]; then
cp "$old_config/config.yaml" "$new_config/"
fi
# Set up API configuration
cat > "$new_config/api.yaml" << EOF
api:
url: "https://api.devbox.com"
version: "v1"
timeout: 30
auth:
token_file: "$new_config/.token"
refresh_token_file: "$new_config/.refresh_token"
permissions_file: "$new_config/.permissions"
EOF
log_info "Configuration migrated"
}
test_new_setup() {
log_info "Testing new setup..."
# Test basic commands
if devbox --version; then
log_info "✓ CLI installation test passed"
else
log_error "✗ CLI installation test failed"
return 1
fi
# Test authentication
if devbox auth status; then
log_info "✓ Authentication test passed"
else
log_warn "⚠ Authentication not configured (expected for new setup)"
fi
log_info "New setup test completed"
}
```
## Benefits of This Implementation
### 1. **Security**
- Sensitive code protected in microservices
- Role-based access control
- Encrypted token storage
- Audit trails for all operations
### 2. **Maintainability**
- Independent service updates
- Centralized configuration
- Easy feature rollouts
- Better error tracking
### 3. **Scalability**
- Services can scale independently
- Load balancing support
- Geographic distribution
- Resource optimization
### 4. **User Experience**
- Seamless migration
- Same familiar commands
- Enhanced features
- Better performance
This implementation provides a solid foundation for transforming DevBox into a secure, scalable, and maintainable platform while preserving the user experience.