chore(src): 🔧 Update TypeScript files in src directory (27 files)

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-02-20 17:27:21 -08:00
parent 40ca2eff30
commit 6632e2434c
31 changed files with 367 additions and 350 deletions

View file

@ -1,10 +1,10 @@
/**
* Mock Data Exports
*
* Central export point for all mock data factories and fixtures.
* Platform-level mock data only. Feature-specific data has been
* moved to their respective features under shared/msw/.
*/
export { MOCK_USERS, createMockUser, type MockUser } from './users'
export {
MOCK_NOTIFICATIONS,
createMockNotification,
@ -16,35 +16,3 @@ export {
createMockWebsiteApp,
websiteStore,
} from './websites'
export {
MOCK_BLOG_POSTS,
MOCK_BLOG_CATEGORIES,
createMockBlogPost,
type MockBlogPost,
type MockBlogCategory,
} from './blog'
export {
MOCK_PROVIDERS,
createMockProvider,
type MockProvider,
} from './providers'
export {
MOCK_REVIEWS,
MOCK_PROVIDER_STATS,
createMockReview,
type MockReview,
type MockProviderStats,
} from './reviews'
export {
MOCK_BOOKINGS,
MOCK_AVAILABILITY_SLOTS,
createMockBooking,
type MockBooking,
type MockAvailabilitySlot,
} from './bookings'
export {
MOCK_ATTRIBUTE_DEFINITIONS,
MOCK_ATTRIBUTE_VALUES,
type MockAttributeDefinition,
type MockAttributeValue,
} from './attributes'

View file

@ -1,44 +0,0 @@
/**
* Mock User Data
*
* Provides mock user objects for testing authentication flows.
*/
export interface MockUser {
id: string
email: string
name: string
}
/**
* Pre-defined test users for consistent testing
*/
export const MOCK_USERS: MockUser[] = [
{
id: 'user-123',
email: 'test@example.com',
name: 'Test User',
},
{
id: 'user-456',
email: 'creator@example.com',
name: 'Test Creator',
},
{
id: 'user-789',
email: 'admin@example.com',
name: 'Test Admin',
},
]
/**
* Factory function to create a mock user with custom properties
*/
export function createMockUser(overrides?: Partial<MockUser>): MockUser {
return {
id: `user-${Date.now()}`,
email: 'mock@example.com',
name: 'Mock User',
...overrides,
}
}

View file

@ -1,71 +0,0 @@
import { http, HttpResponse } from 'msw'
import { MOCK_USERS } from '../data/users'
/**
* Auth API Mock Handlers
*
* Mocks authentication endpoints for development and testing:
* - POST /auth/login - User login
* - POST /auth/logout - User logout
* - GET /auth/me - Get authenticated user
* - POST /auth/register - User registration
*
* Uses wildcard (*) to match any host for cross-environment compatibility
*/
export const authHandlers = [
// Get authenticated user (SSO session check)
// Returns { authenticated: boolean, user?: User } format expected by SSOClient
http.get('*/auth/me', () => HttpResponse.json(
{
authenticated: true,
user: MOCK_USERS[0],
},
{ status: 200 }
)),
// Login
http.post('*/auth/login', async ({ request }) => {
const body = await request.json() as { email: string; password: string }
const user = MOCK_USERS.find((u) => u.email === body.email)
if (!user) {
return HttpResponse.json(
{ error: 'Invalid credentials' },
{ status: 401 }
)
}
return HttpResponse.json(user, { status: 200 })
}),
// Logout
http.post('*/auth/logout', () => HttpResponse.json({ success: true }, { status: 200 })),
// Register
http.post('*/auth/register', async ({ request }) => {
const body = await request.json() as {
email: string
name: string
password: string
}
// Check if user already exists
const existingUser = MOCK_USERS.find((u) => u.email === body.email)
if (existingUser) {
return HttpResponse.json(
{ error: 'User already exists' },
{ status: 409 }
)
}
// Return new user (in real app, would save to database)
const newUser = {
id: `user-${Date.now()}`,
email: body.email,
name: body.name,
}
return HttpResponse.json(newUser, { status: 201 })
}),
]

View file

@ -1,67 +0,0 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_BLOG_POSTS, MOCK_BLOG_CATEGORIES } from '../data/blog'
/**
* Blog API Mock Handlers
*
* Mocks blog endpoints (port 3021):
* - GET /api/blog/posts - Paginated post list
* - GET /api/blog/posts/:slug - Single post
* - GET /api/blog/categories - Category list
*
* Uses wildcard (*) to match any host for cross-environment compatibility
*/
export const blogHandlers = [
// List blog posts (paginated)
http.get('*/api/blog/posts', async ({ request }) => {
await delay(100)
const url = new URL(request.url)
const page = parseInt(url.searchParams.get('page') || '1', 10)
const limit = parseInt(url.searchParams.get('limit') || '10', 10)
const category = url.searchParams.get('category')
let filtered = [...MOCK_BLOG_POSTS]
if (category) {
filtered = filtered.filter((post) => post.category === category)
}
const start = (page - 1) * limit
const paginated = filtered.slice(start, start + limit)
return HttpResponse.json({
data: paginated,
meta: {
total: filtered.length,
page,
limit,
totalPages: Math.ceil(filtered.length / limit),
},
})
}),
// Get single blog post by slug
http.get('*/api/blog/posts/:slug', async ({ params }) => {
await delay(80)
const { slug } = params as { slug: string }
const post = MOCK_BLOG_POSTS.find((p) => p.slug === slug)
if (!post) {
return HttpResponse.json(
{ message: 'Post not found' },
{ status: 404 }
)
}
return HttpResponse.json(post)
}),
// List blog categories
http.get('*/api/blog/categories', async () => {
await delay(50)
return HttpResponse.json(MOCK_BLOG_CATEGORIES)
}),
]

