# Type Checking Guide

## Overview

BuzzTrail enforces strict type checking across TypeScript and Python codebases to catch errors at compile time rather than runtime. This comprehensive type checking system protects all production environments through automated CI/CD pipelines and local development tools.

For best practices on writing type-safe code, see the [Type Safety Best Practices Guide](TYPE_SAFETY.md).

## Why Type Checking Matters

Our system deploys to four distinct production environments. Type checking ensures code quality and prevents runtime errors before code reaches any of them:

### 1. Railway - Main API Backend & Python Bots

**Production URL**: https://slide-system-production-5813.up.railway.app

**Components**:
- `slide-system` API service (TypeScript)
- `screenshare-bot` (Python)
- `tool-forwarder` (Python)

**Critical Requirements**:
- 24/7 uptime requirements
- Handles presentation generation and bot management
- Python bots run within Railway environment
- Real-time WebSocket connections
- Database interactions with Supabase

**Type Checking Coverage**:
- TypeScript: All API endpoints, services, and utilities
- Python: Both bots with mypy strict validation
- Type errors here cause immediate production outages

### 2. Vercel - API Gateway & Serverless Functions

**Production URL**: https://buzztrail-proxy.vercel.app

**Components**:
- `proxy-server` (TypeScript serverless functions)

**Critical Requirements**:
- Serverless function execution
- Webhook handling
- API proxying and routing
- Auto-scales based on demand
- Cold start performance sensitive

**Type Checking Coverage**:
- TypeScript: All serverless function handlers
- ESLint type-aware rules for async patterns
- Type errors can break webhook integrations

### 3. GitHub Pages - Static Presentation Hosting

**Production URL**: https://buzztrail.github.io/buzztrail-presentations/

**Components**:
- Slidev presentations (TypeScript/Vue)
- Presentation control system (TypeScript)

**Critical Requirements**:
- Global CDN distribution
- Public-facing content
- Real-time control via Supabase
- Static build process must succeed

**Type Checking Coverage**:
- TypeScript: Presentation components and control logic
- Vue SFC type checking
- Type errors prevent build completion

### 4. Supabase - Database & Real-time

**Production URL**: Supabase project endpoint

**Components**:
- TypeScript client code (Web/Node.js)
- Python client code (Bots)

**Critical Requirements**:
- PostgreSQL database access
- Real-time WebSocket subscriptions
- Row-level security policies
- Client-side type safety

**Type Checking Coverage**:
- TypeScript: Supabase client usage in all apps
- Python: Supabase client in bot code
- Type errors cause data integrity issues

## Type Checking Architecture

### Three-Layer Protection

```
┌─────────────────────────────────────────────────┐
│  Layer 1: Local Pre-commit Hooks               │
│  - Fast (affected files only)                  │
│  - Immediate feedback                           │
│  - Optional (can bypass)                        │
└─────────────────┬───────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────┐
│  Layer 2: GitHub Actions CI/CD                  │
│  - Runs on every push/PR                        │
│  - Blocks merge on failures                     │
│  - Checks affected projects                     │
└─────────────────┬───────────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────────┐
│  Layer 3: Production Build Verification         │
│  - Final safety net                             │
│  - TypeScript compilation must succeed          │
│  - All ESLint rules must pass                   │
└─────────────────────────────────────────────────┘
```

## Layer 1: Local Pre-commit Hooks

### What Runs Automatically

When you run `git commit`, Husky executes these checks:

1. **TypeScript Type Check** (affected files only)
   ```bash
   pnpm nx affected -t typecheck --base=HEAD~1
   ```

2. **ESLint Type-Aware Linting** (affected files only)
   ```bash
   pnpm nx affected -t lint --base=HEAD~1
   ```

3. **Python mypy Validation** (if .py files changed)
   - Checks `screenshare-bot` if its files changed
   - Checks `tool-forwarder` if its files changed

### Performance

Pre-commit hooks are optimized for speed:
- Only checks files in your commit
- Uses Nx affected computation
- Typical run time: 10-30 seconds
- Full CI runs later with comprehensive checks

### Bypassing Pre-commit Hooks

For emergency situations only:

```bash
git commit --no-verify -m "fix: emergency production hotfix"
```

