284 lines
12 KiB
Markdown
284 lines
12 KiB
Markdown
# 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/core/*`, `/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* |