Files
familysync/.planning/codebase/STACK.md
T
Lucas Berger 982438dc10 style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
2026-06-11 20:35:18 -04:00

5.4 KiB

Technology Stack

Analysis Date: 2026-06-09

Languages

Primary:

  • TypeScript 5.5.x - Full stack: backend (apps/api/src), frontend (apps/pwa/src), shared types
  • JavaScript - Package tooling (node-cron, vite config, drizzle config)

Secondary:

  • CSS - Styling (imported via Vite; Schedule-X provides default theme)
  • HTML - PWA manifest generation via vite-plugin-pwa

Runtime

Environment:

  • Node.js 22 LTS (FROM node:22-alpine in Dockerfile)
  • Browser: ES2023 target; iOS 16.4+ (PWA home-screen install required)

Package Manager:

  • pnpm 11.5.1
  • Lockfile: pnpm-lock.yaml present
  • Workspace: pnpm-workspace.yaml with apps/* packages

Frameworks

Core (Backend):

  • Hono 4.12.23 - HTTP framework with Web Standards API; @hono/node-server for Node.js runtime
  • @hono/oidc-auth 1.8.3 - OIDC session middleware (Authelia integration; storage-less JWT cookies)
  • @hono/zod-validator 0.8.0 - Request body/query validation in route handlers

Core (Frontend):

  • React 19.x - PWA frontend with concurrent features
  • Vite 8.0.16 - Build tooling (dev server with HMR, production bundler)
  • vite-plugin-pwa 1.3.0 - Service worker registration, PWA manifest generation, Workbox 7 integration

Calendar UI:

  • @schedule-x/react 4.1.0 - Calendar component wrapper
  • @schedule-x/calendar 4.6.0 - Core calendar rendering
  • @schedule-x/event-modal 4.6.0 - Event detail/edit modal
  • @schedule-x/events-service 4.6.0 - Event data management
  • @schedule-x/calendar-controls 4.6.0 - Month/week navigation
  • @schedule-x/theme-default 4.6.0 - Default theme (CSS overridden by apps/pwa/src/styles/tokens.css)

Client State:

  • @tanstack/react-query 5.101.0 - Server state fetching, caching, background refetch, invalidation
  • zustand 5.0.14 - UI-only state (selected date range, color assignments, drawer states)

Testing (Backend):

  • Vitest 4.1.8+ - Unit + integration test runner; config: apps/api/vitest.config.ts (environment: node, globals: true)

Testing (Frontend):

  • Vitest 4.1.8+ - Unit test runner; config: apps/pwa/vitest.config.ts (environment: jsdom, TZ=UTC for deterministic date tests)
  • @testing-library/react 16.3.0 - Component testing utilities
  • @testing-library/jest-dom 6.6.3+ - Jest DOM matchers

Build/Dev:

  • @vitejs/plugin-react 4.3.0+ - JSX transform, React Fast Refresh

Key Dependencies

Critical (CalDAV):

  • tsdav 2.2.2 - CalDAV client for Fastmail integration; fetches calendars (PROPFIND) and events (REPORT); handles Basic auth
  • ical.js 2.2.1 - iCalendar (.ics) parsing on both backend (CalDAV responses) and frontend (event hydration); Mozilla-maintained reference implementation
  • rrule 2.8.1 - Not yet declared; RRULE expansion for recurring event expansion (Phase 2 calendar view)

Critical (Database):

  • drizzle-orm 0.45.2 - Type-safe SQL ORM; MySQL dialect targeting MariaDB; zero runtime overhead
  • drizzle-kit 0.31.10 - Schema migration generator (generates SQL from apps/api/src/db/schema.ts)
  • mysql2 3.22.4 - Native MariaDB/MySQL driver; Promises API; used by Drizzle

Critical (Validation):

  • zod 3.25.0+ - Schema validation (event payloads, API requests)

Supporting (Backend):

  • node-cron 4.2.1+ - Cron scheduling for CalDAV poller (5-min), outbox worker (15-sec)
  • temporal-polyfill 0.3.2 - Temporal API polyfill for date/time operations (ISO 8601 handling)

Supporting (Frontend):

  • temporal-polyfill 0.3.2 - Same Temporal polyfill; imported before Schedule-X at apps/pwa/src/main.tsx:7
  • lucide-react 1.17.0 - Icon library
  • idb 7.1.1 - IndexedDB wrapper (optional; available but not yet wired)

Development Only:

  • @types/node 22.x - Node.js type definitions
  • @types/react 19.x - React type definitions
  • @types/react-dom 19.x - React DOM type definitions
  • jsdom 26.1.0+ - DOM simulation for frontend tests

Configuration

Environment (Backend — apps/api):

  • .env - Local secrets (DB credentials, OIDC settings, encryption key); pattern in docker-compose.yml
  • drizzle.config.ts - Dialect: mysql; schema path: ./src/db/schema.ts; migrations: ./src/db/migrations
  • tsconfig.json - Target: ES2023; module: NodeNext; strict: true

Environment (Frontend — apps/pwa):

  • vite.config.ts - React plugin, PWA plugin (Workbox config with navigateFallback and denylist for /callback, /api/*, /health)
  • tsconfig.json - Target: ES2023; lib: [ES2023, DOM, DOM.Iterable]; jsx: react-jsx; strict: true

Build (Docker):

  • Multi-stage Dockerfile (apps/api/Dockerfile):
    • base - Node 22 Alpine with pnpm enabled
    • builder - TypeScript compilation for API only
    • pwa-builder - Vite build for PWA (produces dist/)
    • dev - Development image with hot-reload via node --watch
    • production - Single port (:3000) serving both API and PWA static files

Platform Requirements

Development:

  • Node.js 22 LTS
  • pnpm 11.5.1
  • Docker + Docker Compose (for local MariaDB + Redis)
  • MariaDB 11 (via docker-compose.yml)
  • Redis 7-Alpine (via docker-compose.yml, present but unused in Phase 1)
  • Vite dev server proxy: localhost:3000 for /api, /callback, /health

Production:

  • Node.js 22 LTS runtime in Docker container
  • Authelia OIDC provider (pre-deployed; configured via env vars)
  • MariaDB 11 database
  • Redis 7 (optional; reserved for Phase 4 live list sync pub/sub)
  • Pangolin/Newt tunnel for secure external access (no open ports)
  • Split-DNS internal domain resolution

Stack analysis: 2026-06-09