Alexis Bruneteau b83c7a7d6d
Some checks failed
Build and Deploy to k3s / build-and-deploy (push) Failing after 1m31s
feat(migration): migrate from Angular 20 to Next.js 15
Complete framework migration from Angular to Next.js with full feature parity.

## What Changed
- Migrated from Angular 20 to Next.js 15 with App Router
- Replaced Angular components with React functional components
- Implemented React Context API for state management (replacing RxJS)
- Integrated React Hook Form for form handling
- Added shadcn/ui component library
- Configured Tailwind CSS 4.1 with @tailwindcss/postcss
- Implemented JWT authentication with middleware protection

## Core Features Implemented
-  User registration and login with validation
-  JWT token authentication with localStorage
-  Protected dashboard route with middleware
-  Portfolio listing with status indicators
-  Create portfolio functionality
-  ZIP file upload with progress tracking
-  Portfolio deployment
-  Responsive design with Tailwind CSS

## Technical Stack
- Framework: Next.js 15 (App Router)
- Language: TypeScript 5.8
- Styling: Tailwind CSS 4.1
- UI Components: shadcn/ui + Lucide icons
- State: React Context API + hooks
- Forms: React Hook Form
- API Client: Native fetch with custom wrapper

## File Structure
- /app - Next.js pages (landing, login, register, dashboard)
- /components - React components (ui primitives, auth provider)
- /lib - API client, types, utilities
- /hooks - Custom hooks (useAuth, usePortfolios)
- /middleware.ts - Route protection
- /angular-backup - Preserved Angular source code

## API Compatibility
- All backend endpoints remain unchanged
- JWT Bearer token authentication preserved
- API response format maintained

## Build Output
- Production build: 7 routes compiled successfully
- Bundle size: ~102kB shared JS (optimized)
- First Load JS: 103-126kB per route

## Documentation
- Updated README.md with Next.js setup guide
- Created OpenSpec proposal in openspec/changes/migrate-to-nextjs-launchui/
- Added project context in openspec/project.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 00:34:43 +02:00

403 lines
17 KiB
Markdown

