# Technology Stack

This document outlines GridPilot's technology choices and their rationale. For architectural patterns and layer organization, see [ARCHITECTURE.md](./ARCHITECTURE.md).

## 1. Language & Runtime

### TypeScript (Strict Mode)
- **Version:** Latest stable (5.x+)
- **Configuration:** `strict: true`, no `any` types permitted
- **Rationale:** Type safety catches errors at compile time, improves IDE support, and serves as living documentation. Strict mode eliminates common type-related bugs and enforces explicit handling of null/undefined.

### Node.js LTS
- **Version:** >=20.0.0
- **Rationale:** Long-term support ensures stability and security patches. Modern features (fetch API, native test runner) reduce dependency overhead. Version 20+ provides performance improvements critical for real-time race monitoring.

## 2. Backend Framework

### Current Status: Under Evaluation
Three candidates align with Clean Architecture principles:

**Option A: Express**
- **Pros:** Mature ecosystem, extensive middleware, proven at scale
- **Cons:** Slower than modern alternatives, callback-heavy patterns
- **Use Case:** Best if stability and middleware availability are priorities

**Option B: Fastify**
- **Pros:** High performance, schema-based validation, modern async/await
- **Cons:** Smaller ecosystem than Express
- **Use Case:** Best for performance-critical endpoints (real-time race data)

**Option C: Hono**
- **Pros:** Ultra-lightweight, edge-ready, excellent TypeScript support
- **Cons:** Newest option, smaller community
- **Use Case:** Best for modern deployment targets (Cloudflare Workers, edge functions)

**Requirements (All Options):**
- HTTP server with middleware support
- OpenAPI/Swagger compatibility
- JSON schema validation
- WebSocket support (for real-time features)

**Decision Timeline:** Deferred to implementation phase based on deployment target selection.

## 3. Frontend Framework

### Current Status: Under Evaluation
Two candidates meet accessibility and performance requirements:

**Option A: React 18+ with Vite**
- **Pros:** Maximum flexibility, fast HMR, lightweight bundle
- **Cons:** Manual SEO optimization, client-side routing complexity
- **Use Case:** Best for dashboard-heavy, interactive UI (primary use case)

**Option B: Next.js 14+**
- **Pros:** Built-in SSR/SSG, file-based routing, image optimization
- **Cons:** Larger bundle, more opinionated
- **Use Case:** Best if public league pages require SEO

**Shared Dependencies:**
- **State Management:**
  - TanStack Query: Server state (caching, optimistic updates, real-time sync)
  - Zustand: Client state (UI preferences, form state)
  - Rationale: Separation of concerns prevents state management spaghetti
- **UI Library:**
  - Tailwind CSS: Utility-first styling, design system consistency
  - shadcn/ui: Accessible components (WCAG 2.1 AA), copy-paste philosophy
  - Radix UI primitives: Unstyled, accessible foundations
  - Rationale: Rapid development without sacrificing accessibility or customization
- **Forms:** React Hook Form + Zod schemas (type-safe validation)
- **Routing:** React Router (Option A) or Next.js file-based routing (Option B)

**Decision Timeline:** Deferred to implementation phase. Leaning toward Option A (React + Vite) given dashboard-centric use case.

## 4. Database

### PostgreSQL 15+
- **Rationale:**
  - Complex relationships (leagues → seasons → races → drivers → teams) require relational integrity
  - JSONB columns handle flexible metadata (iRacing session results, custom league rules)
  - Full-text search for driver/team lookups
  - Battle-tested at scale, excellent TypeScript ORM support
- **Features Used:**
  - Foreign keys with cascading deletes
  - Check constraints (business rule validation)
  - Indexes on frequently queried fields (league_id, race_date)
  - Row-level security (multi-tenant data isolation)

### ORM: Under Evaluation

**Option A: Prisma**
- **Pros:** Type-safe queries, automatic migrations, excellent DX
- **Cons:** Additional build step, limited raw SQL for complex queries
- **Use Case:** Best for rapid development, type safety priority

