# 🏗️ ThrillWiki Nuxt Frontend - Architecture Decisions

**Status:** ✅ COMPLETE  
**Last Updated:** 2025-01-27 19:58 UTC  
**Dependencies:** requirements.md  
**Blocks:** All implementation phases  

## 🎯 Architecture Overview

### System Architecture
```
┌─────────────────────────────────────────────────────────────┐
│                    ThrillWiki System                        │
├─────────────────────────────────────────────────────────────┤
│  Frontend (Nuxt 3)          │  Backend (Django)            │
│  ┌─────────────────────┐    │  ┌─────────────────────┐     │
│  │ Pages & Components  │    │  │ REST API (/api/v1/) │     │
│  │ ├─ Parks           │    │  │ ├─ Authentication    │     │
│  │ ├─ Rides           │    │  │ ├─ Parks CRUD        │     │
│  │ ├─ Auth            │    │  │ ├─ Rides CRUD        │     │
│  │ └─ Admin           │    │  │ ├─ Photos            │     │
│  └─────────────────────┘    │  │ └─ Moderation       │     │
│  ┌─────────────────────┐    │  └─────────────────────┘     │
│  │ Composables         │    │  ┌─────────────────────┐     │
│  │ ├─ useAuth          │◄───┼──┤ JWT Authentication  │     │
│  │ ├─ useApi           │◄───┼──┤ Token Management    │     │
│  │ ├─ useParks         │◄───┼──┤ CORS Configuration  │     │
│  │ └─ useRides         │    │  └─────────────────────┘     │
│  └─────────────────────┘    │                              │
│  ┌─────────────────────┐    │  ┌─────────────────────┐     │
│  │ Component Library   │    │  │ Database (PostgreSQL)│     │
│  │ ├─ UI Components    │    │  │ ├─ Parks             │     │
│  │ ├─ Forms            │    │  │ ├─ Rides             │     │
│  │ ├─ Navigation       │    │  │ ├─ Users             │     │
│  │ └─ Modals           │    │  │ └─ Photos            │     │
│  └─────────────────────┘    │  └─────────────────────┘     │
└─────────────────────────────────────────────────────────────┘
```

### Technology Stack Decisions

#### Frontend Framework: Nuxt 3
**Decision:** Use Nuxt 3 with Vue 3 Composition API  
**Rationale:**
- **Server-Side Rendering:** Better SEO and initial load performance
- **File-based Routing:** Intuitive page organization
- **Auto-imports:** Reduced boilerplate code
- **Built-in Optimization:** Image optimization, code splitting, etc.
- **TypeScript Support:** First-class TypeScript integration
- **Ecosystem:** Rich ecosystem with modules and plugins

**Alternatives Considered:**
- **Next.js:** Rejected due to React requirement
- **SvelteKit:** Rejected due to smaller ecosystem
- **Vite + Vue:** Rejected due to lack of SSR out-of-the-box

#### State Management: Pinia
**Decision:** Use Pinia for global state management  
**Rationale:**
- **Vue 3 Native:** Built specifically for Vue 3
- **TypeScript Support:** Excellent TypeScript integration
- **DevTools:** Great debugging experience
- **Modular:** Easy to organize stores by feature
- **Performance:** Optimized for Vue 3 reactivity

**Alternatives Considered:**
- **Vuex:** Rejected due to Vue 3 compatibility issues
- **Composables Only:** Rejected for complex state management needs

#### Component Library: TBD (User Choice Required)
**Status:** ⏳ PENDING USER DECISION  
**Options Analyzed:**

##### Option 1: Nuxt UI (Recommended)
```typescript
// Installation
npm install @nuxt/ui

// Configuration
export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  ui: {
    global: true,
    icons: ['heroicons']
  }
})
```

**Pros:**
- Built specifically for Nuxt 3
- Tailwind CSS integration
- Headless UI foundation (accessibility)
- TypeScript support
- Modern design system
- Tree-shakable

**Cons:**
- Newer library (less mature)
- Smaller component set
- Limited complex components

