Skip to main content

Development Environment

Overview

HyperStudy uses a dedicated development environment that mirrors the production architecture but with reduced resources. This allows developers to test features, including horizontal scaling, without affecting production systems.

Architecture

The development environment runs in a separate Kubernetes namespace (hyperstudy-dev) with its own:

  • LoadBalancer (Traefik)
  • Domain (dev.hyperstudy.io)
  • Docker images (tagged as dev-latest)
  • Scaled-down resources

Resource Allocation

ComponentProductionDevelopmentPurpose
Backend Pods32Test horizontal scaling with minimal resources
Frontend Pods31Single instance sufficient for dev
Pod-Router21Basic routing functionality
Redis11State management
Traefik21Ingress controller

Deployment Workflow

Automatic Deployments

The development environment uses GitHub Actions for continuous deployment:

  1. Push to dev branch → Triggers deployment to development
  2. Push to main branch → Triggers deployment to production
graph LR
A[Push to dev branch] --> B[GitHub Actions]
B --> C[Build Images]
C --> D[Tag as dev-latest]
D --> E[Deploy to hyperstudy-dev]
E --> F[Available at dev.hyperstudy.io]

Manual Deployment

To manually trigger a deployment:

# From GitHub UI
1. Go to Actions → Deploy Application
2. Click "Run workflow"
3. Select branch: dev
4. Select environment: development
5. Click "Run workflow"

Working with the Dev Environment

Switching Between Branches

# Switch to dev branch
git checkout dev

# Make changes
git add .
git commit -m "Your changes"
git push origin dev # Triggers deployment

# Switch back to main
git checkout main

Checking Deployment Status

# View GitHub Actions status
gh run list --workflow=deploy-application.yml --limit 5

# Check dev namespace resources
kubectl get all -n hyperstudy-dev

# View pod logs
kubectl logs -n hyperstudy-dev deployment/backend

# Check pod-router logs
kubectl logs -n hyperstudy-dev deployment/pod-router

Testing Horizontal Scaling

The dev environment has 2 backend pods, allowing you to test:

  • Room-to-pod assignment
  • Participant routing
  • Cross-pod communication
  • Load distribution
# Scale backend pods (temporarily)
kubectl scale statefulset backend -n hyperstudy-dev --replicas=3

# Check room assignments
kubectl exec -n hyperstudy-dev redis-0 -- redis-cli KEYS "room:*:pod"

# Monitor pod distribution
for i in 0 1; do
echo "=== backend-$i ==="
kubectl logs backend-$i -n hyperstudy-dev --tail=10
done

Environment Variables

Development-Specific Settings

The dev environment automatically applies these configurations:

NODE_ENV: development
ENVIRONMENT: development
LOG_LEVEL: debug
CORS_ORIGIN: https://dev.hyperstudy.io
DISABLE_RATE_LIMITING: true
MAX_ROOMS_PER_POD: 5 # Reduced from 20
MAX_PARTICIPANTS_PER_POD: 20 # Reduced from 80

Firebase Configuration

Development uses the same Firebase project as production. Be careful when testing:

  • Use test accounts prefixed with dev_
  • Create test experiments with clear naming
  • Clean up test data regularly

Accessing Services

Public URLs

Internal Services

# Port-forward to access internal services
kubectl port-forward -n hyperstudy-dev svc/traefik-dashboard 8080:8080
# Access at http://localhost:8080

# Redis CLI
kubectl exec -it -n hyperstudy-dev redis-0 -- redis-cli

# Backend health check
kubectl exec -n hyperstudy-dev backend-0 -- curl localhost:3000/health

Debugging Tools

Debug Logger

The frontend includes a built-in debug logger (debugLogger.js) that provides an on-screen debug panel and persistent logging. This tool works even when console.log statements are stripped during the build process.

Features

  • Visible Debug Panel: Shows logs in an on-screen overlay
  • localStorage Persistence: Logs survive page refreshes
  • Export Capability: Download logs as JSON for analysis
  • Automatic in Development: Shows automatically when running in development mode

Usage

Import the debug logger in your component:

import debugLogger from '$lib/utils/debugLogger.js';

// Log a simple message
debugLogger.log('ComponentName', 'Something happened');

// Log with data
debugLogger.log('ComponentName', 'Config updated', { newConfig });

// Log complex objects
debugLogger.log('SparseRating', 'Video config changed', {
videoId: selectedVideoId,
distribution: videoConfig.distribution
});

Keyboard Shortcuts

  • Ctrl+Shift+D: Toggle debug panel visibility
  • The panel shows the last 20 log entries
  • Logs are automatically saved to localStorage

Viewing Logs

  1. On-Screen Panel

    • Appears at bottom-right of browser window
    • Black background with green text (terminal style)
    • Auto-scrolls to show latest entries
    • Click "Clear" button to reset logs
  2. Browser Console

    • Logs are also sent to console.log when available
    • Open DevTools (F12) to view console logs
  3. Export Logs

    // Export logs programmatically
    debugLogger.exportLogs(); // Downloads JSON file

    // Get logs array
    const logs = debugLogger.getLogs();
    console.log(logs);

Example: Debugging Sparse Rating Autosave

// In SparseRatingConfigEditor.svelte
import debugLogger from '$lib/utils/debugLogger.js';