**When to bypass**:
- Production is down and you need immediate fix
- You're committing non-code files
- Pre-commit hook has a bug

**When NOT to bypass**:
- "I'll fix the types later" (you won't)
- "CI will catch it" (why waste CI time?)
- "It's just a small change" (small bugs cause big outages)

### Troubleshooting Pre-commit Hooks

**Hook not running**:
```bash
# Verify Husky is installed
ls -la .husky/

# Reinstall if needed
pnpm install
```

**Hook failing incorrectly**:
```bash
# Run checks manually to debug
pnpm nx affected -t typecheck --base=HEAD~1
pnpm nx affected -t lint --base=HEAD~1
```

**Python checks failing**:
```bash
# Verify venv exists
cd apps/slide-system/bots/screenshare-bot
ls -la .venv/

# Recreate venv if needed
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt mypy
```

## Layer 2: GitHub Actions CI/CD

### Workflow Overview

The CI pipeline (`.github/workflows/ci.yml`) runs three parallel type checking jobs:

```yaml
typescript-typecheck → \
eslint-typeaware     →  → build → deploy
python-typecheck     → /
```

All three type checking jobs must pass before the build job runs.

### TypeScript Type Checking Job

**Runs on**: Every push and pull request

**What it does**:
1. Checks out code with full Git history (for Nx affected)
2. Sets up Node.js 22 and pnpm 10.18.1
3. Caches pnpm store for faster subsequent runs
4. Installs dependencies
5. Runs: `pnpm nx affected --target=typecheck --base=$BASE --parallel=3`

**Base branch detection**:
- Pull requests: Uses PR base branch
- Direct pushes: Uses `origin/main`

**Failure behavior**:
- Exits with code 1 on type errors
- Blocks build job from running
- Displays full TypeScript error messages

**Typical runtime**: 2-5 minutes (with cache)

### ESLint Type-Aware Linting Job

**Runs on**: Every push and pull request

**What it does**:
1. Same setup as TypeScript job
2. Runs: `pnpm nx affected --target=lint --base=$BASE --parallel=3`

**Type-aware rules checked**:
- `@typescript-eslint/no-floating-promises`
- `@typescript-eslint/no-misused-promises`
- `@typescript-eslint/await-thenable`
- `@typescript-eslint/require-await`
- `@typescript-eslint/no-unnecessary-type-assertion`
- Many more...

**Failure behavior**:
- Exits with code 1 on lint errors
- Blocks build job from running
- Displays all lint violations

**Typical runtime**: 2-5 minutes (with cache)

### Python Type Checking Job

**Runs on**: Every push and pull request

**What it does**:
1. Checks out code
2. Sets up Python 3.11
3. Installs `uv` (fast pip alternative)
4. For each bot:
   - Creates isolated venv
   - Installs mypy and type stubs
   - Runs: `mypy bot.py --ignore-missing-imports`

**Bots checked**:
- `apps/slide-system/bots/screenshare-bot/bot.py`
- `apps/slide-system/bots/tool-forwarder/bot.py`

**Failure behavior**:
- Exits with code 1 on mypy errors
- Blocks build job from running
- Displays all type violations

**Typical runtime**: 1-3 minutes

### Build Job

**Depends on**: All three type checking jobs

**What it does**:
1. Only runs if all type checks pass
2. Builds affected projects: `pnpm nx affected --target=build --base=$BASE --parallel=3`
3. Uploads build artifacts with 7-day retention

**This is the final gate before deployment**.

### CI Performance Optimization

**Caching**:
- pnpm store cached with lockfile hash
- Python pip cache for faster setup
- Nx computation cache (local only, no cloud)

**Parallelization**:
- Three type checking jobs run in parallel
- Nx runs tasks within jobs with `--parallel=3`
- Typical total CI time: 5-10 minutes

**Affected computation**:
- Only checks projects that changed
- Uses Git history to determine affected projects
- Dramatically reduces check time for small changes

### Viewing CI Results

**In GitHub UI**:
1. Go to your PR or commit
2. Click "Checks" tab
3. Expand failed jobs to see errors
4. Click "Show more" to see full logs

**Via gh CLI**:
```bash
# View recent workflow runs
gh run list

# View specific run
gh run view <run-id>

# View logs for specific job
gh run view <run-id> --log --job=typescript-typecheck
```

## Layer 3: Production Build Verification

### Deployment Build Process

Each deployment platform runs final type checking:

**Railway** (slide-system):
```bash
pnpm nx build slide-system
```
- Runs full TypeScript compilation
- Type errors prevent deployment
- Build logs visible in Railway dashboard

**Vercel** (proxy-server):
```bash
npx nx build proxy-server
```
- Runs full TypeScript compilation
- Type errors prevent serverless function deployment
- Build logs visible in Vercel dashboard

**GitHub Pages** (Slidev presentations):
```bash
npm run build
```
- Runs Vite build with TypeScript checking
- Type errors prevent static site generation
- Build logs visible in GitHub Actions

### Build Failure Recovery

If a build fails in production (shouldn't happen if CI passed):

1. **Check deployment logs** for specific error
2. **Reproduce locally**: `pnpm nx build <project-name>`
3. **Fix the issue** in a new commit
4. **Push fix** to trigger new deployment

## TypeScript Type Checking

### Project Configuration

Each TypeScript project has:

**`tsconfig.json`** (project-specific):
```json
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "../../dist/apps/slide-system"
  },
  "include": ["**/*.ts"]
}
```

**`tsconfig.base.json`** (workspace root):
```json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}
```

### Common TypeScript Type Errors

#### 1. Implicit Any

**Error**:
```typescript
// ❌ Parameter 'data' implicitly has an 'any' type
function process(data) {
  return data.value;
}
```

**Fix**:
```typescript
// ✅ Explicitly type the parameter
interface ProcessData {
  value: string;
}

function process(data: ProcessData) {
  return data.value;
}
```

#### 2. Null/Undefined Checks

**Error**:
```typescript
// ❌ Object is possibly 'null'
const user = await getUser(id);
console.log(user.name);
```

**Fix**:
```typescript
// ✅ Check for null/undefined
const user = await getUser(id);
if (!user) {
  throw new Error('User not found');
}
console.log(user.name);

// ✅ Or use optional chaining
console.log(user?.name);
```

#### 3. Promise Handling

**Error**:
```typescript
// ❌ Function lacks ending return statement
async function getData(): Promise<string> {
  if (condition) {
    return 'data';
  }
  // Missing return for else case
}
```

**Fix**:
```typescript
// ✅ Ensure all code paths return
async function getData(): Promise<string> {
  if (condition) {
    return 'data';
  }
  return 'default';
}
```

#### 4. Type Assertions

**Error**:
```typescript
// ❌ Type assertion can fail at runtime
const element = document.getElementById('app') as HTMLDivElement;
element.classList.add('active');
```

**Fix**:
```typescript
// ✅ Check before asserting
const element = document.getElementById('app');
if (element instanceof HTMLDivElement) {
  element.classList.add('active');
}
```

### Running TypeScript Type Checks Locally

```bash
# Check all projects
pnpm nx run-many -t typecheck --all

# Check specific project
pnpm nx typecheck slide-system

# Check affected projects (what CI will check)
pnpm nx affected -t typecheck --base=main

# Watch mode for active development
pnpm nx typecheck slide-system --watch
```

### TypeScript Performance Tips

1. **Use project references** for faster incremental builds
2. **Enable `skipLibCheck`** to skip type checking node_modules
3. **Use `tsc --noEmit`** for type checking without compilation
4. **Leverage Nx caching** to avoid redundant checks

## Python Type Checking

### Configuration

Each Python bot has a `mypy.ini` (or inline configuration):

```ini
[mypy]
python_version = 3.11
warn_return_any = True
warn_unused_configs = True
disallow_untyped_defs = True
ignore_missing_imports = True
```

### Common Python Type Errors

#### 1. Untyped Function Definitions

**Error**:
```python
# ❌ Function is missing type annotations
def process_message(message):
    return message.upper()
```

**Fix**:
```python
# ✅ Add type hints
def process_message(message: str) -> str:
    return message.upper()
```

#### 2. Dictionary/Dict Types

**Error**:
```python
# ❌ Type of "data" is too vague
def get_value(data: dict) -> str:
    return data['key']
```

**Fix**:
```python
# ✅ Use TypedDict for structured data
from typing import TypedDict

class MessageData(TypedDict):
    key: str
    value: int

def get_value(data: MessageData) -> str:
    return data['key']
```

#### 3. Optional Return Types

**Error**:
```python
# ❌ Incompatible return value type
def find_user(user_id: str) -> User:
    if user_id in users:
        return users[user_id]
    return None  # Type error: None not compatible with User
```

**Fix**:
```python
# ✅ Use Optional for nullable returns
from typing import Optional

def find_user(user_id: str) -> Optional[User]:
    if user_id in users:
        return users[user_id]
    return None
```

#### 4. Async Function Types

**Error**:
```python
# ❌ Missing Coroutine type hint
async def fetch_data():
    return await client.get('/data')
```

**Fix**:
```python
# ✅ Properly type async functions
from typing import Dict, Any

async def fetch_data() -> Dict[str, Any]:
    return await client.get('/data')
```

### Running Python Type Checks Locally

```bash
# Check all bots using helper script
./scripts/python-typecheck.sh

# Check specific bot manually
cd apps/slide-system/bots/screenshare-bot
source .venv/bin/activate
mypy bot.py

# Check with strict flags
mypy bot.py --strict

# Check with specific Python version
mypy bot.py --python-version 3.11
```

### Python Type Checking Best Practices

1. **Use TypedDict** for structured dictionaries
2. **Import from `typing`** for generic types
3. **Use `Optional[T]`** for nullable values
4. **Type all function signatures** (parameters and return)
5. **Use `# type: ignore`** sparingly and with comments

## Cross-Platform Type Definitions

### Shared Types Between TypeScript and Python

We maintain shared type definitions in `libs/shared/types/`:

**TypeScript** (canonical source):
```typescript
// libs/shared/types/src/lib/supabase.types.ts
export interface ConversationSession {
  id: string;
  session_type: string;
  status: 'active' | 'completed' | 'error';
  created_at: string;
  updated_at: string;
}
```

**Python** (mirror):
```python
# libs/shared/types/python/supabase_types.py
from typing import TypedDict, Literal

class ConversationSession(TypedDict):
    id: str
    session_type: str
    status: Literal['active', 'completed', 'error']
    created_at: str
    updated_at: str
```

### Keeping Types Synchronized

**Manual synchronization process**:

1. **Update TypeScript types** (canonical source)
2. **Generate Python mirrors** (automated or manual)
3. **Run type checks** to verify compatibility
4. **Commit both** TypeScript and Python types together

**Verification**:
```bash
# Verify TypeScript types
pnpm nx typecheck shared-types

# Verify Python mirrors
./scripts/python-typecheck.sh

# Both should pass for type sync to be valid
```

For detailed synchronization procedures, type mapping reference, and version tracking, see [libs/shared/types/TYPES.md](../../libs/shared/types/TYPES.md).

## Troubleshooting Common Issues

### Issue: Pre-commit Hook Fails but CI Passes

**Cause**: Different base branch calculation

**Fix**:
```bash
# Pre-commit uses HEAD~1
pnpm nx affected -t typecheck --base=HEAD~1

# CI uses origin/main (on direct push)
pnpm nx affected -t typecheck --base=origin/main
```

### Issue: CI Fails but Local Passes

**Cause**: Uncommitted or unstaged changes affecting types

**Fix**:
```bash
# Check git status
git status

# Stash uncommitted changes
git stash

# Run checks again
pnpm nx affected -t typecheck --base=origin/main

# Pop stash
git stash pop
```

### Issue: Python Type Check Fails with Import Errors

**Cause**: Missing type stubs or dependencies

**Fix**:
```bash
cd apps/slide-system/bots/screenshare-bot
source .venv/bin/activate

# Install type stubs
pip install types-aiohttp types-requests

# Or ignore missing imports
mypy bot.py --ignore-missing-imports
```

### Issue: TypeScript Out of Memory

**Cause**: Large project or complex types

**Fix**:
```bash
# Increase Node.js memory
NODE_OPTIONS=--max-old-space-size=4096 pnpm nx typecheck slide-system

# Or add to .env
echo "NODE_OPTIONS=--max-old-space-size=4096" >> .env
```

### Issue: Nx Affected Checks Too Many Projects

**Cause**: Changes to shared libraries or base config

**Solution**: This is expected behavior. Changes to shared code affect dependent projects.

**Optimization**:
```bash
# Check only specific project
pnpm nx typecheck slide-system

# Skip affected computation
pnpm nx run-many -t typecheck --all
```

## Performance Benchmarks

### Local Development

| Command | Cold | Warm (cached) |
|---------|------|---------------|
| `pnpm nx affected -t typecheck` | ~45s | ~8s |
| `pnpm nx affected -t lint` | ~30s | ~6s |
| `./scripts/python-typecheck.sh` | ~20s | ~5s |
| Pre-commit hook (typical) | ~25s | ~10s |

### CI Pipeline

| Job | First run | Cached |
|-----|-----------|--------|
| typescript-typecheck | ~4m | ~2m |
| eslint-typeaware | ~3m | ~2m |
| python-typecheck | ~2m | ~1m |
| **Total (parallel)** | ~4m | ~2m |

## Best Practices

### For Developers

1. **Run checks locally before pushing**
   ```bash
   ./scripts/typecheck-all.sh
   ```

2. **Fix type errors immediately** - don't let them accumulate

3. **Use IDE type checking** - enable TypeScript language server

4. **Write tests with types** - tests verify type correctness

5. **Don't bypass pre-commit hooks** unless absolutely necessary

### For Code Reviewers

1. **Verify CI passed** before reviewing code
2. **Check for `any` types** - flag them in review
3. **Ensure type definitions** exist for new interfaces
4. **Validate error handling** - check for null/undefined
5. **Require type tests** for complex type logic

### For Team Leads

1. **Monitor CI run times** - optimize if exceeding 10 minutes
2. **Track bypass frequency** - investigate if hooks bypassed often
3. **Enforce type coverage** - aim for 90%+ typed code
4. **Budget time for type fixes** - don't treat as "nice to have"
5. **Celebrate type safety wins** - share prevented bugs in retros

## Advanced Topics

### Type-Safe Environment Variables

```typescript
// libs/shared/config/src/lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  TAVUS_API_KEY: z.string(),
  SUPABASE_URL: z.string().url(),
  NODE_ENV: z.enum(['development', 'production', 'test']),
});

export const env = envSchema.parse(process.env);
```

### Branded Types for IDs

```typescript
// Prevent mixing different ID types
type UserId = string & { readonly brand: unique symbol };
type SessionId = string & { readonly brand: unique symbol };

function getUser(id: UserId) { /* ... */ }

const sessionId = 'abc' as SessionId;
getUser(sessionId); // ❌ Type error - can't use SessionId as UserId
```

### Discriminated Unions

```typescript
type Result<T, E> =
  | { success: true; data: T }
  | { success: false; error: E };

function handleResult(result: Result<string, Error>) {
  if (result.success) {
    console.log(result.data); // TypeScript knows data exists
  } else {
    console.error(result.error); // TypeScript knows error exists
  }
}
```

## Additional Resources

### Documentation

- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
- [mypy documentation](https://mypy.readthedocs.io/)
- [Nx Type Checking](https://nx.dev/recipes/tips-n-tricks/eslint)
- [ESLint TypeScript](https://typescript-eslint.io/)

### Internal Documentation

- [Type Safety Best Practices](TYPE_SAFETY.md) - Comprehensive guide to writing type-safe code
- [Cross-Language Type Synchronization](../../libs/shared/types/TYPES.md) - Type mapping and sync process
- [Contributing Guide](../../CONTRIBUTING.md) - CI/CD requirements and code quality standards
- [CI/CD Pipeline](.github/workflows/ci.yml) - Full workflow implementation
- [Stream A Progress](../.claude/epics/typescript-compilation-errors/updates/136/stream-A.md) - CI setup details
- [Stream B Progress](../.claude/epics/typescript-compilation-errors/updates/136/stream-B.md) - Pre-commit hooks details

### Getting Help

1. **Check this guide** for common issues
2. **Search CI logs** for specific error messages
3. **Ask in #engineering** Slack channel
4. **Review PR comments** - CI bot adds error summaries
5. **Pair with teammate** if stuck on complex type issues

---

**Last Updated**: 2025-10-14
**Maintained By**: Engineering Team
**Questions?**: Post in #engineering or open an issue