##### Option 2: Vuetify
```typescript
// Installation
npm install vuetify @mdi/font

// Configuration
import { createVuetify } from 'vuetify'
export default defineNuxtPlugin(() => {
  const vuetify = createVuetify({
    theme: { defaultTheme: 'light' }
  })
  return { provide: { vuetify } }
})
```

**Pros:**
- Mature, battle-tested
- Comprehensive component set
- Material Design system
- Strong community
- Good documentation

**Cons:**
- Large bundle size
- Material Design constraints
- Vue 3 support still evolving
- Less customizable

##### Option 3: PrimeVue
```typescript
// Installation
npm install primevue primeicons

// Configuration
import PrimeVue from 'primevue/config'
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(PrimeVue)
})
```

**Pros:**
- Enterprise-focused
- Comprehensive components
- Good TypeScript support
- Professional themes
- Accessibility features

**Cons:**
- Commercial themes cost
- Learning curve
- Less modern design
- Larger bundle size

#### Authentication: JWT with Refresh Tokens
**Decision:** Implement JWT authentication with refresh token mechanism  
**Rationale:**
- **Stateless:** No server-side session storage required
- **Scalable:** Works well with multiple frontend instances
- **Secure:** Short-lived access tokens with refresh mechanism
- **Standard:** Industry standard for API authentication

**Implementation Strategy:**
```typescript
// composables/useAuth.ts
export const useAuth = () => {
  const accessToken = useCookie('access_token', {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 15 * 60 // 15 minutes
  })
  
  const refreshToken = useCookie('refresh_token', {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 7 * 24 * 60 * 60 // 7 days
  })
  
  const refreshAccessToken = async () => {
    // Auto-refresh logic
  }
  
  return {
    login, logout, refreshAccessToken,
    isAuthenticated: computed(() => !!accessToken.value)
  }
}
```

#### API Integration: Custom Composables with $fetch
**Decision:** Use Nuxt's built-in $fetch with custom composables  
**Rationale:**
- **Built-in:** No additional HTTP client needed
- **SSR Compatible:** Works seamlessly with server-side rendering
- **Type Safe:** Full TypeScript support
- **Caching:** Built-in request caching
- **Error Handling:** Consistent error handling patterns

**Implementation Pattern:**
```typescript
// composables/useApi.ts
export const useApi = () => {
  const { $fetch } = useNuxtApp()
  const { accessToken } = useAuth()
  
  const apiCall = async (endpoint: string, options: any = {}) => {
    return await $fetch(`/api/v1${endpoint}`, {
      ...options,
      headers: {
        'Authorization': `Bearer ${accessToken.value}`,
        ...options.headers
      }
    })
  }
  
  return { apiCall }
}
```

### Project Structure Decisions

#### Directory Structure
```
frontend/
├── assets/                 # Static assets (images, fonts, etc.)
├── components/            # Vue components
│   ├── ui/               # UI library components
│   ├── layout/           # Layout components
│   ├── forms/            # Form components
│   └── features/         # Feature-specific components
│       ├── parks/        # Park-related components
│       ├── rides/        # Ride-related components
│       ├── auth/         # Authentication components
│       └── admin/        # Admin/moderation components
├── composables/          # Vue composables
│   ├── useAuth.ts        # Authentication logic
│   ├── useApi.ts         # API integration
│   ├── useParks.ts       # Parks data management
│   ├── useRides.ts       # Rides data management
│   └── useModeration.ts  # Moderation logic
├── layouts/              # Nuxt layouts
│   ├── default.vue       # Default layout
│   ├── auth.vue          # Authentication layout
│   └── admin.vue         # Admin layout
├── middleware/           # Route middleware
│   ├── auth.ts           # Authentication middleware
│   └── admin.ts          # Admin access middleware
├── pages/                # File-based routing
│   ├── index.vue         # Homepage
│   ├── parks/            # Parks pages
│   ├── rides/            # Rides pages
│   ├── auth/             # Authentication pages
│   └── admin/            # Admin pages
├── plugins/              # Nuxt plugins
│   ├── api.client.ts     # API configuration
│   └── context7.client.ts # Context7 integration
├── stores/               # Pinia stores
│   ├── auth.ts           # Authentication store
│   ├── parks.ts          # Parks store
│   └── ui.ts             # UI state store
├── types/                # TypeScript type definitions
│   ├── api.ts            # API response types
│   ├── auth.ts           # Authentication types
│   └── components.ts     # Component prop types
├── utils/                # Utility functions
│   ├── validation.ts     # Form validation
│   ├── formatting.ts     # Data formatting
│   └── constants.ts      # Application constants
├── nuxt.config.ts        # Nuxt configuration
├── package.json          # Dependencies
└── tsconfig.json         # TypeScript configuration
```

