# Milestone 2: Initial Commit & Foundation

**Due:** 30.03.2026  
**Status:** Submitted

## What Got Built

The skeleton is up. Not pretty, not perfect, but it exists—and that's the point of this checkpoint.

We've got the core structure in place: Docker containers defined, basic authentication scaffolded, database schema created, and the load balancer configured. It doesn't run yet. That's fine. This milestone is about proving the architecture is sound before we wire everything together.

## Component Breakdown

### Backend Services

Two Node.js instances, identical in code but running as separate containers. Each one:

- Connects to PostgreSQL on startup
- Exposes health check endpoints for Traefik
- Has JWT middleware ready (not fully wired yet)
- Includes stock service stubs for fetching data

The instances are named `backend-a` and `backend-b`. Simple, boring, effective.

### Database Layer

PostgreSQL container with initialization scripts that run on first boot:

- **Users table**: `id`, `username`, `password_hash`, `created_at`
- **Stock prices table**: `symbol`, `price`, `change_percent`, `last_updated`

Connection pooling is configured but not stress-tested yet. That comes later.

### Load Balancer

Traefik configuration with:

- Health check interval: 10 seconds
- Failover threshold: 3 failed checks
- Round-robin distribution between instances
- Dashboard enabled on port 8080

The health checks hit `/health` on each backend. If an instance doesn't respond within 5 seconds, it's marked down.

### Frontend Stub

React app with basic routing and a login form. No real functionality yet—just the UI shell. The important part is the API client setup, which points to Traefik's load-balanced endpoint.

## Docker Compose Setup

Single command deployment is working: `docker compose up --build`

The compose file defines:

- Network isolation between services
- Volume mounts for PostgreSQL persistence
- Environment variables for configuration
- Dependency ordering (database starts first)

**Pro-tip:** The `depends_on` directive in Docker Compose doesn't wait for services to be _ready_, just _started_. We added health checks to ensure the database is actually accepting connections before backends try to connect.

## What's Not Working Yet

Let's be honest about the gaps:

- JWT generation works, but token validation isn't hooked up to all endpoints
- Stock data fetching is stubbed—returns hardcoded values
- Frontend can't actually communicate with backend yet (CORS not configured)
- No error handling to speak of
- Logs are a mess

This is expected. The goal was to get the structure right, not to ship production code.

## Key Decisions Made

**Why Traefik over Nginx?** Docker-native configuration. We define routing rules via labels in the compose file instead of managing separate config files. Less moving parts.

**Why PostgreSQL over Redis?** We need ACID guarantees for user data. Redis will come later for caching hot stock prices, but the source of truth stays in Postgres.

**Why two instances instead of three?** Simplicity. Two instances prove the failover concept. Adding a third doesn't teach us anything new at this stage.

## Next Steps

Wire up the authentication flow end-to-end. Get stock data flowing from Yahoo Finance. Make the frontend actually display something useful. Test failover manually by killing containers.

The foundation is solid. Now we build on it.