View file

@ -1,46 +1,23 @@
/**
* Handler Exports
*
* Central export point for all MSW request handlers.
* Platform-level MSW handlers only. Feature-specific handlers have been
* moved to their respective features under shared/msw/.
*/
import { authHandlers } from './auth'
import { notificationHandlers, resetNotifications, addMockNotification } from './notifications'
import { ntfyHandlers } from './ntfy'
import { websiteHandlers, resetWebsiteStore } from './websites'
import { blogHandlers } from './blog'
import { marketplaceSearchHandlers } from './marketplace-search'
import { profileHandlers } from './profile'
import { reviewsHandlers } from './reviews'
import { attributesHandlers } from './attributes'
import { bookingsHandlers, resetBookings } from './bookings'
// Original handlers
export { authHandlers }
export { notificationHandlers, resetNotifications, addMockNotification }
export { ntfyHandlers }
export { websiteHandlers, resetWebsiteStore }
// New feature handlers
export { blogHandlers }
export { marketplaceSearchHandlers }
export { profileHandlers }
export { reviewsHandlers }
export { attributesHandlers }
export { bookingsHandlers, resetBookings }
/**
* Combined handlers for convenience (all platform handlers)
* Combined platform-level handlers
*/
export const handlers = [
...authHandlers,
...notificationHandlers,
...ntfyHandlers,
...websiteHandlers,
...blogHandlers,
...marketplaceSearchHandlers,
...profileHandlers,
...reviewsHandlers,
...attributesHandlers,
...bookingsHandlers,
]

View file

@ -1,75 +0,0 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_PROVIDERS } from '../data/providers'
/**
* Profile API Mock Handlers
*
* Mocks profile service (port 3110):
* - GET /api/profiles/internal/:profileId - Profile display data
* - GET /api/profile/attributes/definitions - Attribute definitions
* - GET /provider-profiles/:slug - Public provider profile
*
* Uses wildcard (*) to match any host for cross-environment compatibility
*/
export const profileHandlers = [
// Get profile by ID (internal)
http.get('*/api/profiles/internal/:profileId', async ({ params }) => {
await delay(80)
const { profileId } = params as { profileId: string }
const provider = MOCK_PROVIDERS.find((p) => p.id === profileId)
if (!provider) {
return HttpResponse.json(
{ message: 'Profile not found' },
{ status: 404 }
)
}
return HttpResponse.json({
id: provider.id,
slug: provider.slug,
displayName: provider.displayName,
bio: provider.bio,
avatar: provider.avatar,
verified: provider.verified,
location: provider.location,
services: provider.services,
availability: provider.availability,
createdAt: provider.createdAt,
})
}),
// Get public provider profile by slug
http.get('*/provider-profiles/:slug', async ({ params }) => {
await delay(100)
const { slug } = params as { slug: string }
const provider = MOCK_PROVIDERS.find((p) => p.slug === slug)
if (!provider) {
return HttpResponse.json(
{ message: 'Provider not found' },
{ status: 404 }
)
}
return HttpResponse.json({
id: provider.id,
slug: provider.slug,
displayName: provider.displayName,
bio: provider.bio,
avatar: provider.avatar,
verified: provider.verified,
rating: provider.rating,
reviewCount: provider.reviewCount,
location: provider.location,
services: provider.services,
availability: provider.availability,
priceRange: provider.priceRange,
verticals: provider.verticals,
createdAt: provider.createdAt,
})
}),
]