### Development Environment Decisions

#### Package Manager: npm
**Decision:** Use npm for package management  
**Rationale:**
- **Consistency:** Matches existing project setup
- **Reliability:** Stable and well-supported
- **Lock File:** package-lock.json for reproducible builds
- **CI/CD:** Easy integration with deployment pipelines

#### Development Server Configuration
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },
  
  // Development server configuration
  devServer: {
    port: 3000,
    host: '0.0.0.0'
  },
  
  // Proxy API calls to Django backend
  nitro: {
    devProxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  },
  
  // Runtime configuration
  runtimeConfig: {
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://localhost:8000/api/v1'
    }
  }
})
```

#### Environment Variables
```bash
# .env
NUXT_PUBLIC_API_BASE=http://localhost:8000/api/v1
NUXT_SECRET_JWT_SECRET=your-jwt-secret
NUXT_PUBLIC_APP_NAME=ThrillWiki
NUXT_PUBLIC_APP_VERSION=1.0.0
```

### Performance Optimization Decisions

#### Code Splitting Strategy
**Decision:** Implement route-based and component-based code splitting  
**Implementation:**
```typescript
// Lazy load heavy components
const PhotoGallery = defineAsyncComponent(() => import('~/components/PhotoGallery.vue'))

// Route-based splitting (automatic with Nuxt)
// pages/admin/ - Admin bundle
// pages/parks/ - Parks bundle
// pages/rides/ - Rides bundle
```

#### Image Optimization
**Decision:** Use Nuxt Image module for automatic optimization  
**Configuration:**
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/image'],
  image: {
    provider: 'ipx',
    quality: 80,
    format: ['webp', 'avif', 'jpg'],
    screens: {
      xs: 320,
      sm: 640,
      md: 768,
      lg: 1024,
      xl: 1280
    }
  }
})
```

#### Caching Strategy
**Decision:** Multi-layer caching approach  
**Layers:**
1. **Browser Cache:** Static assets with long cache times
2. **API Cache:** Response caching with TTL
3. **Component Cache:** Expensive component computations
4. **Route Cache:** Static route pre-generation

```typescript
// API caching example
export const useParks = () => {
  const { data: parks } = useLazyFetch('/api/v1/parks/', {
    key: 'parks-list',
    server: true,
    default: () => [],
    transform: (data: any) => data.results || data
  })
  
  return { parks }
}
```

### Security Decisions

#### Token Storage
**Decision:** Use HTTP-only cookies for token storage  
**Rationale:**
- **XSS Protection:** Tokens not accessible via JavaScript
- **CSRF Protection:** SameSite cookie attribute
- **Automatic Handling:** Browser handles cookie management

#### Input Validation
**Decision:** Client-side validation with server-side verification  
**Implementation:**
```typescript
// utils/validation.ts
import { z } from 'zod'

export const parkSchema = z.object({
  name: z.string().min(1).max(100),
  location: z.string().min(1),
  operator: z.string().optional(),
  status: z.enum(['OPERATING', 'CLOSED', 'UNDER_CONSTRUCTION'])
})

export type ParkInput = z.infer<typeof parkSchema>
```

#### CORS Configuration
**Decision:** Strict CORS policy for production  
**Django Configuration:**
```python
# backend/config/settings/production.py
CORS_ALLOWED_ORIGINS = [
    "https://thrillwiki.com",
    "https://www.thrillwiki.com"
]

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = False  # Never true in production
```

### Testing Strategy Decisions

