Running Days Docs
GitHub

Architecture Overview

Running Days is built as a Turborepo monorepo with clear separation between applications and shared packages.

System Architecture

graph TB
    subgraph "Client Layer"
        iOS[iOS App<br/>Swift/SwiftUI]
        Web[Web Dashboard<br/>SvelteKit]
    end

    subgraph "API Layer"
        API[Fastify API<br/>Port 3000]
    end

    subgraph "Data Layer"
        DB[(SQLite/PostgreSQL<br/>Drizzle ORM)]
    end

    subgraph "External"
        Apple[Apple Health<br/>via Health Auto Export]
        AppleAuth[Apple Sign-In]
    end

    iOS --> API
    Web --> API
    Apple --> API
    AppleAuth --> API
    API --> DB

Package Structure

The monorepo uses pnpm workspaces with Turborepo for build orchestration.

Applications (apps/)

AppPurposeTech Stack
apiREST API backendFastify 5, TypeScript
webCloud SaaS dashboardSvelteKit 2, Svelte 5
ossSelf-hosted versionSvelteKit (single-user)
iosNative iOS appSwift, SwiftUI

Packages (packages/)

PackagePurposeDependencies
typesShared TypeScript typesNone (zero deps)
utilsDate formatters, utilitiestypes
databaseDrizzle ORM schematypes
business-logicGoals, streaks, achievementstypes, utils
observabilityLogging, metrics, audittypes
uiShared Svelte componentsutils

Data Flow

Workout Import Flow

sequenceDiagram
    participant iOS as iOS App
    participant HAE as Health Auto Export
    participant API as Fastify API
    participant DB as Database

    iOS->>HAE: Configure webhook
    HAE->>API: POST /api/webhook
    API->>API: Validate token
    API->>API: Parse workouts
    API->>DB: Upsert workouts
    API->>DB: Update daily stats
    API-->>HAE: 200 OK

Authentication Flow

sequenceDiagram
    participant User
    participant Web as Web App
    participant API as Fastify API
    participant Apple as Apple Sign-In

    User->>Web: Click "Sign in with Apple"
    Web->>API: GET /api/v1/auth/apple
    API->>Apple: PKCE + nonce
    Apple-->>User: Apple login UI
    User->>Apple: Authenticate
    Apple->>API: POST /api/v1/auth/apple/callback
    API->>API: Validate identity token
    API-->>Web: Set httpOnly cookies

Key Design Decisions

1. Monorepo Structure

Using Turborepo with pnpm workspaces enables:

  • Shared code without publishing to npm
  • Coordinated builds with caching
  • Single lockfile for dependencies

2. Zero-Dependency Types Package

The @running-days/types package has no external dependencies, making it safe to import anywhere without bundling concerns.

3. Server-Only Database Access

Database code is restricted to .server.ts files in SvelteKit, preventing accidental client-side database imports.

4. OKLCH Color System

The design system uses OKLCH colors for perceptual uniformity. Adjusting lightness gives predictable visual results across all hues.

Port Assignments

ServicePort
API3000
Web Dashboard3001 (Docker) / 5173 (dev)
Grafana3002
Loki3100