Some checks failed
Build and Deploy to k3s / build-and-deploy (push) Failing after 1m31s
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>
403 lines
17 KiB
Markdown
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
|