941 lines
31 KiB
Markdown
941 lines
31 KiB
Markdown
# Frontend Implementation Plan - ColaFlow Enterprise Features
|
|
|
|
## Document Overview
|
|
|
|
This document provides a detailed technical implementation plan for ColaFlow's enterprise-level multi-tenant, SSO, and MCP Token management features on the frontend.
|
|
|
|
**Target Timeline**: Days 5-7 of development
|
|
**Tech Stack**: Next.js 16 (App Router) + React 19 + TypeScript 5 + Zustand + TanStack Query v5 + shadcn/ui + Tailwind CSS 4
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Architecture Overview](#architecture-overview)
|
|
2. [File Structure](#file-structure)
|
|
3. [Dependencies](#dependencies)
|
|
4. [Development Phases](#development-phases)
|
|
5. [Testing Strategy](#testing-strategy)
|
|
6. [Performance Optimization](#performance-optimization)
|
|
7. [Security Checklist](#security-checklist)
|
|
8. [Deployment Checklist](#deployment-checklist)
|
|
|
|
---
|
|
|
|
## Architecture Overview
|
|
|
|
### Frontend Architecture Layers
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ UI Layer (Pages) │
|
|
│ - Login/Signup Pages (SSO) │
|
|
│ - Settings Pages (Tenant, SSO, MCP Tokens) │
|
|
│ - Auth Callback Pages │
|
|
└────────────────────────┬────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────▼────────────────────────────────────────┐
|
|
│ Component Layer │
|
|
│ - SsoButton, TenantSlugInput, PasswordStrengthIndicator │
|
|
│ - McpPermissionMatrix, TokenDisplay, SsoConfigForm │
|
|
└────────────────────────┬────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────▼────────────────────────────────────────┐
|
|
│ State Management Layer │
|
|
│ Zustand (Client State) TanStack Query (Server State) │
|
|
│ - useAuthStore - useLogin, useCheckSlug │
|
|
│ - TenantContext - useMcpTokens, useSsoConfig │
|
|
└────────────────────────┬────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────▼────────────────────────────────────────┐
|
|
│ Service Layer │
|
|
│ - authService (login, loginWithSso, logout, refresh) │
|
|
│ - tenantService (checkSlug, updateSso, testSso) │
|
|
│ - mcpService (listTokens, createToken, revokeToken) │
|
|
└────────────────────────┬────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────▼────────────────────────────────────────┐
|
|
│ API Client Layer │
|
|
│ - Axios instance with interceptors │
|
|
│ - Auto Token injection (Authorization header) │
|
|
│ - Auto Token refresh on 401 │
|
|
│ - Tenant ID injection (X-Tenant-Id header) │
|
|
└────────────────────────┬────────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────▼────────────────────────────────────────┐
|
|
│ Backend API (.NET 9) │
|
|
│ - http://localhost:5000/api │
|
|
└──────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### State Management Strategy
|
|
|
|
| State Type | Technology | Purpose | Example |
|
|
|------------|------------|---------|---------|
|
|
| **Client State** | Zustand | Authentication, UI state, user preferences | `useAuthStore` (user, tenant, accessToken) |
|
|
| **Server State** | TanStack Query | API data, caching, mutations | `useMcpTokens`, `useCheckSlug` |
|
|
| **Form State** | React Hook Form | Form validation, submission | Signup form, SSO config form |
|
|
|
|
**Key Principle**:
|
|
- Zustand stores **authentication context** (user, tenant, token)
|
|
- TanStack Query handles **all API data** (projects, issues, tokens)
|
|
- No duplication: Auth data flows from Zustand → API Client → TanStack Query
|
|
|
|
---
|
|
|
|
## File Structure
|
|
|
|
### Complete Frontend Structure
|
|
|
|
```
|
|
colaflow-web/
|
|
├── app/ # Next.js 16 App Router
|
|
│ ├── (auth)/ # Auth layout group
|
|
│ │ ├── login/
|
|
│ │ │ └── page.tsx # Login page (local + SSO)
|
|
│ │ ├── signup/
|
|
│ │ │ └── page.tsx # Tenant registration
|
|
│ │ ├── auth/
|
|
│ │ │ └── callback/
|
|
│ │ │ └── page.tsx # SSO callback handler
|
|
│ │ └── suspended/
|
|
│ │ └── page.tsx # Tenant suspended page
|
|
│ │
|
|
│ ├── (dashboard)/ # Dashboard layout group
|
|
│ │ ├── layout.tsx # Protected layout
|
|
│ │ ├── dashboard/
|
|
│ │ │ └── page.tsx # Home page
|
|
│ │ └── settings/
|
|
│ │ ├── organization/
|
|
│ │ │ └── page.tsx # Tenant settings + SSO config
|
|
│ │ └── mcp-tokens/
|
|
│ │ └── page.tsx # MCP Token management
|
|
│ │
|
|
│ ├── layout.tsx # Root layout (Providers)
|
|
│ └── middleware.ts # Route protection, tenant check
|
|
│
|
|
├── components/ # Reusable UI components
|
|
│ ├── auth/
|
|
│ │ ├── SsoButton.tsx # SSO provider button
|
|
│ │ ├── PasswordStrengthIndicator.tsx
|
|
│ │ └── TenantSlugInput.tsx # Real-time slug validation
|
|
│ ├── settings/
|
|
│ │ ├── SsoConfigForm.tsx # Dynamic SSO form (OIDC/SAML)
|
|
│ │ └── McpPermissionMatrix.tsx # Checkbox grid for permissions
|
|
│ ├── mcp/
|
|
│ │ ├── TokenDisplay.tsx # Copy/download token
|
|
│ │ ├── CreateTokenDialog.tsx # Multi-step token creation
|
|
│ │ └── AuditLogTable.tsx # Token usage logs
|
|
│ └── ui/ # shadcn/ui components
|
|
│ ├── button.tsx
|
|
│ ├── dialog.tsx
|
|
│ ├── form.tsx
|
|
│ └── ... (other shadcn components)
|
|
│
|
|
├── stores/ # Zustand stores
|
|
│ ├── useAuthStore.ts # Auth state (user, tenant, token)
|
|
│ └── useUiStore.ts # UI state (sidebar, theme)
|
|
│
|
|
├── contexts/ # React Contexts
|
|
│ └── TenantContext.tsx # Tenant info provider
|
|
│
|
|
├── hooks/ # Custom React hooks
|
|
│ ├── auth/
|
|
│ │ ├── useLogin.ts # TanStack Query: login mutation
|
|
│ │ ├── useLoginWithSso.ts # SSO login logic
|
|
│ │ └── useLogout.ts # Logout mutation
|
|
│ ├── tenants/
|
|
│ │ ├── useCheckSlug.ts # Debounced slug validation
|
|
│ │ ├── useSsoConfig.ts # Get/Update SSO config
|
|
│ │ └── useTestSsoConnection.ts # Test SSO connection
|
|
│ └── mcp/
|
|
│ ├── useMcpTokens.ts # List tokens
|
|
│ ├── useCreateMcpToken.ts # Create token mutation
|
|
│ ├── useRevokeMcpToken.ts # Revoke token mutation
|
|
│ └── useMcpAuditLogs.ts # Token audit logs
|
|
│
|
|
├── services/ # API service layer
|
|
│ ├── auth.service.ts # Auth API calls
|
|
│ ├── tenant.service.ts # Tenant API calls
|
|
│ └── mcp.service.ts # MCP API calls
|
|
│
|
|
├── lib/ # Utilities
|
|
│ ├── api-client.ts # Axios instance + interceptors
|
|
│ ├── query-client.ts # TanStack Query config
|
|
│ ├── utils.ts # Helper functions (cn, etc.)
|
|
│ └── validations.ts # Zod schemas
|
|
│
|
|
├── types/ # TypeScript types
|
|
│ ├── auth.ts # LoginCredentials, User, Tenant
|
|
│ ├── mcp.ts # McpToken, McpPermission
|
|
│ ├── api.ts # ApiResponse, ApiError
|
|
│ └── index.ts # Re-exports
|
|
│
|
|
├── public/ # Static assets
|
|
│ └── logos/
|
|
│ ├── azure-ad.svg
|
|
│ ├── google.svg
|
|
│ └── okta.svg
|
|
│
|
|
├── __tests__/ # Unit + integration tests
|
|
│ ├── components/
|
|
│ ├── hooks/
|
|
│ └── pages/
|
|
│
|
|
├── .env.local # Environment variables
|
|
├── next.config.js # Next.js config
|
|
├── tailwind.config.ts # Tailwind config
|
|
└── tsconfig.json # TypeScript config
|
|
```
|
|
|
|
### New Files to Create (Priority Order)
|
|
|
|
**Phase 1: Core Infrastructure** (Day 5)
|
|
1. `lib/api-client.ts` - Axios with interceptors
|
|
2. `stores/useAuthStore.ts` - Zustand auth store
|
|
3. `types/auth.ts`, `types/mcp.ts`, `types/api.ts` - TypeScript types
|
|
4. `services/auth.service.ts` - Auth API service
|
|
5. `app/middleware.ts` - Route protection
|
|
|
|
**Phase 2: Authentication** (Day 5-6)
|
|
6. `app/(auth)/login/page.tsx` - Login page
|
|
7. `app/(auth)/signup/page.tsx` - Signup page
|
|
8. `app/(auth)/auth/callback/page.tsx` - SSO callback
|
|
9. `hooks/auth/useLogin.ts` - Login hook
|
|
10. `components/auth/SsoButton.tsx` - SSO button
|
|
|
|
**Phase 3: Settings Pages** (Day 6)
|
|
11. `app/(dashboard)/settings/organization/page.tsx` - SSO config
|
|
12. `app/(dashboard)/settings/mcp-tokens/page.tsx` - MCP tokens
|
|
13. `components/settings/SsoConfigForm.tsx` - SSO form
|
|
14. `components/mcp/CreateTokenDialog.tsx` - Token creation
|
|
|
|
**Phase 4: MCP Features** (Day 7)
|
|
15. `services/mcp.service.ts` - MCP API service
|
|
16. `hooks/mcp/useMcpTokens.ts` - MCP hooks
|
|
17. `components/mcp/McpPermissionMatrix.tsx` - Permission UI
|
|
18. `components/mcp/TokenDisplay.tsx` - Token display
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
### Required npm Packages
|
|
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"next": "^16.0.0",
|
|
"react": "^19.0.0",
|
|
"react-dom": "^19.0.0",
|
|
"typescript": "^5.6.0",
|
|
|
|
"zustand": "^5.0.0",
|
|
"@tanstack/react-query": "^5.60.0",
|
|
"axios": "^1.7.0",
|
|
|
|
"react-hook-form": "^7.53.0",
|
|
"zod": "^3.23.0",
|
|
"@hookform/resolvers": "^3.9.0",
|
|
|
|
"@radix-ui/react-dialog": "^1.1.0",
|
|
"@radix-ui/react-select": "^2.1.0",
|
|
"@radix-ui/react-checkbox": "^1.1.0",
|
|
"@radix-ui/react-tabs": "^1.1.0",
|
|
"class-variance-authority": "^0.7.0",
|
|
"clsx": "^2.1.0",
|
|
"tailwind-merge": "^2.5.0",
|
|
"tailwindcss": "^4.0.0",
|
|
|
|
"jose": "^5.9.0",
|
|
"sonner": "^1.7.0",
|
|
"date-fns": "^4.1.0",
|
|
"zxcvbn": "^4.4.2"
|
|
},
|
|
"devDependencies": {
|
|
"@testing-library/react": "^16.0.0",
|
|
"@testing-library/jest-dom": "^6.5.0",
|
|
"@testing-library/user-event": "^14.5.0",
|
|
"vitest": "^2.1.0",
|
|
"msw": "^2.6.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Installation Command
|
|
|
|
```bash
|
|
cd colaflow-web
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Install shadcn/ui components
|
|
npx shadcn@latest init
|
|
npx shadcn@latest add button dialog form input select checkbox tabs alert table
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
**File**: `.env.local`
|
|
|
|
```env
|
|
# API Configuration
|
|
NEXT_PUBLIC_API_URL=http://localhost:5000/api
|
|
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
|
|
# JWT Configuration (for middleware validation)
|
|
JWT_SECRET=your-jwt-secret-key-from-backend
|
|
|
|
# Feature Flags
|
|
NEXT_PUBLIC_ENABLE_SSO=true
|
|
NEXT_PUBLIC_ENABLE_MCP_TOKENS=true
|
|
```
|
|
|
|
---
|
|
|
|
## Development Phases
|
|
|
|
### Phase 1: Core Infrastructure (Day 5 - Morning)
|
|
|
|
**Estimated Time**: 3-4 hours
|
|
|
|
#### 1.1 API Client Setup
|
|
|
|
**File**: `lib/api-client.ts`
|
|
|
|
**Tasks**:
|
|
- Create Axios instance with base URL
|
|
- Implement request interceptor (add Authorization header)
|
|
- Implement response interceptor (handle 401, refresh token)
|
|
- Add error handling and retry logic
|
|
|
|
**Success Criteria**:
|
|
- ✅ All API requests automatically include `Authorization: Bearer {token}`
|
|
- ✅ 401 errors trigger automatic token refresh
|
|
- ✅ Refresh only happens once for concurrent requests
|
|
- ✅ Failed refresh redirects to `/login`
|
|
|
|
#### 1.2 Auth Store Setup
|
|
|
|
**File**: `stores/useAuthStore.ts`
|
|
|
|
**Tasks**:
|
|
- Define `AuthState` interface (user, tenant, accessToken, isAuthenticated)
|
|
- Implement `login`, `logout`, `refreshToken` actions
|
|
- Implement `setUser` and `clearAuth` helpers
|
|
- Add automatic token refresh (5 min before expiry)
|
|
|
|
**Success Criteria**:
|
|
- ✅ Auth state persists across page reloads (use `zustand/middleware`)
|
|
- ✅ Token stored in memory (not localStorage)
|
|
- ✅ Automatic refresh works before token expires
|
|
|
|
#### 1.3 TypeScript Types
|
|
|
|
**Files**: `types/auth.ts`, `types/mcp.ts`, `types/api.ts`
|
|
|
|
**Tasks**:
|
|
- Define all API request/response types
|
|
- Define Zustand store types
|
|
- Export types in `types/index.ts`
|
|
|
|
**Success Criteria**:
|
|
- ✅ No TypeScript errors
|
|
- ✅ Full IntelliSense support in VSCode
|
|
|
|
---
|
|
|
|
### Phase 2: Authentication Pages (Day 5 - Afternoon + Day 6 - Morning)
|
|
|
|
**Estimated Time**: 6-8 hours
|
|
|
|
#### 2.1 Login Page
|
|
|
|
**File**: `app/(auth)/login/page.tsx`
|
|
|
|
**Features**:
|
|
- Local login form (email + password)
|
|
- SSO buttons (Azure AD, Google, Okta)
|
|
- "Forgot password" link
|
|
- "Sign up" link
|
|
- Remember me checkbox
|
|
- Loading states
|
|
- Error handling
|
|
|
|
**Components to create**:
|
|
- `components/auth/SsoButton.tsx` - Provider-specific button
|
|
- `hooks/auth/useLogin.ts` - TanStack Query mutation
|
|
- `hooks/auth/useLoginWithSso.ts` - SSO redirect logic
|
|
|
|
**Success Criteria**:
|
|
- ✅ Local login works and redirects to dashboard
|
|
- ✅ SSO buttons redirect to backend SSO endpoint
|
|
- ✅ Form validation with Zod
|
|
- ✅ Error messages displayed with `sonner` toast
|
|
|
|
#### 2.2 Signup Page
|
|
|
|
**File**: `app/(auth)/signup/page.tsx`
|
|
|
|
**Features**:
|
|
- Multi-step form (3 steps):
|
|
1. Organization info (name, slug)
|
|
2. Admin user (email, password, full name)
|
|
3. Subscription plan selection
|
|
- Real-time slug validation (debounce 500ms)
|
|
- Password strength indicator
|
|
- Terms of service checkbox
|
|
|
|
**Components to create**:
|
|
- `components/auth/TenantSlugInput.tsx` - Slug input with validation
|
|
- `components/auth/PasswordStrengthIndicator.tsx` - zxcvbn integration
|
|
- `components/auth/SubscriptionPlanCard.tsx` - Plan selection
|
|
- `hooks/tenants/useCheckSlug.ts` - TanStack Query for slug check
|
|
|
|
**Success Criteria**:
|
|
- ✅ Slug validation shows "Available" or "Taken" in real-time
|
|
- ✅ Password strength indicator works (weak/medium/strong)
|
|
- ✅ Plan selection highlights selected plan
|
|
- ✅ After signup, user is logged in automatically
|
|
|
|
#### 2.3 SSO Callback Page
|
|
|
|
**File**: `app/(auth)/auth/callback/page.tsx`
|
|
|
|
**Features**:
|
|
- Parse URL parameters (`?token=xxx&tenant=yyy`)
|
|
- Validate state parameter (CSRF protection)
|
|
- Store token in AuthStore
|
|
- Redirect to original page or dashboard
|
|
- Error handling (SSO failed)
|
|
|
|
**Success Criteria**:
|
|
- ✅ Token extracted from URL and stored
|
|
- ✅ User redirected to dashboard
|
|
- ✅ Invalid state shows error page
|
|
- ✅ Error page has "Try again" button
|
|
|
|
#### 2.4 Next.js Middleware
|
|
|
|
**File**: `app/middleware.ts`
|
|
|
|
**Features**:
|
|
- Protect routes requiring authentication
|
|
- Verify JWT token (use `jose` library)
|
|
- Check tenant status (Active/Suspended)
|
|
- Redirect logic:
|
|
- Unauthenticated → `/login?redirect=/original-path`
|
|
- Authenticated + on `/login` → `/dashboard`
|
|
- Suspended tenant → `/suspended`
|
|
|
|
**Success Criteria**:
|
|
- ✅ Protected routes require login
|
|
- ✅ Token validation works (JWT signature check)
|
|
- ✅ Redirect preserves original URL
|
|
- ✅ Suspended tenants can't access app
|
|
|
|
---
|
|
|
|
### Phase 3: Settings Pages (Day 6 - Afternoon)
|
|
|
|
**Estimated Time**: 5-6 hours
|
|
|
|
#### 3.1 Organization Settings Page (SSO Config)
|
|
|
|
**File**: `app/(dashboard)/settings/organization/page.tsx`
|
|
|
|
**Features**:
|
|
- Tabs: General, SSO, Billing, Usage
|
|
- **SSO Tab**:
|
|
- Provider selection dropdown (Azure AD, Google, Okta, SAML)
|
|
- Dynamic form fields based on provider
|
|
- "Test Connection" button
|
|
- "Save Configuration" button
|
|
- Allowed domains (TagInput)
|
|
- Auto-provision users toggle
|
|
|
|
**Components to create**:
|
|
- `components/settings/SsoConfigForm.tsx` - Dynamic SSO form
|
|
- `hooks/tenants/useSsoConfig.ts` - Get/Update SSO config
|
|
- `hooks/tenants/useTestSsoConnection.ts` - Test connection mutation
|
|
|
|
**Dynamic Fields Logic**:
|
|
```typescript
|
|
// OIDC providers (Azure AD, Google, Okta)
|
|
- Authority URL (required)
|
|
- Client ID (required)
|
|
- Client Secret (required, password input)
|
|
- Metadata URL (optional)
|
|
|
|
// SAML provider
|
|
- Entity ID (required)
|
|
- Sign-On URL (required)
|
|
- X.509 Certificate (textarea, required)
|
|
- Metadata URL (optional)
|
|
```
|
|
|
|
**Success Criteria**:
|
|
- ✅ Form fields change based on provider selection
|
|
- ✅ "Test Connection" shows success/error message
|
|
- ✅ "Save Configuration" updates tenant SSO config
|
|
- ✅ Form validation with Zod
|
|
- ✅ Only Admin users can edit (permission check)
|
|
|
|
---
|
|
|
|
### Phase 4: MCP Token Management (Day 7)
|
|
|
|
**Estimated Time**: 6-8 hours
|
|
|
|
#### 4.1 MCP Tokens List Page
|
|
|
|
**File**: `app/(dashboard)/settings/mcp-tokens/page.tsx`
|
|
|
|
**Features**:
|
|
- Token list table (using `@tanstack/react-table`)
|
|
- Columns: Name, Permissions, Last Used, Expires, Status, Actions
|
|
- "Generate Token" button (opens dialog)
|
|
- "Revoke" button for each token
|
|
- Token details page (click row → navigate to `/settings/mcp-tokens/{id}`)
|
|
|
|
**Components to create**:
|
|
- `hooks/mcp/useMcpTokens.ts` - List tokens query
|
|
- `hooks/mcp/useRevokeMcpToken.ts` - Revoke mutation
|
|
|
|
**Success Criteria**:
|
|
- ✅ Token list loads and displays
|
|
- ✅ Permissions shown as tags
|
|
- ✅ Last Used shows "2 hours ago" format
|
|
- ✅ Revoke confirmation dialog works
|
|
- ✅ Revoked tokens marked as "Revoked" (red badge)
|
|
|
|
#### 4.2 Create Token Dialog
|
|
|
|
**File**: `components/mcp/CreateTokenDialog.tsx`
|
|
|
|
**Features**:
|
|
- Multi-step dialog (3 steps):
|
|
1. **Basic Info**: Name, Expiration date (optional)
|
|
2. **Permissions**: Resource + Operations matrix
|
|
3. **Review & Create**: Show summary
|
|
|
|
**Permission Matrix UI**:
|
|
```
|
|
Resources | read | create | update | delete | search
|
|
---------------------------------------------------------
|
|
Projects | ☑ | ☑ | ☐ | ☐ | ☑
|
|
Issues | ☑ | ☑ | ☑ | ☐ | ☑
|
|
Documents | ☑ | ☐ | ☐ | ☐ | ☑
|
|
Reports | ☑ | ☐ | ☐ | ☐ | ☐
|
|
Sprints | ☑ | ☐ | ☐ | ☐ | ☑
|
|
```
|
|
|
|
**Components to create**:
|
|
- `components/mcp/McpPermissionMatrix.tsx` - Checkbox grid
|
|
- `components/mcp/TokenDisplay.tsx` - Display token after creation
|
|
- `hooks/mcp/useCreateMcpToken.ts` - Create token mutation
|
|
|
|
**Token Display Modal**:
|
|
- Show generated token (once only)
|
|
- Warning: "Save this token now! You won't see it again."
|
|
- Copy button (copies to clipboard)
|
|
- Download button (downloads as `.txt` file)
|
|
- "I've saved the token" button (closes modal)
|
|
|
|
**Success Criteria**:
|
|
- ✅ 3-step wizard works smoothly
|
|
- ✅ Permission matrix shows checkboxes
|
|
- ✅ Token created successfully
|
|
- ✅ Token displayed only once
|
|
- ✅ Copy and download buttons work
|
|
|
|
#### 4.3 Token Details Page (Audit Logs)
|
|
|
|
**File**: `app/(dashboard)/settings/mcp-tokens/[id]/page.tsx`
|
|
|
|
**Features**:
|
|
- Token metadata (name, created date, expires date, status)
|
|
- Usage statistics (total calls, last used)
|
|
- Audit log table:
|
|
- Columns: Timestamp, HTTP Method, Endpoint, Status Code, Duration, IP Address
|
|
- Pagination
|
|
- Filters (date range, status code)
|
|
|
|
**Components to create**:
|
|
- `components/mcp/AuditLogTable.tsx` - Audit log table
|
|
- `hooks/mcp/useMcpAuditLogs.ts` - Audit logs query
|
|
|
|
**Success Criteria**:
|
|
- ✅ Token metadata displayed
|
|
- ✅ Audit log table loads with pagination
|
|
- ✅ Date filter works
|
|
- ✅ Status code filter works (200, 401, 403, 500)
|
|
|
|
---
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests (Vitest + React Testing Library)
|
|
|
|
**Priority Components to Test**:
|
|
|
|
1. **Auth Components**
|
|
- `SsoButton.tsx` - Renders provider logo, triggers redirect
|
|
- `TenantSlugInput.tsx` - Shows "Available" or "Taken"
|
|
- `PasswordStrengthIndicator.tsx` - Shows correct strength level
|
|
|
|
2. **Auth Store**
|
|
- `useAuthStore.ts` - Login, logout, token refresh logic
|
|
|
|
3. **API Client**
|
|
- `lib/api-client.ts` - Token injection, 401 handling
|
|
|
|
4. **Custom Hooks**
|
|
- `useLogin.ts` - Success/error handling
|
|
- `useCheckSlug.ts` - Debouncing, caching
|
|
|
|
**Example Test**:
|
|
|
|
```typescript
|
|
// __tests__/components/auth/SsoButton.test.tsx
|
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import { SsoButton } from '@/components/auth/SsoButton';
|
|
|
|
describe('SsoButton', () => {
|
|
it('renders Azure AD button with logo', () => {
|
|
render(<SsoButton provider="AzureAD" onClick={vi.fn()} />);
|
|
expect(screen.getByText(/Sign in with Microsoft/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it('calls onClick when clicked', () => {
|
|
const handleClick = vi.fn();
|
|
render(<SsoButton provider="Google" onClick={handleClick} />);
|
|
fireEvent.click(screen.getByRole('button'));
|
|
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
```
|
|
|
|
### Integration Tests (Playwright)
|
|
|
|
**Critical User Flows**:
|
|
|
|
1. **Local Login Flow**
|
|
- Navigate to `/login`
|
|
- Enter email and password
|
|
- Click "Sign In"
|
|
- Verify redirect to `/dashboard`
|
|
- Verify token in AuthStore
|
|
|
|
2. **SSO Login Flow (Mocked)**
|
|
- Click "Sign in with Azure AD"
|
|
- Mock SSO callback with token
|
|
- Verify redirect to dashboard
|
|
|
|
3. **Create MCP Token Flow**
|
|
- Navigate to `/settings/mcp-tokens`
|
|
- Click "Generate Token"
|
|
- Fill in name and permissions
|
|
- Verify token displayed
|
|
- Verify token can be copied
|
|
|
|
### API Mocking (MSW)
|
|
|
|
**Mock Handlers**:
|
|
|
|
```typescript
|
|
// mocks/handlers.ts
|
|
import { http, HttpResponse } from 'msw';
|
|
|
|
export const handlers = [
|
|
http.post('/api/auth/login', () => {
|
|
return HttpResponse.json({
|
|
user: { id: '1', email: 'test@example.com', fullName: 'Test User' },
|
|
tenant: { id: '1', slug: 'test', name: 'Test Corp' },
|
|
accessToken: 'mock-token',
|
|
});
|
|
}),
|
|
|
|
http.get('/api/tenants/check-slug', ({ request }) => {
|
|
const url = new URL(request.url);
|
|
const slug = url.searchParams.get('slug');
|
|
return HttpResponse.json({ available: slug !== 'taken' });
|
|
}),
|
|
|
|
http.post('/api/mcp-tokens', () => {
|
|
return HttpResponse.json({
|
|
tokenId: '1',
|
|
token: 'mcp_test_abc123xyz789',
|
|
name: 'Test Token',
|
|
});
|
|
}),
|
|
];
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Optimization
|
|
|
|
### 1. Code Splitting
|
|
|
|
**Lazy Load Heavy Components**:
|
|
|
|
```typescript
|
|
// app/(dashboard)/settings/mcp-tokens/page.tsx
|
|
import { lazy, Suspense } from 'react';
|
|
|
|
const CreateTokenDialog = lazy(() => import('@/components/mcp/CreateTokenDialog'));
|
|
const AuditLogTable = lazy(() => import('@/components/mcp/AuditLogTable'));
|
|
|
|
export default function McpTokensPage() {
|
|
return (
|
|
<Suspense fallback={<LoadingSpinner />}>
|
|
<CreateTokenDialog />
|
|
<AuditLogTable />
|
|
</Suspense>
|
|
);
|
|
}
|
|
```
|
|
|
|
### 2. TanStack Query Caching
|
|
|
|
**Cache Configuration**:
|
|
|
|
```typescript
|
|
// lib/query-client.ts
|
|
import { QueryClient } from '@tanstack/react-query';
|
|
|
|
export const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
gcTime: 1000 * 60 * 10, // 10 minutes (formerly cacheTime)
|
|
refetchOnWindowFocus: false,
|
|
retry: 1,
|
|
},
|
|
},
|
|
});
|
|
```
|
|
|
|
**Prefetch Critical Data**:
|
|
|
|
```typescript
|
|
// app/(dashboard)/layout.tsx
|
|
export default function DashboardLayout() {
|
|
const queryClient = useQueryClient();
|
|
|
|
useEffect(() => {
|
|
// Prefetch user projects
|
|
queryClient.prefetchQuery({
|
|
queryKey: ['projects'],
|
|
queryFn: () => projectService.getAll(),
|
|
});
|
|
}, []);
|
|
|
|
return <>{children}</>;
|
|
}
|
|
```
|
|
|
|
### 3. Debouncing
|
|
|
|
**Slug Validation**:
|
|
|
|
```typescript
|
|
// hooks/tenants/useCheckSlug.ts
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { useMemo } from 'react';
|
|
import { debounce } from 'lodash-es';
|
|
|
|
export function useCheckSlug(slug: string) {
|
|
const debouncedSlug = useMemo(
|
|
() => debounce((value: string) => value, 500),
|
|
[]
|
|
);
|
|
|
|
return useQuery({
|
|
queryKey: ['check-slug', slug],
|
|
queryFn: () => tenantService.checkSlugAvailability(slug),
|
|
enabled: slug.length >= 3,
|
|
staleTime: 5000,
|
|
});
|
|
}
|
|
```
|
|
|
|
### 4. Image Optimization
|
|
|
|
**Use Next.js Image Component**:
|
|
|
|
```tsx
|
|
import Image from 'next/image';
|
|
|
|
<Image
|
|
src="/logos/azure-ad.svg"
|
|
alt="Azure AD"
|
|
width={24}
|
|
height={24}
|
|
priority
|
|
/>
|
|
```
|
|
|
|
---
|
|
|
|
## Security Checklist
|
|
|
|
### Authentication Security
|
|
|
|
- ✅ Access tokens stored in memory (Zustand), not localStorage
|
|
- ✅ Refresh tokens in httpOnly cookies (managed by backend)
|
|
- ✅ Token expiration checked before API calls
|
|
- ✅ Automatic logout on refresh failure
|
|
- ✅ CSRF protection (state parameter for SSO)
|
|
- ✅ JWT signature validation in middleware
|
|
- ✅ Redirect to login on 401 errors
|
|
|
|
### SSO Security
|
|
|
|
- ✅ State parameter generated with crypto random (32 bytes)
|
|
- ✅ State parameter validated on callback
|
|
- ✅ State stored in sessionStorage (cleared after use)
|
|
- ✅ SSO errors logged and reported to user
|
|
- ✅ Email domain validation (if configured)
|
|
|
|
### MCP Token Security
|
|
|
|
- ✅ Token displayed only once (after creation)
|
|
- ✅ Token copied/downloaded securely
|
|
- ✅ Token revocation confirmation dialog
|
|
- ✅ Audit logs for all token operations
|
|
|
|
### General Security
|
|
|
|
- ✅ All API calls over HTTPS in production
|
|
- ✅ Sensitive data (passwords) not logged
|
|
- ✅ Error messages don't leak sensitive info
|
|
- ✅ Rate limiting on login attempts (backend)
|
|
- ✅ XSS protection (React auto-escapes by default)
|
|
|
|
---
|
|
|
|
## Deployment Checklist
|
|
|
|
### Pre-Deployment
|
|
|
|
- ✅ All unit tests pass (`npm run test`)
|
|
- ✅ All integration tests pass (`npm run test:e2e`)
|
|
- ✅ TypeScript builds without errors (`npm run build`)
|
|
- ✅ No console errors in browser
|
|
- ✅ Environment variables configured (`.env.production`)
|
|
- ✅ API URLs point to production backend
|
|
- ✅ Error tracking configured (Sentry)
|
|
|
|
### Performance Checks
|
|
|
|
- ✅ Lighthouse score > 90 (Performance, Accessibility, Best Practices, SEO)
|
|
- ✅ First Contentful Paint < 1.5s
|
|
- ✅ Time to Interactive < 3s
|
|
- ✅ Bundle size < 200KB (gzipped)
|
|
- ✅ Images optimized (WebP format)
|
|
|
|
### Security Checks
|
|
|
|
- ✅ JWT_SECRET in production environment variables
|
|
- ✅ No hardcoded secrets in code
|
|
- ✅ HTTPS enforced (Next.js redirects)
|
|
- ✅ CSP headers configured
|
|
- ✅ Security headers (X-Frame-Options, X-Content-Type-Options)
|
|
|
|
### Monitoring
|
|
|
|
- ✅ Error tracking (Sentry or similar)
|
|
- ✅ Performance monitoring (Vercel Analytics)
|
|
- ✅ API error logging
|
|
- ✅ User analytics (PostHog or similar)
|
|
|
|
---
|
|
|
|
## Estimated Effort
|
|
|
|
| Phase | Tasks | Time | Priority |
|
|
|-------|-------|------|----------|
|
|
| **Phase 1: Core Infrastructure** | API Client, Auth Store, Types, Middleware | 4 hours | P0 |
|
|
| **Phase 2: Authentication** | Login, Signup, SSO Callback, Middleware | 8 hours | P0 |
|
|
| **Phase 3: Settings** | Organization Settings, SSO Config | 6 hours | P1 |
|
|
| **Phase 4: MCP Tokens** | Token List, Create, Display, Audit Logs | 8 hours | P1 |
|
|
| **Testing** | Unit tests, Integration tests, E2E tests | 6 hours | P1 |
|
|
| **Total** | | **32 hours** (~4 days) | |
|
|
|
|
**Timeline**:
|
|
- **Day 5**: Phase 1 + Phase 2 (Login, Signup)
|
|
- **Day 6**: Phase 2 (SSO Callback) + Phase 3 (Settings)
|
|
- **Day 7**: Phase 4 (MCP Tokens)
|
|
- **Day 8**: Testing + Bug fixes
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Backend API Readiness Check**
|
|
- Verify backend APIs are ready: `/api/auth/login`, `/api/tenants/check-slug`, `/api/mcp-tokens`, etc.
|
|
- Test API endpoints with Postman or Insomnia
|
|
- Document any API issues or missing endpoints
|
|
|
|
2. **Environment Setup**
|
|
- Clone frontend repo
|
|
- Install dependencies (`npm install`)
|
|
- Configure `.env.local`
|
|
- Start dev server (`npm run dev`)
|
|
|
|
3. **Start with Phase 1**
|
|
- Create `lib/api-client.ts`
|
|
- Create `stores/useAuthStore.ts`
|
|
- Create TypeScript types
|
|
- Test token injection and refresh
|
|
|
|
4. **Continuous Testing**
|
|
- Write tests as you build features
|
|
- Run tests before committing code
|
|
- Fix failing tests immediately
|
|
|
|
5. **Code Review**
|
|
- Self-review code before committing
|
|
- Use ESLint and Prettier
|
|
- Follow TypeScript strict mode
|
|
|
|
---
|
|
|
|
## Risk Mitigation
|
|
|
|
### Technical Risks
|
|
|
|
| Risk | Probability | Impact | Mitigation |
|
|
|------|-------------|--------|------------|
|
|
| Token refresh fails during API calls | Medium | High | Implement queue for pending requests during refresh |
|
|
| SSO callback errors (state mismatch) | Low | High | Add detailed error logging and user-friendly error page |
|
|
| Permission matrix UI too complex | Low | Medium | Use shadcn Checkbox component, add "Select All" shortcuts |
|
|
| TanStack Query cache invalidation issues | Medium | Medium | Document cache invalidation strategy, use query keys consistently |
|
|
| Middleware performance (JWT validation) | Low | Low | Cache JWT validation results, use efficient `jose` library |
|
|
|
|
### Schedule Risks
|
|
|
|
| Risk | Probability | Impact | Mitigation |
|
|
|------|-------------|--------|------------|
|
|
| Backend API delays | High | High | Mock API responses with MSW, develop UI first |
|
|
| Complex SSO flow takes longer | Medium | Medium | Simplify SSO flow, skip SAML in MVP if needed |
|
|
| Testing takes longer than expected | Medium | Medium | Prioritize critical path tests, skip edge cases for MVP |
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
This implementation plan provides a clear roadmap for building ColaFlow's enterprise-level frontend features. The plan is structured to minimize risk, maximize code quality, and deliver a production-ready solution within 4 days.
|
|
|
|
**Key Success Factors**:
|
|
- ✅ Backend API readiness
|
|
- ✅ Clear component boundaries
|
|
- ✅ Comprehensive testing strategy
|
|
- ✅ Performance optimization from day 1
|
|
- ✅ Security-first approach
|
|
|
|
**Next Document**: `api-integration-guide.md` (detailed API endpoints and request/response examples)
|