function updateVideoConfig(videoId, path, value, immediate) {
debugLogger.log('SparseRating', `Updating ${path}`, { videoId, value });

const currentVideoConfig = getOrCreateVideoConfig(videoId, selectedStateId);
const updatedVideoConfig = setNestedValue(currentVideoConfig, path, value);

debugLogger.log('SparseRating', 'Updated config created', updatedVideoConfig);

const newConfig = createConfigUpdate(videoId, updatedVideoConfig);

if (immediate || !shouldDebounce(path)) {
debugLogger.log('SparseRating', 'Immediate save', newConfig);
updater.updateImmediate(newConfig);
} else {
debugLogger.log('SparseRating', 'Debounced save', newConfig);
updater.updateDebounced(newConfig, path);
}
}

Browser DevTools Console

If console logs are not appearing in the browser console after rebuilding the Docker image, check:

  1. Vite Configuration: Ensure mode === 'production' check in vite.config.js

    terserOptions: {
    compress: {
    drop_console: mode === 'production', // Only strip in production
    drop_debugger: mode === 'production'
    }
    }
  2. Rebuild Frontend Image: After changing Vite config

    # Trigger rebuild via GitHub Actions
    gh workflow run "Deploy Application" --ref dev

    # Or manually rebuild
    kubectl rollout restart deployment/frontend -n hyperstudy-dev
  3. Check Browser Console Settings:

    • Open DevTools (F12)
    • Go to Console tab
    • Ensure log levels are enabled (Info, Debug, etc.)
    • Clear "Hide network" and other filters

Debugging Tips

  1. Component Hierarchy: Use consistent component names

    debugLogger.log('ComponentName', message, data);
    // Examples: 'SparseRating', 'ComponentConfigPanel', 'GlobalComponentConfigurator'
  2. Update Chain: Log at each level to trace data flow

    // Child component
    debugLogger.log('Child', 'Sending update to parent', newData);

    // Parent component
    debugLogger.log('Parent', 'Received update from child', newData);
  3. Reactivity Issues: Log before/after derived state changes

    debugLogger.log('Component', 'Before derived update', { oldState });
    // ... state change ...
    debugLogger.log('Component', 'After derived update', { newState });
  4. Autosave Flow: Trace the complete save chain

    // Level 1: Child editor
    debugLogger.log('Editor', 'Config changed', config);

    // Level 2: Config panel
    debugLogger.log('ConfigPanel', 'Forwarding to parent', config);

    // Level 3: Configurator
    debugLogger.log('Configurator', 'Saving to backend', config);

Troubleshooting

Common Issues

Deployment Not Triggering

  • Ensure you're pushing to the dev branch
  • Check GitHub Actions is enabled for the repository
  • Verify secrets are configured in GitHub

Pods Not Starting

# Check pod status
kubectl get pods -n hyperstudy-dev

# Describe pod for events
kubectl describe pod <pod-name> -n hyperstudy-dev

# Check logs
kubectl logs <pod-name> -n hyperstudy-dev

DNS Not Resolving

  • Verify Cloudflare DNS points to: 159.203.149.180
  • Check IngressRoute configuration:
kubectl get ingressroute -n hyperstudy-dev

Images Not Found

# Check if images exist
doctl registry repository list-tags backend | grep dev-latest
doctl registry repository list-tags frontend | grep dev-latest

# Manually build and push if needed
docker build -t registry.digitalocean.com/hyperstudy/backend:dev-latest ./backend
docker push registry.digitalocean.com/hyperstudy/backend:dev-latest

Monitoring

Resource Usage

# Check resource consumption
kubectl top pods -n hyperstudy-dev

# View HPA status (if configured)
kubectl get hpa -n hyperstudy-dev

Logs Aggregation

# Stream all backend logs
kubectl logs -n hyperstudy-dev -l app=backend -f

# Stream pod-router logs
kubectl logs -n hyperstudy-dev deployment/pod-router -f

Cleanup

Temporary Scaling Down

# Scale down when not in use
kubectl scale deployment frontend -n hyperstudy-dev --replicas=0
kubectl scale statefulset backend -n hyperstudy-dev --replicas=0
kubectl scale deployment pod-router -n hyperstudy-dev --replicas=0

Complete Removal

# Delete all resources in dev namespace
kubectl delete all --all -n hyperstudy-dev

# Delete the namespace (removes everything)
kubectl delete namespace hyperstudy-dev

Best Practices

  1. Branch Management

    • Keep dev branch close to main
    • Regularly merge main into dev
    • Test features in dev before merging to main
  2. Data Isolation

    • Use test accounts for development
    • Prefix test data with dev_ or test_
    • Don't use production user accounts
  3. Resource Management

    • Scale down when not actively developing
    • Monitor resource usage to avoid waste
    • Clean up old test data regularly
  4. Testing

    • Test horizontal scaling with 2+ pods
    • Verify room assignments work correctly
    • Test failover scenarios

Configuration Files

The development environment configuration is located in:

k8s/environments/dev/
├── namespace.yaml # Namespace definition
├── kustomization.yaml # Kustomize configuration
├── scaling-patches.yaml # Resource scaling
├── config-patches.yaml # Environment variables
├── traefik-dev.yaml # Traefik LoadBalancer
└── ingress-dev.yaml # IngressRoute for dev.hyperstudy.io

CI/CD Pipeline

The GitHub Actions workflow (deploy-application.yml) automatically:

  1. Detects the branch (dev or main)
  2. Sets appropriate environment variables
  3. Builds Docker images with correct tags
  4. Deploys to the correct namespace
  5. Verifies deployment health

Environment Detection

if [[ "${{ github.ref }}" == "refs/heads/dev" ]]; then
ENVIRONMENT="development"
NAMESPACE="hyperstudy-dev"
IMAGE_TAG="dev-latest"
else
ENVIRONMENT="production"
NAMESPACE="hyperstudy"
IMAGE_TAG="latest"
fi