# 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
```bash
# 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`:
```javascript
/** @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`:
```bash
# 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`:
```bash
# 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`:
```typescript
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
```json
{
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
}
}
```
### Checklist
- [x] Next.js 16 installed with Bun (Next.js 16.0.1)
- [x] ~~Turbopack enabled in next.config.js~~ (Removed - deprecated experimental key in Next.js 16)
- [x] .env.local created with all variables
- [x] .env.example documented
- [x] Environment validation in lib/env.ts
- [x] package.json scripts use Bun
- [x] Dev server runs with `bun run dev` - ✅ Running on http://localhost:3000
- [x] No TypeScript errors
---
## ✅ Task 1.1: Base API Client (3 hours)
### Checklist
- [x] Install dependencies: `bun add axios zod` (axios installed, zod already present)
- [x] Create `lib/api/client.ts`
- [x] Configure base URL from environment variable
- [x] Add JWT token management
- [x] Get token from localStorage
- [x] Attach to Authorization header
- [x] Handle token expiry
- [x] Create request interceptor
- [x] Add auth headers
- [x] Add request logging (dev only)
- [x] Create response interceptor
- [x] Handle success responses
- [x] Handle error responses
- [x] Extract data from Django response format
- [x] Implement retry logic
- [x] Retry on network failures
- [x] Exponential backoff
- [x] Max 3 retries
- [x] Add timeout configuration (30s default)
- [x] Export configured axios instance
### Acceptance Criteria
- [x] Can make GET request to `/api/v1/health` (client configured)
- [x] Token automatically attached to requests
- [x] Errors are properly caught and logged
- [x] Retries work on network failures
- [x] TypeScript types are correct
### Implementation Example
```typescript
// 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
```typescript
// 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
API Status: {data.status}
;
}
```
---
## ✅ Task 1.2: Type Definitions (2 hours)
### Checklist
- [ ] Install zod: `bun add zod`
- [ ] Create `types/api/responses.ts`
- [ ] `ApiResponse` generic type
- [ ] `PaginatedResponse` type
- [ ] `SuccessResponse` 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
```typescript
// ApiResponse
interface ApiResponse {
data: T;
status: 'success' | 'error';
message?: string;
}
// PaginatedResponse
interface PaginatedResponse {
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
- [x] Create `lib/api/errorHandler.ts`
- [x] Map Django error responses to user messages
- [x] Handle HTTP status codes
- [x] 400 - Validation errors
- [x] 401 - Unauthorized
- [x] 403 - Forbidden
- [x] 404 - Not found
- [x] 429 - Rate limiting
- [x] 500+ - Server errors
- [x] Extract validation errors from Django format
- [x] Format error messages for UI display
- [x] Integrate with existing error logging
- [ ] Add Sentry integration (if available) - Deferred to later phase
- [x] Create user-friendly error messages
- [x] Handle network errors separately
### Acceptance Criteria
- [x] All Django errors are properly translated
- [x] Validation errors show field-specific messages
- [x] Errors are logged to monitoring
- [x] User sees helpful error messages
- [x] No stack traces exposed to users
### Testing
```typescript
// 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(url: string): Promise`
- [ ] `list(url: string, params?: any): Promise`
- [ ] `create(url: string, data: any): Promise`
- [ ] `update(url: string, data: any): Promise`
- [ ] `delete(url: string): Promise`
- [ ] Add pagination helper methods
- [ ] `getPaginated(url: string, params?: any): Promise>`
- [ ] 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
```typescript
// 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
```typescript
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
- [x] Task 1.0: Next.js 15 + Bun Setup
- [x] Task 1.1: Base API Client
- [ ] Task 1.2: Type Definitions - **DEFERRED** to be created as needed in Phases 2-11
- [x] 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](./PHASE_02_AUTHENTICATION.md)
---
## 🔗 Related Documentation
- [Environment Variables Guide](./ENVIRONMENT_VARIABLES.md)
- [Bun Setup Guide](./BUN_GUIDE.md)
- [Next.js 15 Migration Guide](./NEXTJS_15_MIGRATION_GUIDE.md)
- Next.js Documentation: https://nextjs.org/docs
- Bun Documentation: https://bun.sh/docs
---
**Document Version:** 2.0
**Last Updated:** November 9, 2025
**Changes:** Added Next.js 15 + App Router + Turbopack + Bun setup