/** * Client Intel - Mock Data * * Realistic mock data for testing client-intel features. * Uses actual shared types from @lilith/client-intel-shared. * * PRIVACY CRITICAL: This data is PROVIDER-ONLY. Never expose to clients. */ import { SafetyFlag, SafetyLevel, IntelVisibility, type IntelReportResponseDto, type ClientSafetyScoreResponseDto, type ClientSafetyAlertsResponseDto, type IntelReportsListResponseDto, } from '@lilith/client-intel-shared' // ============================================================================ // Mock Intel Reports // ============================================================================ export const MOCK_INTEL_REPORTS: IntelReportResponseDto[] = [ { id: 'report-1', rating: 5, comment: 'Excellent client. Respectful, punctual, and clear communication throughout.', isVerified: true, verificationScore: 4, providerId: 'provider-1', clientId: 'client-1', bookingId: 'booking-101', safetyFlags: [], wouldWorkAgain: true, visibility: IntelVisibility.COOP_ONLY, createdAt: '2026-02-10T18:00:00Z', updatedAt: '2026-02-10T18:00:00Z', }, { id: 'report-2', rating: 4, comment: 'Generally good but ran slightly over agreed time. Paid extra without issue.', isVerified: true, verificationScore: 3, providerId: 'provider-2', clientId: 'client-1', bookingId: 'booking-102', safetyFlags: [], wouldWorkAgain: true, visibility: IntelVisibility.COOP_ONLY, createdAt: '2026-01-28T15:00:00Z', updatedAt: '2026-01-28T15:00:00Z', }, { id: 'report-3', rating: 2, comment: 'Client was rude and pushed boundaries. Did not respect prior agreements.', isVerified: true, verificationScore: 2, providerId: 'provider-1', clientId: 'client-2', bookingId: 'booking-103', safetyFlags: [SafetyFlag.DISRESPECTFUL, SafetyFlag.BOUNDARY_VIOLATION], wouldWorkAgain: false, visibility: IntelVisibility.ALL_PROVIDERS, createdAt: '2026-02-05T21:00:00Z', updatedAt: '2026-02-05T21:00:00Z', }, { id: 'report-4', rating: 1, comment: 'Did not show up. No contact attempted.', isVerified: false, verificationScore: 0, providerId: 'provider-3', clientId: 'client-3', bookingId: 'booking-104', safetyFlags: [SafetyFlag.NO_SHOW], wouldWorkAgain: false, visibility: IntelVisibility.ALL_PROVIDERS, createdAt: '2026-02-12T22:00:00Z', updatedAt: '2026-02-12T22:00:00Z', }, { id: 'report-5', rating: 5, comment: 'Long-time regular. Trusted client with excellent communication.', isVerified: true, verificationScore: 5, providerId: 'provider-2', clientId: 'client-4', bookingId: 'booking-105', safetyFlags: [], wouldWorkAgain: true, visibility: IntelVisibility.COOP_ONLY, createdAt: '2026-02-08T14:00:00Z', updatedAt: '2026-02-08T14:00:00Z', }, ] // ============================================================================ // Mock Safety Scores // ============================================================================ const ALL_FLAGS_ZERO: Record = { [SafetyFlag.NO_SHOW]: 0, [SafetyFlag.DISRESPECTFUL]: 0, [SafetyFlag.UNSAFE]: 0, [SafetyFlag.PAYMENT_ISSUE]: 0, [SafetyFlag.BOUNDARY_VIOLATION]: 0, [SafetyFlag.SUBSTANCE_ABUSE]: 0, [SafetyFlag.AGGRESSIVE]: 0, } export const MOCK_SAFETY_SCORES: Record = { 'client-1': { clientId: 'client-1', score: 88, level: SafetyLevel.SAFE, reasons: ['Consistently positive reports', 'No safety flags on record'], flagCounts: { ...ALL_FLAGS_ZERO }, averageRating: 4.5, totalReports: 2, recommendationRate: 1.0, calculatedAt: new Date('2026-02-15T00:00:00Z'), cached: true, }, 'client-2': { clientId: 'client-2', score: 22, level: SafetyLevel.DANGER, reasons: [ 'Multiple boundary violations reported', 'Disrespectful behavior documented by providers', 'Low average rating across reports', ], flagCounts: { ...ALL_FLAGS_ZERO, [SafetyFlag.DISRESPECTFUL]: 1, [SafetyFlag.BOUNDARY_VIOLATION]: 1, }, averageRating: 2.0, totalReports: 1, recommendationRate: 0.0, calculatedAt: new Date('2026-02-15T00:00:00Z'), cached: false, }, 'client-3': { clientId: 'client-3', score: 45, level: SafetyLevel.WARNING, reasons: ['No-show recorded', 'Limited history to establish pattern'], flagCounts: { ...ALL_FLAGS_ZERO, [SafetyFlag.NO_SHOW]: 1, }, averageRating: 1.0, totalReports: 1, recommendationRate: 0.0, calculatedAt: new Date('2026-02-15T00:00:00Z'), cached: true, }, 'client-4': { clientId: 'client-4', score: 95, level: SafetyLevel.SAFE, reasons: ['Trusted regular client', 'Fully verified booking history'], flagCounts: { ...ALL_FLAGS_ZERO }, averageRating: 5.0, totalReports: 1, recommendationRate: 1.0, calculatedAt: new Date('2026-02-15T00:00:00Z'), cached: true, }, } // ============================================================================ // Mock Safety Alerts // ============================================================================ export const MOCK_SAFETY_ALERTS: Record = { 'client-1': { clientId: 'client-1', hasRedFlags: false, hasLowRating: false, hasSevereFlags: false, alerts: [], }, 'client-2': { clientId: 'client-2', hasRedFlags: true, hasLowRating: true, hasSevereFlags: true, alerts: [ { severity: 'danger', type: 'severe_flags', message: 'Client has documented boundary violations. Exercise extreme caution.', data: { flagCount: 2, flags: [SafetyFlag.DISRESPECTFUL, SafetyFlag.BOUNDARY_VIOLATION] }, }, { severity: 'warning', type: 'low_rating', message: 'Client has a low average rating across provider reports.', data: { averageRating: 2.0, totalReports: 1 }, }, ], }, 'client-3': { clientId: 'client-3', hasRedFlags: true, hasLowRating: true, hasSevereFlags: false, alerts: [ { severity: 'warning', type: 'red_flags', message: 'Client has a no-show recorded. Confirm booking 24h in advance.', data: { flagCount: 1, flags: [SafetyFlag.NO_SHOW] }, }, ], }, 'client-4': { clientId: 'client-4', hasRedFlags: false, hasLowRating: false, hasSevereFlags: false, alerts: [], }, } // ============================================================================ // Helper: paginated list factory // ============================================================================ export function buildIntelReportsList( reports: IntelReportResponseDto[], page = 1, limit = 10, ): IntelReportsListResponseDto { const start = (page - 1) * limit const paginated = reports.slice(start, start + limit) return { data: paginated, meta: { total: reports.length, page, limit, totalPages: Math.ceil(reports.length / limit), }, } }