Files
thrilltrack-explorer/migration/PHASE_01_FOUNDATION.md

14 KiB

PHASE 1: Foundation + Next.js 15 Setup

Status: 🟡 Partially Complete (Core Foundation Ready) Estimated Time: 20-25 hours
Priority: CRITICAL
Depends On: None
Blocks: All other phases

Note: Core infrastructure complete (Tasks 1.0, 1.1, 1.3). Types (1.2), Base Service (1.4), and Testing (1.5) deferred to be created as needed in subsequent phases.


🎯 Phase Goal

Set up Next.js 16 with App Router + Turbopack, configure Bun, establish environment variables, and build the core infrastructure that all services will depend on: API client, type system, error handling, and base service class.

This phase includes:

  1. Next.js 16 installation and configuration
  2. Bun package manager setup
  3. Environment variables configuration
  4. API client infrastructure
  5. Type system for Django API
  6. Service layer foundation

📋 Prerequisites

  • Django backend is running at https://api.thrillwiki.com
  • You have API access token for testing
  • Bun is installed (curl -fsSL https://bun.sh/install | bash)
  • Node.js 18+ is installed (for Next.js 15)
  • Git repository is initialized

🗂️ Files to Create/Modify

# Next.js Configuration
next.config.js         (NEW)
.env.local            (NEW)
.env.example          (NEW)
tsconfig.json         (UPDATE)
package.json          (UPDATE)

# Next.js App Structure
app/
├── layout.tsx        (NEW)
├── page.tsx          (NEW)
├── loading.tsx       (NEW)
├── error.tsx         (NEW)
└── not-found.tsx     (NEW)

# API & Services
lib/
├── api/
│   ├── client.ts     (NEW)
│   ├── errorHandler.ts (NEW)
│   └── index.ts      (NEW)
└── env.ts            (NEW - env validation)

types/
├── api/
│   ├── responses.ts  (NEW)
│   ├── requests.ts   (NEW)
│   ├── errors.ts     (NEW)
│   └── index.ts      (NEW)
└── entities/
    ├── park.ts       (NEW)
    ├── ride.ts       (NEW)
    └── ... (others)

services/
├── base/
│   ├── BaseService.ts (NEW)
│   └── index.ts       (NEW)
└── __tests__/
    ├── setup.ts       (NEW)
    └── mocks/         (NEW)

Task 1.0: Next.js 15 + Bun Setup (5 hours)

Step 1: Install Next.js 15 with Bun

# Create Next.js 15 project with Bun
bun create next-app@latest . --typescript --tailwind --app --no-src-dir

# Or if starting fresh in a new directory:
bun create next-app@latest thrillwiki --typescript --tailwind --app --no-src-dir
cd thrillwiki

Step 2: Configure next.config.js

Create next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Enable Turbopack for development
  experimental: {
    turbo: {
      resolveAlias: {
        '@': './',
      },
    },
  },
  
  // Image optimization for CloudFlare
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'imagedelivery.net',
      },
    ],
    formats: ['image/avif', 'image/webp'],
  },
  
  // Production optimizations
  compress: true,
  poweredByHeader: false,
  reactStrictMode: true,
};

module.exports = nextConfig;

Step 3: Environment Variables Setup

Create .env.local:

# Django API
NEXT_PUBLIC_DJANGO_API_URL=http://localhost:8000/api/v1

# CloudFlare Images
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=your_account_id

# Supabase (temporary - keep during migration)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key

Create .env.example:

# Django API (required)
NEXT_PUBLIC_DJANGO_API_URL=

# CloudFlare Images (required)
NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID=

# Supabase (temporary - will be removed)
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

Step 4: Environment Variable Validation

Create lib/env.ts:

import { z } from 'zod';

const envSchema = z.object({
  NEXT_PUBLIC_DJANGO_API_URL: z.string().url(),
  NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID: z.string().min(1),
});

export const env = envSchema.parse({
  NEXT_PUBLIC_DJANGO_API_URL: process.env.NEXT_PUBLIC_DJANGO_API_URL,
  NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID: process.env.NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_ID,
});

Step 5: Update package.json Scripts

{
  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "type-check": "tsc --noEmit"
  }
}

