import { OperationsHealth, SafeAuditEvent, ComponentHealthStatus, HealthComponentKey, OperationsOverviewData, OverviewSecurityErrorItem, SafeIncidentSummary, } from '../components/ops/types'; export const HEALTH_COMPONENT_METADATA: Record< HealthComponentKey, { name: string; description: string } > = { operations_api: { name: 'Operations API', description: 'FastAPI core endpoint runtime & ingress', }, operations_database: { name: 'Operations Database', description: 'PostgreSQL ops schema relational persistence', }, session_validation: { name: 'Session Validation', description: '__Host-motorsignal_ops token verification & authority', }, audit_persistence: { name: 'Audit Persistence', description: 'Immutable operational security activity persistence', }, }; export const APPROVED_AUDIT_METADATA_KEYS = new Set([ 'component', 'status_code', 'subsystem', 'duration_ms', 'policy', 'action_scope', 'session_valid', 'mfa_verified', 'migration_version', 'records_affected', ]); export function isValidHealthStatus(status: unknown): status is ComponentHealthStatus { return ( status === 'available' || status === 'degraded' || status === 'unavailable' || status === 'unknown' ); } export function normalizeHealthResponse(raw: unknown): OperationsHealth { const fallbackCheckedAt = new Date().toISOString(); if (!raw || typeof raw !== 'object') { return { status: 'unavailable', checked_at: fallbackCheckedAt, components: { operations_api: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_api.description }, operations_database: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_database.description }, session_validation: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.session_validation.description }, audit_persistence: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.audit_persistence.description }, }, }; } const obj = raw as Record; const rawStatus = obj.status; const overallStatus: ComponentHealthStatus = isValidHealthStatus(rawStatus) ? rawStatus : 'unknown'; const checkedAt = typeof obj.checked_at === 'string' && obj.checked_at.length > 0 ? obj.checked_at : fallbackCheckedAt; const rawComponents = obj.components && typeof obj.components === 'object' ? (obj.components as Record) : {}; const keys: HealthComponentKey[] = [ 'operations_api', 'operations_database', 'session_validation', 'audit_persistence', ]; const components: Record< HealthComponentKey, { status: ComponentHealthStatus; description: string } > = { operations_api: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_api.description }, operations_database: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_database.description }, session_validation: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.session_validation.description }, audit_persistence: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.audit_persistence.description }, }; for (const key of keys) { const rawComp = rawComponents[key] as Record | undefined; const compStatus = rawComp && isValidHealthStatus(rawComp.status) ? rawComp.status : isValidHealthStatus(obj[key]) ? (obj[key] as ComponentHealthStatus) : overallStatus; components[key] = { status: compStatus, description: (rawComp?.description as string) || HEALTH_COMPONENT_METADATA[key].description, }; } return { status: overallStatus, checked_at: checkedAt, components, }; } export function sanitizeAuditEvent(raw: unknown): SafeAuditEvent | null { if (!raw || typeof raw !== 'object') { return null; // Fail closed } const obj = raw as Record; // Required: timestamp (ISO string) if (typeof obj.timestamp !== 'string' || !obj.timestamp.trim()) { return null; } const timestamp = obj.timestamp.trim(); // Required: action if (typeof obj.action !== 'string' || !obj.action.trim()) { return null; } const action = obj.action.trim(); // Required: result if (typeof obj.result !== 'string' || !obj.result.trim()) { return null; } const result = obj.result.trim(); // Required: actor_identity (exact OPS-3B contract, no actor_email alias) if (typeof obj.actor_identity !== 'string' || !obj.actor_identity.trim()) { return null; // Fail closed: missing verified identity } const actor_identity = obj.actor_identity.trim(); // Optional transport ID (unrendered in UI) const id = typeof obj.id === 'string' && obj.id.trim() ? obj.id.trim() : undefined; // Optional: actor_role const actor_role = typeof obj.actor_role === 'string' && obj.actor_role.trim() ? obj.actor_role.trim() : undefined; // Optional: target_resource (exact OPS-3B contract, no target alias) const target_resource = typeof obj.target_resource === 'string' && obj.target_resource.trim() ? obj.target_resource.trim() : undefined; // Optional: reason_code const reason_code = typeof obj.reason_code === 'string' && obj.reason_code.trim() ? obj.reason_code.trim() : undefined; // Optional: case_reference const case_reference = typeof obj.case_reference === 'string' && obj.case_reference.trim() ? obj.case_reference.trim() : undefined; // Explicit Allowlist Metadata Projection only let metadata: Record | undefined = undefined; if (obj.metadata && typeof obj.metadata === 'object' && !Array.isArray(obj.metadata)) { const rawMeta = obj.metadata as Record; const safeMeta: Record = {}; for (const [k, v] of Object.entries(rawMeta)) { if (!APPROVED_AUDIT_METADATA_KEYS.has(k)) { continue; // Drop unapproved metadata key } if (typeof v === 'string' && v.length <= 100) { safeMeta[k] = v; } else if (typeof v === 'number' || typeof v === 'boolean') { safeMeta[k] = v; } } if (Object.keys(safeMeta).length > 0) { metadata = safeMeta; } } return { id, timestamp, action, result, actor_identity, actor_role, target_resource, reason_code, case_reference, metadata, }; } // ============================================================ // Incident Sanitizers & Validators (OPS-4) // ============================================================ export function isValidIncidentSeverity(severity: unknown): severity is import('../components/ops/types').IncidentSeverity { return ( severity === 'low' || severity === 'medium' || severity === 'high' || severity === 'critical' ); } export function isValidIncidentStatus(status: unknown): status is import('../components/ops/types').IncidentStatus { return ( status === 'open' || status === 'investigating' || status === 'monitoring' || status === 'resolved' || status === 'closed' || status === 'archived' ); } const ALLOWED_INCIDENT_TRANSITIONS: Record> = { open: new Set(['investigating', 'resolved', 'closed']), investigating: new Set(['monitoring', 'resolved', 'closed']), monitoring: new Set(['investigating', 'resolved', 'closed']), resolved: new Set(['closed', 'investigating']), closed: new Set(['investigating']), // Reopen (Owner only) archived: new Set(), // Terminal }; export function isValidStatusTransition( current: import('../components/ops/types').IncidentStatus, target: import('../components/ops/types').IncidentStatus, role: import('../components/ops/types').OperationsRole ): boolean { if (current === target) return false; if (current === 'archived') return false; // Terminal if (target === 'archived') return role === 'owner'; // Owner only if (current === 'closed' && target === 'investigating') return role === 'owner'; // Owner only const allowed = ALLOWED_INCIDENT_TRANSITIONS[current]; return allowed ? allowed.has(target) : false; } export function sanitizeIncidentSummary(raw: unknown): import('../components/ops/types').SafeIncidentSummary | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; if (typeof obj.case_reference !== 'string' || !obj.case_reference.trim()) return null; const case_reference = obj.case_reference.trim(); if (typeof obj.title !== 'string' || !obj.title.trim()) return null; const title = obj.title.trim(); if (!isValidIncidentSeverity(obj.severity)) return null; const severity = obj.severity; if (!isValidIncidentStatus(obj.status)) return null; const status = obj.status; if (typeof obj.created_at !== 'string' || !obj.created_at.trim()) return null; const created_at = obj.created_at.trim(); const updated_at = typeof obj.updated_at === 'string' && obj.updated_at.trim() ? obj.updated_at.trim() : created_at; return { case_reference, title, severity, status, created_at, updated_at, }; } export function sanitizeIncidentDetail(raw: unknown): import('../components/ops/types').SafeIncidentDetail | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; const summaryData = sanitizeIncidentSummary(raw); if (!summaryData) return null; if (typeof obj.summary !== 'string' || !obj.summary.trim()) return null; const summary = obj.summary.trim(); if (typeof obj.created_by_identity !== 'string' || !obj.created_by_identity.trim()) return null; const created_by_identity = obj.created_by_identity.trim(); const closed_at = typeof obj.closed_at === 'string' && obj.closed_at.trim() ? obj.closed_at.trim() : null; const resolution = typeof obj.resolution === 'string' && obj.resolution.trim() ? obj.resolution.trim() : null; const closed_by_identity = typeof obj.closed_by_identity === 'string' && obj.closed_by_identity.trim() ? obj.closed_by_identity.trim() : null; return { ...summaryData, summary, created_by_identity, closed_at, resolution, closed_by_identity, }; } export function sanitizeIncidentNote(raw: unknown): import('../components/ops/types').SafeIncidentNote | null { if (!raw || typeof raw !== 'object') return null; const obj = raw as Record; if (typeof obj.created_at !== 'string' || !obj.created_at.trim()) return null; const created_at = obj.created_at.trim(); if (typeof obj.created_by_identity !== 'string' || !obj.created_by_identity.trim()) return null; const created_by_identity = obj.created_by_identity.trim(); if (typeof obj.body !== 'string' || !obj.body.trim()) return null; const body = obj.body.trim(); return { created_at, created_by_identity, body, }; } export function normalizeOverviewResponse(raw: unknown): OperationsOverviewData { const fallbackGeneratedAt = new Date().toISOString(); const defaultHealth = normalizeHealthResponse(null); if (!raw || typeof raw !== 'object') { return { generated_at: fallbackGeneratedAt, users: { total_registered: 0, active_24h: 0, active_7d: 0, new_this_week: 0, }, membership: { total_subscribers: 0, premium_members: 0, free_members: 0, conversion_rate_pct: 0, }, activity: { web_active_sessions_24h: 0, web_logins_24h: 0, web_signups_7d: 0, mobile_active_sessions_24h: 0, mobile_rides_today: 0, mobile_rides_active: 0, mobile_datapoints_24h: 0, }, incidents: { total_open: 0, critical_count: 0, high_count: 0, medium_count: 0, low_count: 0, recent_open: [], }, errors: { errors_24h: 0, denials_24h: 0, recent: [], }, health: defaultHealth, }; } const obj = raw as Record; const rawUsers = obj.users && typeof obj.users === 'object' ? (obj.users as Record) : {}; const rawMembership = obj.membership && typeof obj.membership === 'object' ? (obj.membership as Record) : {}; const rawActivity = obj.activity && typeof obj.activity === 'object' ? (obj.activity as Record) : {}; const rawIncidents = obj.incidents && typeof obj.incidents === 'object' ? (obj.incidents as Record) : {}; const rawErrors = obj.errors && typeof obj.errors === 'object' ? (obj.errors as Record) : {}; const rawRecentOpen = Array.isArray(rawIncidents.recent_open) ? rawIncidents.recent_open : []; const safeRecentOpen: SafeIncidentSummary[] = rawRecentOpen .map(sanitizeIncidentSummary) .filter((i): i is SafeIncidentSummary => i !== null); const rawRecentErrors = Array.isArray(rawErrors.recent) ? rawErrors.recent : []; const safeRecentErrors: OverviewSecurityErrorItem[] = rawRecentErrors .map((e): OverviewSecurityErrorItem | null => { if (!e || typeof e !== 'object') return null; const errObj = e as Record; if (typeof errObj.timestamp !== 'string' || !errObj.timestamp.trim()) return null; if (typeof errObj.action !== 'string' || !errObj.action.trim()) return null; if (typeof errObj.actor_identity !== 'string' || !errObj.actor_identity.trim()) return null; return { id: typeof errObj.id === 'string' && errObj.id.trim() ? errObj.id.trim() : undefined, timestamp: errObj.timestamp.trim(), action: errObj.action.trim(), actor_identity: errObj.actor_identity.trim(), reason_code: typeof errObj.reason_code === 'string' && errObj.reason_code.trim() ? errObj.reason_code.trim() : undefined, result: typeof errObj.result === 'string' && errObj.result.trim() ? errObj.result.trim() : 'failure', target_resource: typeof errObj.target_resource === 'string' && errObj.target_resource.trim() ? errObj.target_resource.trim() : undefined, }; }) .filter((e): e is OverviewSecurityErrorItem => e !== null); return { generated_at: typeof obj.generated_at === 'string' && obj.generated_at.trim() ? obj.generated_at.trim() : fallbackGeneratedAt, users: { total_registered: typeof rawUsers.total_registered === 'number' ? rawUsers.total_registered : 0, active_24h: typeof rawUsers.active_24h === 'number' ? rawUsers.active_24h : 0, active_7d: typeof rawUsers.active_7d === 'number' ? rawUsers.active_7d : 0, new_this_week: typeof rawUsers.new_this_week === 'number' ? rawUsers.new_this_week : 0, }, membership: { total_subscribers: typeof rawMembership.total_subscribers === 'number' ? rawMembership.total_subscribers : 0, premium_members: typeof rawMembership.premium_members === 'number' ? rawMembership.premium_members : typeof rawMembership.pro_members === 'number' ? rawMembership.pro_members : 0, free_members: typeof rawMembership.free_members === 'number' ? rawMembership.free_members : 0, conversion_rate_pct: typeof rawMembership.conversion_rate_pct === 'number' ? rawMembership.conversion_rate_pct : 0, }, activity: { web_active_sessions_24h: typeof rawActivity.web_active_sessions_24h === 'number' ? rawActivity.web_active_sessions_24h : 0, web_logins_24h: typeof rawActivity.web_logins_24h === 'number' ? rawActivity.web_logins_24h : 0, web_signups_7d: typeof rawActivity.web_signups_7d === 'number' ? rawActivity.web_signups_7d : 0, mobile_active_sessions_24h: typeof rawActivity.mobile_active_sessions_24h === 'number' ? rawActivity.mobile_active_sessions_24h : 0, mobile_rides_today: typeof rawActivity.mobile_rides_today === 'number' ? rawActivity.mobile_rides_today : 0, mobile_rides_active: typeof rawActivity.mobile_rides_active === 'number' ? rawActivity.mobile_rides_active : 0, mobile_datapoints_24h: typeof rawActivity.mobile_datapoints_24h === 'number' ? rawActivity.mobile_datapoints_24h : 0, }, incidents: { total_open: typeof rawIncidents.total_open === 'number' ? rawIncidents.total_open : safeRecentOpen.length, critical_count: typeof rawIncidents.critical_count === 'number' ? rawIncidents.critical_count : 0, high_count: typeof rawIncidents.high_count === 'number' ? rawIncidents.high_count : 0, medium_count: typeof rawIncidents.medium_count === 'number' ? rawIncidents.medium_count : 0, low_count: typeof rawIncidents.low_count === 'number' ? rawIncidents.low_count : 0, recent_open: safeRecentOpen, }, errors: { errors_24h: typeof rawErrors.errors_24h === 'number' ? rawErrors.errors_24h : 0, denials_24h: typeof rawErrors.denials_24h === 'number' ? rawErrors.denials_24h : 0, recent: safeRecentErrors, }, health: normalizeHealthResponse(obj.health), }; }