# Technical Design: Next.js + Launch UI Migration
## Context
The hosting-frontend application is currently built with Angular 20, using standalone components, reactive forms, and RxJS for state management. The backend API is a separate service that will remain unchanged during this migration.
### Current Architecture
- **Framework**: Angular 20 with standalone components
- **Routing**: Angular Router with lazy loading
- **State**: RxJS BehaviorSubjects for auth token management
- **Forms**: ReactiveFormsModule with custom validators
- **Styling**: Tailwind CSS v4 with custom components
- **Authentication**: JWT tokens in localStorage, HTTP interceptor for Bearer token injection
### Target Architecture
- **Framework**: Next.js 15 with App Router
- **Component Library**: Launch UI (shadcn/ui + Tailwind CSS 4.0)
- **State**: React Context API + hooks (useState, useEffect, useContext)
- **Forms**: React Hook Form (aligns with Launch UI patterns)
- **Styling**: Tailwind CSS 4.0 (maintained) + Launch UI components
- **Authentication**: Next.js middleware + API route handlers + React Context
### Constraints
- Backend API endpoints must remain unchanged
- JWT authentication pattern must be preserved
- User sessions should be preserved during deployment (stretch goal)
- Deployment infrastructure (Dockerfile) must support Next.js
## Goals / Non-Goals
### Goals
1. **Complete Framework Migration**: Replace Angular with Next.js 15
2. **Launch UI Integration**: Utilize all free Launch UI components (Navbar, Hero, Items, Logos, FAQ, Stats, CTA, Footer)
3. **API Compatibility**: Maintain 100% compatibility with existing backend API
4. **Performance Improvement**: Achieve better Core Web Vitals through SSR
5. **Developer Experience**: Simplify component development with pre-built Launch UI primitives
6. **SEO Enhancement**: Leverage Next.js metadata API for better search engine optimization
### Non-Goals
1. Backend API changes (out of scope)
2. Database schema modifications
3. Authentication mechanism changes (JWT remains)
4. Deployment platform changes (Dockerfile-based deployment maintained)
5. Pro Launch UI components (keep budget low with free version only)
## Decisions
### Decision 1: App Router over Pages Router
**Choice**: Use Next.js App Router (`/app` directory)
**Rationale**:
- Launch UI is built for App Router patterns
- Better TypeScript support and DX
- Native React Server Components support
- Future-proof architecture (Pages Router is legacy)
**Alternatives Considered**:
- Pages Router: Rejected due to legacy status and incompatibility with Launch UI examples
### Decision 2: React Hook Form over React Final Form
**Choice**: Use React Hook Form for form management
**Rationale**:
- Smaller bundle size (9KB vs 20KB+)
- Better TypeScript support
- Native integration with shadcn/ui (Launch UI's foundation)
- More active community and maintenance
**Alternatives Considered**:
- Formik: Rejected due to larger bundle size and performance overhead
- React Final Form: Good alternative but less community momentum
### Decision 3: React Context + Hooks over Redux/Zustand
**Choice**: Use React Context API with custom hooks for state management
**Rationale**:
- Application state is simple (auth token, user info, portfolio list)
- Avoids unnecessary dependencies and complexity
- Aligns with Next.js best practices for small-to-medium apps
- Easy migration path from RxJS BehaviorSubject patterns
**Alternatives Considered**:
- Zustand: Good option for scaling, but premature optimization
- Redux Toolkit: Overkill for current state complexity
### Decision 4: Fetch API with Custom Wrapper over Axios
**Choice**: Use native `fetch` with custom API client wrapper
**Rationale**:
- Next.js optimizes `fetch` with automatic request deduplication
- Smaller bundle size (no axios dependency)
- Better server-side rendering support
- Launch UI examples use fetch patterns
**Alternatives Considered**:
- Axios: Familiar from Angular HttpClient, but adds bundle size
- SWR/React Query: Considered for later optimization if needed
### Decision 5: Parallel Deployment Strategy
**Choice**: Deploy Next.js version as separate build, then cutover DNS/routing
**Rationale**:
- Minimizes risk of downtime
- Allows A/B testing or gradual rollout
- Easy rollback if issues discovered
**Migration Steps**:
1. Build Next.js version in new repository/branch
2. Deploy to staging environment
3. Run parallel production deployment (different subdomain)
4. Validate functionality and performance
5. Cutover DNS or reverse proxy routing
6. Monitor for 48 hours before deprecating Angular version
**Alternatives Considered**:
- Big Bang Deployment: Rejected due to high risk
- Feature Flag Migration: Overly complex for complete framework change
### Decision 6: Component Mapping Strategy
| Angular Component | Next.js Equivalent | Launch UI Component |
|-------------------|-------------------|---------------------|
| LandingComponent | `/app/page.tsx` | Hero, Items, Logos, FAQ, CTA |
| LoginComponent | `/app/login/page.tsx` | Custom form with shadcn/ui inputs |
| RegisterComponent | `/app/register/page.tsx` | Custom form with shadcn/ui inputs |
| DashboardComponent | `/app/dashboard/page.tsx` | Custom with Stats component integration |
| AppComponent | `/app/layout.tsx` | Navbar + Footer from Launch UI |
### Decision 7: TypeScript Configuration
**Choice**: Downgrade from TypeScript 5.8 to TypeScript 5.0 (Launch UI requirement)
**Rationale**:
- Launch UI tested with TypeScript 5.0
- Next.js 15 supports TypeScript 5.0+
- Minimal risk from downgrade (no critical features lost)
## Architecture Diagrams
### Current Angular Architecture
```
┌─────────────────────────────────────────┐
│ Angular 20 Application │
├─────────────────────────────────────────┤
│ Components (Standalone) │
│ ├── Landing, Login, Register, Dashboard│
│ └── Angular Router │
├─────────────────────────────────────────┤
│ Services Layer │
│ ├── ApiService (HttpClient) │
│ └── PortfolioService │
├─────────────────────────────────────────┤
│ State Management (RxJS) │
│ └── BehaviorSubject (auth token) │
├─────────────────────────────────────────┤
│ HTTP Interceptor (Auth) │
└─────────────────────────────────────────┘
↓ HTTP Requests
┌─────────────────────────────────────────┐
│ Backend API (Unchanged) │
│ /api/auth/*, /api/portfolios/* │
└─────────────────────────────────────────┘
```
### Target Next.js Architecture
```
┌─────────────────────────────────────────┐
│ Next.js 15 Application │
├─────────────────────────────────────────┤
│ App Router (RSC + Client Components) │
│ ├── / (page.tsx) - Landing │
│ ├── /login (page.tsx) │
│ ├── /register (page.tsx) │
│ └── /dashboard (page.tsx) │
├─────────────────────────────────────────┤
│ Launch UI Components │
│ ├── Navbar, Hero, Items, Logos │
│ ├── FAQ, Stats, CTA, Footer │
│ └── shadcn/ui primitives │
├─────────────────────────────────────────┤
│ React State Management │
│ ├── AuthContext (Context API) │
│ ├── useAuth() hook │
│ └── useState/useEffect │
├─────────────────────────────────────────┤
│ API Client Layer │
│ ├── /lib/api-client.ts (fetch wrapper) │
│ └── API route handlers (optional) │
├─────────────────────────────────────────┤
│ Middleware (Auth) │
│ └── middleware.ts (JWT validation) │
└─────────────────────────────────────────┘
↓ HTTP Requests
┌─────────────────────────────────────────┐
│ Backend API (Unchanged) │
│ /api/auth/*, /api/portfolios/* │
└─────────────────────────────────────────┘
```
## Data Models (Preserved)
### Portfolio Model
```typescript
// Maintained from Angular version
interface Portfolio {
active: boolean;
id: number;
name: string;
domain: string;
path?: string;
created_at: string;
updated_at: string;
}
```
### API Response Model
```typescript
// Maintained from Angular version
interface ApiResponse<T = any> {
success: boolean;
data?: T;
message?: string;
errors?: any;
}
```
## Authentication Flow
### Current (Angular)
1. User submits login form
2. `ApiService.post<LoginResponse>('/auth/login', credentials)`
3. Response includes JWT token
4. Token stored in localStorage
5. `tokenSubject.next(token)` updates RxJS state
6. HTTP Interceptor adds `Authorization: Bearer ${token}` to all requests
7. 401 responses trigger logout and redirect
### Target (Next.js)
1. User submits login form (client component)
2. `POST /api/auth/login` via fetch wrapper
3. Response includes JWT token
4. Token stored in localStorage (client-side)
5. `setAuthToken(token)` updates React Context
6. API client function adds `Authorization: Bearer ${token}` header
7. Middleware validates token on protected routes
8. 401 responses trigger logout and redirect via context hook
## File Structure
```
hosting-frontend/
├── app/
│ ├── layout.tsx # Root layout (Navbar + Footer)
│ ├── page.tsx # Landing page (Launch UI Hero, Items, etc.)
│ ├── login/
│ │ └── page.tsx # Login form
│ ├── register/
│ │ └── page.tsx # Registration form
│ └── dashboard/
│ └── page.tsx # Dashboard (protected)
├── components/
│ ├── launch-ui/ # Launch UI components
│ │ ├── navbar.tsx
│ │ ├── hero.tsx
│ │ ├── items.tsx
│ │ ├── logos.tsx
│ │ ├── faq.tsx
│ │ ├── stats.tsx
│ │ ├── cta.tsx
│ │ └── footer.tsx
│ ├── ui/ # shadcn/ui primitives
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ ├── card.tsx
│ │ └── ...
│ └── auth/
│ └── auth-provider.tsx # React Context for auth state
├── lib/
│ ├── api-client.ts # Fetch wrapper with auth
│ └── utils.ts # Utility functions
├── hooks/
│ ├── use-auth.ts # Custom auth hook
│ └── use-portfolios.ts # Portfolio data fetching hook
├── middleware.ts # Route protection
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
└── package.json
```
## Risks / Trade-offs
### Risk 1: Complete Codebase Rewrite
- **Risk**: High chance of bugs, missing features, regression issues
- **Mitigation**:
- Comprehensive test plan covering all user flows
- Parallel deployment with gradual rollout
- Feature parity checklist before cutover
- Extended QA period in staging environment
### Risk 2: Team Learning Curve
- **Risk**: Developers unfamiliar with Next.js patterns may introduce anti-patterns
- **Mitigation**:
- Code review process with Next.js best practices checklist
- Reference Launch UI examples as canonical patterns
- Pair programming sessions during initial development
- Documentation of patterns and conventions
### Risk 3: SSR Performance Issues
- **Risk**: Server-side rendering could introduce latency vs. client-side Angular
- **Mitigation**:
- Use static generation where possible (`generateStaticParams`)
- Implement proper caching strategies (Next.js cache headers)
- Monitor Core Web Vitals and API response times
- Use React Server Components for data fetching
### Risk 4: Launch UI Customization Limitations
- **Risk**: Launch UI components may not match exact design requirements
- **Mitigation**:
- Evaluate component customizability before full migration
- Budget for custom component development if needed
- Consider Pro version if free components insufficient
- Leverage shadcn/ui flexibility for customization
### Risk 5: Session Preservation During Migration
- **Risk**: Users may lose active sessions during cutover
- **Mitigation**:
- Deploy during low-traffic window
- Communicate planned maintenance window
- Implement session migration script if feasible
- Provide clear re-authentication flow
## Migration Plan
### Phase 1: Foundation Setup (Week 1)
- [ ] Initialize Next.js 15 project with App Router
- [ ] Install Launch UI and shadcn/ui dependencies
- [ ] Configure Tailwind CSS 4.0
- [ ] Set up TypeScript 5.0 configuration
- [ ] Create API client wrapper with auth support
- [ ] Implement AuthContext and useAuth hook
### Phase 2: Core Pages Migration (Week 2-3)
- [ ] Build Landing page with Launch UI components (Hero, Items, Logos, FAQ, CTA)
- [ ] Migrate Login component to Next.js with React Hook Form
- [ ] Migrate Register component with validation
- [ ] Implement authentication flow and middleware
- [ ] Add Navbar and Footer from Launch UI
### Phase 3: Dashboard & Protected Routes (Week 4)
- [ ] Build Dashboard page with portfolio listing
- [ ] Implement portfolio upload functionality
- [ ] Add portfolio deployment features
- [ ] Integrate Stats component for dashboard metrics
- [ ] Implement route protection middleware
### Phase 4: Testing & Validation (Week 5)
- [ ] End-to-end testing of all user flows
- [ ] Performance testing and optimization
- [ ] Cross-browser compatibility testing
- [ ] Mobile responsiveness validation
- [ ] API compatibility verification
### Phase 5: Deployment & Cutover (Week 6)
- [ ] Deploy to staging environment
- [ ] Run parallel production deployment
- [ ] Conduct UAT with stakeholders
- [ ] Perform gradual traffic rollout (10% → 50% → 100%)
- [ ] Monitor errors and performance metrics
- [ ] Complete cutover and deprecate Angular version
### Rollback Plan
If critical issues discovered post-deployment:
1. Revert DNS/routing to Angular version (5 minute rollback)
2. Investigate issues in Next.js version
3. Fix and redeploy when stable
4. Retry cutover after validation
## Performance Targets
| Metric | Current (Angular) | Target (Next.js) |
|--------|-------------------|------------------|
| First Contentful Paint | ~1.5s | <1.0s |
| Largest Contentful Paint | ~2.0s | <1.5s |
| Time to Interactive | ~2.5s | <2.0s |
| Bundle Size (JS) | ~500KB | <400KB |
| Lighthouse Score | 75-85 | 90+ |
## Open Questions
1. **Q**: Should we use Next.js API routes as a proxy to the backend, or call backend directly from client?
- **Recommendation**: Call backend directly from client (simpler, maintains current architecture)
- **Alternative**: Use API routes for sensitive endpoints requiring additional validation
2. **Q**: Do we need Pro version of Launch UI for advanced components?
- **Recommendation**: Start with free version, evaluate need based on design requirements
- **Budget**: Pro version is $99 one-time if needed
3. **Q**: Should we implement real-time updates for portfolio deployment status?
- **Recommendation**: Defer to post-migration enhancement (use polling initially)
- **Alternative**: Integrate WebSocket support if backend provides it
4. **Q**: How do we handle environment variables in Next.js vs Angular?
- **Recommendation**: Use Next.js environment variable conventions (`NEXT_PUBLIC_*` for client-side)
- **Migration**: Map `environment.ts` values to `.env.local` and `.env.production`
5. **Q**: Should we implement server-side session management instead of client-side JWT?
- **Recommendation**: Maintain client-side JWT pattern for consistency with backend
- **Future Enhancement**: Consider server-side sessions in future backend refactor