Checklist

  • Next.js 16 installed with Bun (Next.js 16.0.1)
  • Turbopack enabled in next.config.js (Removed - deprecated experimental key in Next.js 16)
  • .env.local created with all variables
  • .env.example documented
  • Environment validation in lib/env.ts
  • package.json scripts use Bun
  • Dev server runs with bun run dev - Running on http://localhost:3000
  • No TypeScript errors

Task 1.1: Base API Client (3 hours)

Checklist

  • Install dependencies: bun add axios zod (axios installed, zod already present)
  • Create lib/api/client.ts
  • Configure base URL from environment variable
  • Add JWT token management
    • Get token from localStorage
    • Attach to Authorization header
    • Handle token expiry
  • Create request interceptor
    • Add auth headers
    • Add request logging (dev only)
  • Create response interceptor
    • Handle success responses
    • Handle error responses
    • Extract data from Django response format
  • Implement retry logic
    • Retry on network failures
    • Exponential backoff
    • Max 3 retries
  • Add timeout configuration (30s default)
  • Export configured axios instance

Acceptance Criteria

  • Can make GET request to /api/v1/health (client configured)
  • Token automatically attached to requests
  • Errors are properly caught and logged
  • Retries work on network failures
  • TypeScript types are correct

Implementation Example

// lib/api/client.ts
import axios from 'axios';
import { env } from '@/lib/env';

