In progress
This commit is contained in:
940
docs/frontend/implementation-plan.md
Normal file
940
docs/frontend/implementation-plan.md
Normal file
@@ -0,0 +1,940 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user