#### Testing Framework: Vitest
**Decision:** Use Vitest for unit and component testing  
**Rationale:**
- **Vite Integration:** Fast test execution
- **Vue Support:** Excellent Vue component testing
- **TypeScript:** Native TypeScript support
- **Jest Compatible:** Familiar API for developers

#### E2E Testing: Playwright
**Decision:** Use Playwright for end-to-end testing  
**Rationale:**
- **Cross-browser:** Chrome, Firefox, Safari support
- **Mobile Testing:** Mobile browser simulation
- **Reliable:** Stable test execution
- **Modern:** Built for modern web applications

#### Testing Configuration
```typescript
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'happy-dom',
    coverage: {
      reporter: ['text', 'json', 'html'],
      threshold: {
        global: {
          branches: 80,
          functions: 80,
          lines: 80,
          statements: 80
        }
      }
    }
  }
})
```

### Deployment Decisions

#### Build Strategy
**Decision:** Hybrid rendering with static generation for public pages  
**Configuration:**
```typescript
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: [
        '/',
        '/parks',
        '/rides',
        '/about',
        '/privacy',
        '/terms'
      ]
    }
  },
  
  // Route rules for different rendering strategies
  routeRules: {
    '/': { prerender: true },
    '/parks': { prerender: true },
    '/rides': { prerender: true },
    '/admin/**': { ssr: false }, // SPA mode for admin
    '/auth/**': { ssr: false }   // SPA mode for auth
  }
})
```

#### Docker Configuration
**Decision:** Multi-stage Docker build for production  
**Dockerfile:**
```dockerfile
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/.output ./
EXPOSE 3000
CMD ["node", "server/index.mjs"]
```

### Context7 Integration Decisions

#### Documentation Strategy
**Decision:** Integrate Context7 for automatic documentation generation  
**Implementation:**
```typescript
// plugins/context7.client.ts
export default defineNuxtPlugin(() => {
  if (process.dev) {
    // Initialize Context7 connection
    const context7 = new Context7Client({
      endpoint: 'http://localhost:8080',
      project: 'thrillwiki-frontend'
    })
    
    // Auto-document API calls
    context7.trackApiCalls()
    
    // Document component usage
    context7.trackComponentUsage()
  }
})
```

#### Knowledge Preservation
**Decision:** Structured documentation with progress tracking  
**Features:**
- Automatic API endpoint documentation
- Component usage tracking
- Implementation decision logging
- Progress milestone tracking
- LLM handoff preparation

---

## 🔧 Implementation Priorities

### Phase 1: Foundation (Week 1)
1. **Project Setup:** Initialize Nuxt 3 with TypeScript
2. **Component Library:** Integrate chosen UI library
3. **Authentication:** Implement JWT auth system
4. **API Integration:** Set up Django backend communication
5. **Basic Layout:** Create header, footer, navigation

### Phase 2: Core Features (Week 2)
1. **Parks System:** Listing, detail, search functionality
2. **Rides System:** Listing, detail, filtering
3. **User Profiles:** Profile management and settings
4. **Photo System:** Upload, display, basic moderation

### Phase 3: Advanced Features (Week 3)
1. **Submission System:** Content submission workflow
2. **Moderation Interface:** Admin tools and queues
3. **Advanced Search:** Filters, autocomplete, suggestions
4. **Maps Integration:** Location visualization

### Phase 4: Polish & Deployment (Week 4)
1. **Performance Optimization:** Bundle size, loading times
2. **Testing:** Comprehensive test suite
3. **Documentation:** Complete user and developer docs
4. **Deployment:** Production setup and monitoring

---

## 🚨 Critical Dependencies

### Immediate Blockers
1. **Component Library Choice:** Must be decided before implementation
2. **Django JWT Setup:** Backend enhancement required
3. **Development Environment:** CORS and proxy configuration

### Technical Dependencies
1. **Node.js 18+:** Required for Nuxt 3
2. **Django Backend:** Must be running for development
3. **PostgreSQL:** Database must be accessible
4. **Context7:** Integration approach needs clarification

---

**Next Document:** `component-library-analysis.md` - Detailed analysis of chosen library  
**Status:** Ready for component library decision and implementation start