**Option B: TypeORM**
- **Pros:** Decorators, Active Record pattern, SQL flexibility
- **Cons:** Older API design, less type-safe than Prisma
- **Use Case:** Best if complex SQL queries are frequent

**Decision Timeline:** Deferred to implementation phase. Both integrate cleanly with Clean Architecture (repository pattern at infrastructure layer).

## 5. Authentication

### iRacing OAuth Flow
- **Provider:** iRacing official OAuth 2.0
- **Rationale:** Official integration ensures compliance with iRacing Terms of Service. Users trust official credentials over third-party passwords.
- **Flow:** Authorization Code with PKCE (Proof Key for Code Exchange)

### Session Management
- **JWT:** Stateless tokens for API authentication
- **Storage:** HTTP-only cookies (XSS protection), encrypted at rest
- **Refresh Strategy:** Short-lived access tokens (15 min), long-lived refresh tokens (7 days)

### Implementation
- **Passport.js:** OAuth strategy handling, pluggable architecture
- **bcrypt:** Fallback password hashing (if local accounts added later)
- **Rationale:** Passport's strategy pattern aligns with Clean Architecture (adapter layer). Well-tested, extensive documentation.

## 6. Automation (Companion App)

### Electron
- **Version:** Latest stable (28.x+)
- **Rationale:** Cross-platform desktop framework (Windows, macOS, Linux). Native OS integration (system tray, notifications, auto-start).
- **Security:** Isolated renderer processes, context bridge for IPC

### Playwright (Browser Automation)
- **Purpose:** Automate the iRacing website (members.iracing.com) via DOM manipulation
- **Rationale:** Standard browser automation for the iRacing web interface. The iRacing website is a standard HTML/DOM application that can be automated with Playwright. This is 100% legal and the only approach GridPilot uses.
- **Key Features:**
  - Cross-browser support (Chromium, Firefox, WebKit)
  - Auto-wait for elements (eliminates flaky tests)
  - Network interception for testing
  - Screenshot/video capture for debugging

### Important: iRacing Automation Rules
- **✅ Allowed:** Browser automation of members.iracing.com (standard web application)
- **❌ Forbidden:** DOM automation inside the iRacing Electron desktop app (TOS violation)
- **❌ Forbidden:** Script injection or client modification (like iRefined)

### Electron IPC
- **Main ↔ Renderer:** Type-safe message passing via preload scripts
- **Rationale:** Security (no direct Node.js access in renderer), type safety (Zod schemas for IPC contracts)

### Auto-Updates
- **electron-updater:** Handles signed updates, delta downloads
- **Rationale:** Critical for security patches, seamless user experience

