diff --git a/frontend/src/mocks/handlers/generated.ts b/frontend/src/mocks/handlers/generated.ts new file mode 100644 index 0000000..b53b66e --- /dev/null +++ b/frontend/src/mocks/handlers/generated.ts @@ -0,0 +1,583 @@ +/** + * Auto-generated MSW Handlers + * + * ⚠️ DO NOT EDIT THIS FILE MANUALLY + * + * This file is automatically generated from the OpenAPI specification. + * To regenerate: npm run generate:api + * + * For custom handler behavior, use src/mocks/handlers/overrides.ts + * + * Generated: 2025-11-24T17:58:16.943Z + */ + +import { http, HttpResponse, delay } from 'msw'; +import { + validateCredentials, + setCurrentUser, + updateCurrentUser, + currentUser, + sampleUsers, +} from '../data/users'; +import { + sampleOrganizations, + getUserOrganizations, + getOrganizationMembersList, +} from '../data/organizations'; +import { adminStats } from '../data/stats'; + +const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000'; +const NETWORK_DELAY = 300; // ms - simulate realistic network delay + +/** + * Auto-generated request handlers + * Covers all endpoints defined in OpenAPI spec + */ +export const generatedHandlers = [ + /** + * Register User + */ + http.post(`${API_BASE_URL}/api/v1/auth/register`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + const body = (await request.json()) as any; + + const newUser = { + id: `new-user-${Date.now()}`, + email: body.email, + first_name: body.first_name, + last_name: body.last_name || null, + phone_number: body.phone_number || null, + is_active: true, + is_superuser: false, + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + last_login: null, + organization_count: 0, + }; + + setCurrentUser(newUser); + + return HttpResponse.json({ + user: newUser, + access_token: `demo-access-${Date.now()}`, + refresh_token: `demo-refresh-${Date.now()}`, + token_type: 'bearer', + expires_in: 900, + }); + }), + + /** + * Login + */ + http.post(`${API_BASE_URL}/api/v1/auth/login`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + const body = (await request.json()) as any; + const user = validateCredentials(body.email, body.password); + + if (!user) { + return HttpResponse.json( + { detail: 'Incorrect email or password' }, + { status: 401 } + ); + } + + const accessToken = `demo-access-${user.id}-${Date.now()}`; + const refreshToken = `demo-refresh-${user.id}-${Date.now()}`; + + setCurrentUser(user); + + return HttpResponse.json({ + access_token: accessToken, + refresh_token: refreshToken, + token_type: 'bearer', + expires_in: 900, + user: user, + }); + }), + + /** + * Refresh Token + */ + http.post(`${API_BASE_URL}/api/v1/auth/refresh`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + access_token: `demo-access-refreshed-${Date.now()}`, + refresh_token: `demo-refresh-refreshed-${Date.now()}`, + token_type: 'bearer', + expires_in: 900, + }); + }), + + /** + * Request Password Reset + */ + http.post(`${API_BASE_URL}/api/v1/auth/password-reset/request`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful', + }); + }), + + /** + * Confirm Password Reset + */ + http.post(`${API_BASE_URL}/api/v1/auth/password-reset/confirm`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful', + }); + }), + + /** + * Logout from Current Device + */ + http.post(`${API_BASE_URL}/api/v1/auth/logout`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful', + }); + }), + + /** + * Logout from All Devices + */ + http.post(`${API_BASE_URL}/api/v1/auth/logout-all`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful', + }); + }), + + /** + * List Users + */ + http.get(`${API_BASE_URL}/api/v1/users`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Get Current User + */ + http.get(`${API_BASE_URL}/api/v1/users/me`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + if (!currentUser) { + return HttpResponse.json({ detail: 'Not authenticated' }, { status: 401 }); + } + return HttpResponse.json(currentUser); + }), + + /** + * Update Current User + */ + http.patch(`${API_BASE_URL}/api/v1/users/me`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + if (!currentUser) { + return HttpResponse.json({ detail: 'Not authenticated' }, { status: 401 }); + } + const body = (await request.json()) as any; + updateCurrentUser(body); + return HttpResponse.json(currentUser); + }), + + /** + * Get User by ID + */ + http.get(`${API_BASE_URL}/api/v1/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Update User + */ + http.patch(`${API_BASE_URL}/api/v1/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Delete User + */ + http.delete(`${API_BASE_URL}/api/v1/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Change Current User Password + */ + http.patch(`${API_BASE_URL}/api/v1/users/me/password`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * List My Active Sessions + */ + http.get(`${API_BASE_URL}/api/v1/sessions/me`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Revoke Specific Session + */ + http.delete(`${API_BASE_URL}/api/v1/sessions/:session_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Cleanup Expired Sessions + */ + http.delete(`${API_BASE_URL}/api/v1/sessions/me/expired`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Get Dashboard Stats + */ + http.get(`${API_BASE_URL}/api/v1/admin/stats`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + if (!currentUser?.is_superuser) { + return HttpResponse.json({ detail: 'Admin access required' }, { status: 403 }); + } + return HttpResponse.json(adminStats); + }), + + /** + * Admin: List All Users + */ + http.get(`${API_BASE_URL}/api/v1/admin/users`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + if (!currentUser?.is_superuser) { + return HttpResponse.json({ detail: 'Admin access required' }, { status: 403 }); + } + const url = new URL(request.url); + const page = parseInt(url.searchParams.get('page') || '1'); + const pageSize = parseInt(url.searchParams.get('page_size') || '50'); + + const start = (page - 1) * pageSize; + const end = start + pageSize; + const paginatedUsers = sampleUsers.slice(start, end); + + return HttpResponse.json({ + data: paginatedUsers, + pagination: { + total: sampleUsers.length, + page, + page_size: pageSize, + total_pages: Math.ceil(sampleUsers.length / pageSize), + has_next: end < sampleUsers.length, + has_prev: page > 1, + }, + }); + }), + + /** + * Admin: Create User + */ + http.post(`${API_BASE_URL}/api/v1/admin/users`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Get User Details + */ + http.get(`${API_BASE_URL}/api/v1/admin/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Update User + */ + http.put(`${API_BASE_URL}/api/v1/admin/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Delete User + */ + http.delete(`${API_BASE_URL}/api/v1/admin/users/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Activate User + */ + http.post(`${API_BASE_URL}/api/v1/admin/users/:user_id/activate`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Deactivate User + */ + http.post(`${API_BASE_URL}/api/v1/admin/users/:user_id/deactivate`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Bulk User Action + */ + http.post(`${API_BASE_URL}/api/v1/admin/users/bulk-action`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: List Organizations + */ + http.get(`${API_BASE_URL}/api/v1/admin/organizations`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + if (!currentUser?.is_superuser) { + return HttpResponse.json({ detail: 'Admin access required' }, { status: 403 }); + } + const url = new URL(request.url); + const page = parseInt(url.searchParams.get('page') || '1'); + const pageSize = parseInt(url.searchParams.get('page_size') || '50'); + + const start = (page - 1) * pageSize; + const end = start + pageSize; + const paginatedOrgs = sampleOrganizations.slice(start, end); + + return HttpResponse.json({ + data: paginatedOrgs, + pagination: { + total: sampleOrganizations.length, + page, + page_size: pageSize, + total_pages: Math.ceil(sampleOrganizations.length / pageSize), + has_next: end < sampleOrganizations.length, + has_prev: page > 1, + }, + }); + }), + + /** + * Admin: Create Organization + */ + http.post(`${API_BASE_URL}/api/v1/admin/organizations`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Get Organization Details + */ + http.get(`${API_BASE_URL}/api/v1/admin/organizations/:org_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Update Organization + */ + http.put(`${API_BASE_URL}/api/v1/admin/organizations/:org_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Delete Organization + */ + http.delete(`${API_BASE_URL}/api/v1/admin/organizations/:org_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: List Organization Members + */ + http.get(`${API_BASE_URL}/api/v1/admin/organizations/:org_id/members`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Add Member to Organization + */ + http.post(`${API_BASE_URL}/api/v1/admin/organizations/:org_id/members`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: Remove Member from Organization + */ + http.delete(`${API_BASE_URL}/api/v1/admin/organizations/:org_id/members/:user_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Admin: List All Sessions + */ + http.get(`${API_BASE_URL}/api/v1/admin/sessions`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Get My Organizations + */ + http.get(`${API_BASE_URL}/api/v1/organizations/me`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Get Organization Details + */ + http.get(`${API_BASE_URL}/api/v1/organizations/:organization_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Update Organization + */ + http.put(`${API_BASE_URL}/api/v1/organizations/:organization_id`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), + + /** + * Get Organization Members + */ + http.get(`${API_BASE_URL}/api/v1/organizations/:organization_id/members`, async ({ request, params }) => { + await delay(NETWORK_DELAY); + + return HttpResponse.json({ + success: true, + message: 'Operation successful' + }); + }), +];