const apiClient = axios.create({
  baseURL: env.NEXT_PUBLIC_DJANGO_API_URL,
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// Request interceptor
apiClient.interceptors.request.use((config) => {
  // Add auth token if available
  if (typeof window !== 'undefined') {
    const token = localStorage.getItem('auth_token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
  }
  return config;
});

// Response interceptor
apiClient.interceptors.response.use(
  (response) => response,
  (error) => {
    // Handle errors
    return Promise.reject(error);
  }
);

export { apiClient };

Testing

// Test in app/page.tsx or a Server Component
import { env } from '@/lib/env';

export default async function HomePage() {
  // Test API connection
  const response = await fetch(`${env.NEXT_PUBLIC_DJANGO_API_URL}/health`);
  const data = await response.json();
  
  return <div>API Status: {data.status}</div>;
}

Task 1.2: Type Definitions (2 hours)

Checklist

  • Install zod: bun add zod
  • Create types/api/responses.ts
    • ApiResponse<T> generic type
    • PaginatedResponse<T> type
    • SuccessResponse<T> type
  • Create src/types/api/errors.ts
    • ApiError interface
    • ValidationError interface
    • ErrorDetail interface
  • Create src/types/api/requests.ts
    • PaginationParams interface
    • FilterParams interface
    • SortParams interface
  • Create entity type files
    • types/entities/park.ts
    • types/entities/ride.ts
    • types/entities/company.ts
    • types/entities/rideModel.ts
    • types/entities/submission.ts
    • types/entities/review.ts
  • Create types/api/index.ts - export all types
  • Document type usage

Acceptance Criteria

  • All types match Django API schema
  • No any types used
  • Types are reusable across services
  • Generic types work correctly
  • TypeScript compiler is happy

Example Types

// ApiResponse<T>
interface ApiResponse<T> {
  data: T;
  status: 'success' | 'error';
  message?: string;
}

// PaginatedResponse<T>
interface PaginatedResponse<T> {
  results: T[];
  count: number;
  next: string | null;
  previous: string | null;
}

// ApiError
interface ApiError {
  message: string;
  code?: string;
  details?: ErrorDetail[];
  status: number;
}

Task 1.3: Error Handler Integration (2 hours)

Checklist

  • Create lib/api/errorHandler.ts
  • Map Django error responses to user messages
  • Handle HTTP status codes
    • 400 - Validation errors
    • 401 - Unauthorized
    • 403 - Forbidden
    • 404 - Not found
    • 429 - Rate limiting
    • 500+ - Server errors
  • Extract validation errors from Django format
  • Format error messages for UI display
  • Integrate with existing error logging
  • Add Sentry integration (if available) - Deferred to later phase
  • Create user-friendly error messages
  • Handle network errors separately

Acceptance Criteria

  • All Django errors are properly translated
  • Validation errors show field-specific messages
  • Errors are logged to monitoring
  • User sees helpful error messages
  • No stack traces exposed to users

Testing

// Test error handling
try {
  await apiClient.post('/api/v1/submissions/', { invalid: 'data' });
} catch (error) {
  console.log('Caught error:', error.message);
  console.log('User message:', formatErrorForUser(error));
}

Task 1.4: Service Base Class (2 hours)

Checklist

  • Create services/base/BaseService.ts
  • Add API client instance
  • Implement common CRUD methods
    • get<T>(url: string): Promise<T>
    • list<T>(url: string, params?: any): Promise<T[]>
    • create<T>(url: string, data: any): Promise<T>
    • update<T>(url: string, data: any): Promise<T>
    • delete(url: string): Promise<void>
  • Add pagination helper methods
    • getPaginated<T>(url: string, params?: any): Promise<PaginatedResponse<T>>
  • Add filtering/sorting helpers
  • Add error handling wrapper
  • Add loading state management (optional)
  • Document usage patterns
  • Add TypeScript generics

Acceptance Criteria

  • Base service can be extended
  • All CRUD operations work
  • Pagination works correctly
  • Errors are properly handled
  • TypeScript types are inferred correctly

Example Usage

// Example service extending BaseService
class ParkService extends BaseService {
  async getParks(params?: FilterParams) {
    return this.getPaginated('/api/v1/parks/', params);
  }
  
  async getPark(id: string) {
    return this.get(`/api/v1/parks/${id}/`);
  }
}

Task 1.5: Testing Infrastructure (3 hours)

Checklist

  • Install MSW: bun add -d msw @testing-library/react @testing-library/jest-dom vitest
  • Create services/__tests__/setup.ts
    • Initialize MSW
    • Configure test environment
  • Create src/services/__tests__/mocks/handlers.ts
    • Mock Django API responses
    • Create realistic test data
  • Create services/__tests__/mocks/server.ts
    • Set up MSW server
    • Configure for Node/Next.js environment
  • Create services/__tests__/utils.ts
    • Test helper functions
    • Mock data factories
  • Write example service tests
    • Test success cases
    • Test error cases
    • Test pagination
  • Document testing patterns
  • Set up CI test runs (if applicable)

Acceptance Criteria

  • MSW intercepts API calls in tests
  • Tests can run without real API
  • Test data is realistic
  • All test utilities are documented
  • CI passes tests

Example Test

import { describe, it, expect } from 'vitest';
import { ParkService } from '../parks/parkService';

describe('ParkService', () => {
  it('should fetch parks', async () => {
    const service = new ParkService();
    const parks = await service.getParks();
    expect(parks).toHaveLength(10);
  });
});

🎯 Phase Completion Criteria

Code Quality

  • All files created and in correct locations
  • Zero TypeScript errors
  • Zero linter warnings
  • Code is well-documented
  • Naming conventions followed

Functionality

  • Can make requests to Django API
  • Authentication works
  • Error handling works
  • Base service can be extended
  • Tests pass

Testing

  • Unit tests for API client
  • Unit tests for error handler
  • Unit tests for base service
  • Test coverage >80%
  • All tests pass

📊 Progress Tracking

Started: [Date]
Completed: [Date]
Time Spent: [Hours]

Tasks Completed

  • Task 1.0: Next.js 15 + Bun Setup
  • Task 1.1: Base API Client
  • Task 1.2: Type Definitions - DEFERRED to be created as needed in Phases 2-11
  • Task 1.3: Error Handler Integration
  • Task 1.4: Service Base Class - DEFERRED to Phase 4 (Entity Services)
  • Task 1.5: Testing Infrastructure - DEFERRED to later phases

🚨 Blockers & Issues

Document any issues encountered:

  1. Issue: [Description]
    • Impact: [How it blocks progress]
    • Resolution: [How it was resolved]

📝 Notes

Document important decisions and learnings:

  • [Date] - [Note about implementation decision]

⏭️ Next Phase

Once this phase is complete, proceed to Phase 2: Authentication



Document Version: 2.0
Last Updated: November 9, 2025
Changes: Added Next.js 15 + App Router + Turbopack + Bun setup