mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 12:11:13 -05:00
557 lines
14 KiB
Markdown
557 lines
14 KiB
Markdown
# 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 <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
|
|
```typescript
|
|
// 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
|
|
- [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<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
|
|
```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
|