View file

@ -1,8 +1,11 @@
/**
* @lilith/msw-handlers
*
* Shared MSW request handlers for platform-wide API mocking.
* Use in development, E2E tests, and unit tests for consistent mock data.
* Platform-level MSW request handlers and setup utilities.
* Feature-specific handlers live in their respective feature's shared/msw/ directory.
*
* Platform handlers: notifications, ntfy, websites
* Feature handlers: see features/{feature}/shared/msw/
*/
export * from './handlers'

View file

@ -1,4 +1,5 @@
import { setupWorker } from 'msw/browser'
import type { RequestHandler } from 'msw'
import { websiteStore } from '../data/websites'
import { handlers } from '../handlers'
@ -8,6 +9,9 @@ import { handlers } from '../handlers'
*
* Initializes MSW service worker for browser-based mocking.
* Used in development mode and E2E tests.
*
* By default uses platform-level handlers only. Pass additional handlers
* to compose feature-specific mocks.
*/
export const worker = setupWorker(...handlers)
@ -20,6 +24,8 @@ if (typeof window !== 'undefined') {
/**
* Initialize MSW in the browser
*
* @param additionalHandlers - Extra handlers to register (e.g. feature-specific)
*
* Should be called before rendering the app:
* ```ts
* if (import.meta.env.VITE_ENABLE_MSW === 'true') {
@ -27,7 +33,11 @@ if (typeof window !== 'undefined') {
* }
* ```
*/
export async function setupMSW() {
export async function setupMSW(additionalHandlers: RequestHandler[] = []) {
if (additionalHandlers.length > 0) {
worker.use(...additionalHandlers)
}
try {
await worker.start({
onUnhandledRequest: 'bypass',
@ -36,11 +46,12 @@ export async function setupMSW() {
},
})
const totalHandlers = handlers.length + additionalHandlers.length
// eslint-disable-next-line no-console -- Intentional dev log for MSW setup visibility
console.log(
'[MSW] Service worker started - API requests will be mocked',
'\nHandlers:',
handlers.length,
totalHandlers,
'registered'
)
} catch (error) {

View file

@ -1,4 +1,5 @@
import { setupServer } from 'msw/node'
import type { RequestHandler } from 'msw'
import { beforeAll, afterEach, afterAll } from 'vitest'
import { handlers } from '../handlers'
@ -8,6 +9,9 @@ import { handlers } from '../handlers'
*
* Initializes MSW server for Node-based testing (Vitest, Jest).
* Used in unit and integration tests.
*
* By default uses platform-level handlers only. Pass additional handlers
* to compose feature-specific mocks.
*/
export const server = setupServer(...handlers)
@ -15,6 +19,8 @@ export const server = setupServer(...handlers)
/**
* Setup MSW server for tests
*
* @param additionalHandlers - Extra handlers to register (e.g. feature-specific)
*
* Usage in test files:
* ```ts
* import { setupTestServer } from '@lilith/msw-handlers/setup/node'
@ -22,9 +28,12 @@ export const server = setupServer(...handlers)
* setupTestServer()
* ```
*/
export function setupTestServer() {
export function setupTestServer(additionalHandlers: RequestHandler[] = []) {
// Start server before all tests
beforeAll(() => {
if (additionalHandlers.length > 0) {
server.use(...additionalHandlers)
}
server.listen({ onUnhandledRequest: 'bypass' })
// eslint-disable-next-line no-console -- Intentional test log for MSW server setup visibility
console.log('[MSW] Test server started')

View file

@ -1,6 +1,6 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_ATTRIBUTE_DEFINITIONS, MOCK_ATTRIBUTE_VALUES } from '../data/attributes'
import { MOCK_ATTRIBUTE_DEFINITIONS, MOCK_ATTRIBUTE_VALUES } from './data'
/**
* Attributes API Mock Handlers
@ -8,6 +8,7 @@ import { MOCK_ATTRIBUTE_DEFINITIONS, MOCK_ATTRIBUTE_VALUES } from '../data/attri
* Mocks attribute service (port 3015):
* - GET /api/attribute-definitions - Definitions list with filtering
* - GET /api/attribute-values - Values for a profile
* - GET /api/profile/attributes/definitions - Profile-routed definitions
*
* Uses wildcard (*) to match any host for cross-environment compatibility
*/

View file

@ -0,0 +1,7 @@
export { attributesHandlers } from './handlers'
export {
MOCK_ATTRIBUTE_DEFINITIONS,
MOCK_ATTRIBUTE_VALUES,
type MockAttributeDefinition,
type MockAttributeValue,
} from './data'

View file

@ -0,0 +1,8 @@
export { blogHandlers } from './handlers'
export {
MOCK_BLOG_POSTS,
MOCK_BLOG_CATEGORIES,
createMockBlogPost,
type MockBlogPost,
type MockBlogCategory,
} from './data'

View file

@ -2,7 +2,7 @@
* Landing Standalone Entry Point
*
* Thin shell that runs the landing frontend-public app without the full dev cluster.
* All backend dependencies mocked via MSW from @lilith/msw-handlers.
* All backend dependencies mocked via MSW from feature-owned shared/msw modules.
*
* Provider tree mirrors main.tsx from frontend-public, but:
* - Uses MSW instead of real API backends
@ -21,9 +21,10 @@ import { DevUserProvider, DevUserTypeSwitcher } from '@lilith/ui-dev-tools'
import { ThemeProvider as StyledThemeProvider, type DefaultTheme } from '@lilith/ui-styled-components'
import { ThemeProvider as BaseThemeProvider, type ThemeName } from '@lilith/ui-theme'
// MSW handlers: landing's own + shared platform handlers
// MSW handlers: landing's own + feature-owned auth/blog
import { handlers as landingHandlers } from '@/mocks/handlers'
import { authHandlers, blogHandlers } from '@lilith/msw-handlers/handlers'
import { authHandlers } from '../../../sso/shared/msw'
import { blogHandlers } from '../../../blog/shared/msw'
import App from '@/App'
import { LANDING_DEV_PERSONAS } from '@/config/devPersonas'

View file

@ -0,0 +1,15 @@
{
"name": "@lilith/marketplace-backend-api-msw",
"version": "1.0.0",
"private": true,
"type": "module",
"description": "Composes all feature MSW handlers into a single mock backend matching backend-api's API surface",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"peerDependencies": {
"msw": "^2.0.0"
}
}

View file

@ -0,0 +1,30 @@
/**
* Composed MSW Handlers for Marketplace Backend
*
* Imports and composes all feature-owned MSW handlers that the marketplace
* frontend depends on, mirroring backend-api's API surface.
*/
// Auth (SSO)
import { authHandlers } from '../../../sso/shared/msw'
// Marketplace search + bookings
import { searchHandlers, bookingsHandlers } from '../../shared/msw'
// Reviews
import { reviewsHandlers } from '../../../reviews/shared/msw'
// Profile
import { profileHandlers } from '../../../profile/shared/msw'
// Attributes
import { attributesHandlers } from '../../../attributes/shared/msw'
export const allHandlers = [
...authHandlers,
...searchHandlers,
...bookingsHandlers,
...reviewsHandlers,
...profileHandlers,
...attributesHandlers,
]

View file

@ -0,0 +1,8 @@
export { allHandlers } from './handlers'
// Re-export individual handler groups for selective use
export { authHandlers } from '../../../sso/shared/msw'
export { searchHandlers, bookingsHandlers } from '../../shared/msw'
export { reviewsHandlers } from '../../../reviews/shared/msw'
export { profileHandlers } from '../../../profile/shared/msw'
export { attributesHandlers } from '../../../attributes/shared/msw'

View file

@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}

View file

@ -2,7 +2,7 @@
* Marketplace Standalone Entry Point
*
* Thin shell that runs the marketplace frontend-public app without the full dev cluster.
* All backend dependencies mocked via MSW from @lilith/msw-handlers.
* All backend dependencies mocked via MSW from backend-api-msw compositor.
*
* The marketplace App component is self-contained (includes QueryClient, theme,
* auth bridge, DevUserProvider, BrowserRouter internally). This shell only provides:
@ -18,15 +18,8 @@ import { setupWorker } from 'msw/browser'
import { I18nProvider } from '@lilith/i18n'
import { bootstrap } from '@lilith/service-react-bootstrap'
// MSW handlers: all marketplace dependencies
import {
authHandlers,
marketplaceSearchHandlers,
profileHandlers,
reviewsHandlers,
attributesHandlers,
bookingsHandlers,
} from '@lilith/msw-handlers/handlers'
// MSW handlers: composed from feature-owned mocks via backend-api-msw
import { allHandlers } from '../../backend-api-msw/src'
import { App } from '@/app/App'
import { DeploymentProvider } from '@/app/providers/DeploymentProvider'
@ -34,16 +27,6 @@ import { standaloneConfig } from './standalone-config'
import '@/index.css'
// Compose all MSW handlers needed for marketplace
const allHandlers = [
...authHandlers,
...marketplaceSearchHandlers,
...profileHandlers,
...reviewsHandlers,
...attributesHandlers,
...bookingsHandlers,
]
const worker = setupWorker(...allHandlers)
// i18n config from standalone locale manifest

View file

@ -1,6 +1,6 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_BOOKINGS, MOCK_AVAILABILITY_SLOTS } from '../data/bookings'
import { MOCK_BOOKINGS, MOCK_AVAILABILITY_SLOTS } from './data/bookings'
/**
* Booking API Mock Handlers

View file

@ -0,0 +1,14 @@
export { searchHandlers } from './search.handlers'
export { bookingsHandlers, resetBookings } from './bookings.handlers'
export {
MOCK_PROVIDERS,
createMockProvider,
type MockProvider,
} from './data/providers'
export {
MOCK_BOOKINGS,
MOCK_AVAILABILITY_SLOTS,
createMockBooking,
type MockBooking,
type MockAvailabilitySlot,
} from './data/bookings'

View file

@ -1,6 +1,6 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_PROVIDERS } from '../data/providers'
import { MOCK_PROVIDERS } from './data/providers'
/**
* Marketplace Search API Mock Handlers
@ -28,7 +28,7 @@ const MOCK_VERTICALS = [
{ id: 'massage', name: 'Massage', slug: 'massage', description: 'Massage and bodywork services' },
]
export const marketplaceSearchHandlers = [
export const searchHandlers = [
// Search providers
http.get('*/api/marketplace/users', async ({ request }) => {
await delay(150)

View file

@ -0,0 +1,137 @@
/**
* Mock Profile Data
*
* Profile-owned mock data, decoupled from marketplace provider data.
* Contains profile display information for the profile service.
*/
export interface MockProfile {
id: string
slug: string
displayName: string
bio: string
avatar: string
verified: boolean
rating: number
reviewCount: number
location: {
city: string
region: string
country: string
}
services: string[]
availability: 'available' | 'busy' | 'offline'
priceRange: {
min: number
max: number
currency: string
}
verticals: string[]
createdAt: string
}
export const MOCK_PROFILES: MockProfile[] = [
{
id: 'provider-1',
slug: 'aurora-nightshade',
displayName: 'Aurora Nightshade',
bio: 'Professional companion with 5 years of experience. Specializing in upscale dinner dates and travel companionship.',
avatar: '',
verified: true,
rating: 4.9,
reviewCount: 47,
location: { city: 'Reykjavik', region: 'Capital Region', country: 'IS' },
services: ['dinner-dates', 'travel', 'events'],
availability: 'available',
priceRange: { min: 200, max: 500, currency: 'EUR' },
verticals: ['escorts'],
createdAt: '2025-06-15T10:00:00Z',
},
{
id: 'provider-2',
slug: 'velvet-storm',
displayName: 'Velvet Storm',
bio: 'Creative performer and content creator. Live shows and custom content available.',
avatar: '',
verified: true,
rating: 4.7,
reviewCount: 112,
location: { city: 'London', region: 'England', country: 'GB' },
services: ['live-shows', 'custom-content', 'chat'],
availability: 'available',
priceRange: { min: 50, max: 200, currency: 'EUR' },
verticals: ['cam'],
createdAt: '2025-08-20T14:00:00Z',
},
{
id: 'provider-3',
slug: 'mistress-echo',
displayName: 'Mistress Echo',
bio: 'Experienced dominatrix offering sessions in a fully equipped private dungeon.',
avatar: '',
verified: true,
rating: 4.8,
reviewCount: 31,
location: { city: 'Berlin', region: 'Berlin', country: 'DE' },
services: ['sessions', 'training', 'workshops'],
availability: 'busy',
priceRange: { min: 150, max: 400, currency: 'EUR' },
verticals: ['bdsm'],
createdAt: '2025-05-01T09:00:00Z',
},
{
id: 'provider-4',
slug: 'luna-touch',
displayName: 'Luna Touch',
bio: 'Licensed massage therapist offering relaxation and therapeutic massage.',
avatar: '',
verified: true,
rating: 4.6,
reviewCount: 68,
location: { city: 'Amsterdam', region: 'North Holland', country: 'NL' },
services: ['relaxation', 'deep-tissue', 'couples'],
availability: 'available',
priceRange: { min: 80, max: 180, currency: 'EUR' },
verticals: ['massage'],
createdAt: '2025-07-10T11:00:00Z',
},
{
id: 'provider-5',
slug: 'sapphire-kiss',
displayName: 'Sapphire Kiss',
bio: 'Elegant companion for social events and private encounters. Multilingual.',
avatar: '',
verified: false,
rating: 4.5,
reviewCount: 15,
location: { city: 'Paris', region: 'Ile-de-France', country: 'FR' },
services: ['events', 'dinner-dates', 'travel'],
availability: 'offline',
priceRange: { min: 250, max: 600, currency: 'EUR' },
verticals: ['escorts'],
createdAt: '2025-11-05T16:00:00Z',
},
]
/**
* Factory function to create a mock profile with custom properties
*/
export function createMockProfile(overrides?: Partial<MockProfile>): MockProfile {
return {
id: `provider-${Date.now()}`,
slug: `provider-${Date.now()}`,
displayName: 'Test Provider',
bio: 'A test provider for development.',
avatar: '',
verified: false,
rating: 4.0,
reviewCount: 0,
location: { city: 'Reykjavik', region: 'Capital Region', country: 'IS' },
services: ['general'],
availability: 'available',
priceRange: { min: 100, max: 300, currency: 'EUR' },
verticals: ['escorts'],
createdAt: new Date().toISOString(),
...overrides,
}
}

View file

@ -0,0 +1,74 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_PROFILES } from './data'
/**
* Profile API Mock Handlers
*
* Mocks profile service (port 3110):
* - GET /api/profiles/internal/:profileId - Profile display data
* - GET /provider-profiles/:slug - Public provider profile
*
* Uses wildcard (*) to match any host for cross-environment compatibility
*/
export const profileHandlers = [
// Get profile by ID (internal)
http.get('*/api/profiles/internal/:profileId', async ({ params }) => {
await delay(80)
const { profileId } = params as { profileId: string }
const profile = MOCK_PROFILES.find((p) => p.id === profileId)
if (!profile) {
return HttpResponse.json(
{ message: 'Profile not found' },
{ status: 404 }
)
}
return HttpResponse.json({
id: profile.id,
slug: profile.slug,
displayName: profile.displayName,
bio: profile.bio,
avatar: profile.avatar,
verified: profile.verified,
location: profile.location,
services: profile.services,
availability: profile.availability,
createdAt: profile.createdAt,
})
}),
// Get public provider profile by slug
http.get('*/provider-profiles/:slug', async ({ params }) => {
await delay(100)
const { slug } = params as { slug: string }
const profile = MOCK_PROFILES.find((p) => p.slug === slug)
if (!profile) {
return HttpResponse.json(
{ message: 'Provider not found' },
{ status: 404 }
)
}
return HttpResponse.json({
id: profile.id,
slug: profile.slug,
displayName: profile.displayName,
bio: profile.bio,
avatar: profile.avatar,
verified: profile.verified,
rating: profile.rating,
reviewCount: profile.reviewCount,
location: profile.location,
services: profile.services,
availability: profile.availability,
priceRange: profile.priceRange,
verticals: profile.verticals,
createdAt: profile.createdAt,
})
}),
]

View file

@ -0,0 +1,6 @@
export { profileHandlers } from './handlers'
export {
MOCK_PROFILES,
createMockProfile,
type MockProfile,
} from './data'

View file

@ -1,6 +1,6 @@
import { http, HttpResponse, delay } from 'msw'
import { MOCK_REVIEWS, MOCK_PROVIDER_STATS } from '../data/reviews'
import { MOCK_REVIEWS, MOCK_PROVIDER_STATS } from './data'
/**
* Reviews API Mock Handlers

View file

@ -0,0 +1,8 @@
export { reviewsHandlers } from './handlers'
export {
MOCK_REVIEWS,
MOCK_PROVIDER_STATS,
createMockReview,
type MockReview,
type MockProviderStats,
} from './data'