**Why This Approach:**
- Assistant-style automation (user-initiated), not gameplay bots
- Complements web app (handles tasks iRacing API doesn't expose)
- Desktop integration (notifications for upcoming races, quick access via system tray)
- Browser automation is reliable and testable

## 7. Testing Tools

### Unit & Integration: Vitest
- **Rationale:** Native TypeScript support, fast execution (ESM, watch mode), compatible with Vite ecosystem
- **Coverage:** Built-in coverage reports (Istanbul), enforces 80% threshold

### E2E: Playwright
- **Rationale:** Reliable browser automation, cross-browser testing (Chromium, Firefox, WebKit), built-in wait strategies
- **Features:** Screenshot/video on failure, network mocking, parallel execution

### Test Containers (Docker)
- **Purpose:** Isolated test databases, Redis instances
- **Rationale:** Prevents test pollution, matches production environment, automatic cleanup
- **Services:** PostgreSQL, Redis, S3 (MinIO)

**Testing Strategy:**
- Unit tests: Core domain logic (pure functions, business rules)
- Integration tests: Repository implementations, API endpoints
- E2E tests: Critical user flows (create league, register for race, view results)

## 8. DevOps & Infrastructure

### Docker & Docker Compose
- **Purpose:** Local development, E2E testing, consistent environments
- **Services:**
  - PostgreSQL (primary database)
  - Redis (caching, rate limiting, job queue)
  - MinIO (S3-compatible storage for local dev)
- **Rationale:** Developers get production-like environment instantly

### Redis
- **Use Cases:**
  - Caching (league standings, frequently accessed driver stats)
  - Rate limiting (API throttling, abuse prevention)
  - Bull queue (background jobs: race result processing, email notifications)
- **Rationale:** Proven performance, simple key-value model, pub/sub for real-time features

### Object Storage
- **Production:** AWS S3 (logos, exported reports)
- **Development:** MinIO (S3-compatible, Docker-based)
- **Rationale:** Cost-effective, scalable, CDN integration

### Bull Queue (Redis-backed)
- **Jobs:** Process race results, send notifications, generate reports
- **Rationale:** Offloads heavy tasks from HTTP requests, retry logic, job prioritization

### CI/CD: Placeholder
- **Options:** GitHub Actions, GitLab CI
- **Rationale:** TBD based on hosting choice (GitHub vs. self-hosted GitLab)

## 9. Monorepo Tooling

### npm Workspaces
- **Rationale:** Built-in, zero configuration, dependency hoisting
- **Structure:** `/src/apps/*`, `/src/packages/*`, `/tests/*`

### Build Orchestration: Under Evaluation

**Option A: Turborepo**
- **Pros:** Fast incremental builds, remote caching, simple config
- **Cons:** Vercel-owned (vendor lock-in risk)

**Option B: Nx**
- **Pros:** Advanced dependency graph, affected commands, plugins
- **Cons:** Steeper learning curve, more complex config

**Decision Timeline:** Start with npm workspaces alone. Evaluate Turborepo/Nx if build times become bottleneck (unlikely at current scale).

## 10. Development Tools

### Code Quality
- **ESLint:** Enforce coding standards, catch common mistakes
- **Prettier:** Consistent formatting (no debates on tabs vs. spaces)
- **Rationale:** Automated code reviews reduce friction, onboarding time

### Pre-Commit Hooks
- **Husky:** Git hook management
- **lint-staged:** Run linters only on changed files
- **Rationale:** Fast feedback loop, prevents broken commits reaching CI

### TypeScript Configuration
- **Strict Mode:** All strict flags enabled
- **No Implicit Any:** Forces explicit types
- **Rationale:** Type safety as first-class citizen, not opt-in feature

### Runtime Validation
- **Zod:** Schema definition, runtime validation, type inference
- **Use Cases:**
  - API request/response validation
  - Environment variable parsing
  - Form validation (shared between frontend/backend)
- **Rationale:** Single source of truth for data shapes, generates TypeScript types automatically

---

## Decision Status Summary

**Finalized:**
- Language: TypeScript (strict mode)
- Runtime: Node.js 20+
- Database: PostgreSQL 15+
- Auth: iRacing OAuth + JWT
- Companion: Electron + Playwright (browser automation only)
- Testing: Vitest + Playwright + Test Containers
- Infra: Docker + Redis + S3/MinIO
- Monorepo: npm workspaces
- Dev Tools: ESLint + Prettier + Husky + Zod

**Under Evaluation (Deferred to Implementation):**
- Backend framework: Express vs. Fastify vs. Hono
- Frontend framework: React + Vite vs. Next.js
- ORM: Prisma vs. TypeORM
- Build orchestration: Turborepo vs. Nx (if needed)
- CI/CD: GitHub Actions vs. GitLab CI

**Deferred Decisions Rationale:**
- Backend/frontend frameworks: Choice depends on deployment target (cloud vs. edge vs. self-hosted)
- ORM: Both options integrate cleanly with Clean Architecture; decision based on team preference during implementation
- Build tools: Optimize when proven bottleneck (YAGNI principle)

---

## Cross-References

- **Architecture Patterns:** See [ARCHITECTURE.md](./ARCHITECTURE.md) for how these technologies map to Clean Architecture layers
- **Project Overview:** See [CONCEPT.md](./CONCEPT.md) for business context driving technology choices
- **Setup Instructions:** See [README.md](../README.md) for installation and getting started

---

*Last Updated: 2025-11-23*