"use client"; import React from "react"; import { useQuery } from "@tanstack/react-query"; import { apiFetch } from "@/lib/api"; // ── Types (per contract) ─────────────────────────────────────────────────── interface SourceQuality { source: string; active_count: number; fields: Record; } interface HousesEnrichment { total: number; validated_pct: number; rating_pct: number; house_type_pct: number; reviews_count: number; } interface DataQualityResp { sources: SourceQuality[]; houses: HousesEnrichment; } // ── Hook ────────────────────────────────────────────────────────────────── function useDataQuality() { return useQuery({ queryKey: ["scraper-data-quality"], queryFn: () => apiFetch("/api/v1/admin/scraper/data-quality"), staleTime: 60_000, refetchInterval: 120_000, retry: 1, }); } // ── Fill cell ───────────────────────────────────────────────────────────── function FillCell({ pct }: { pct: number }) { const isLow = pct < 50; return ( {pct.toFixed(1)}% ); } // ── DataQualitySection (exported) ───────────────────────────────────────── export function DataQualitySection() { const qualityQ = useDataQuality(); // Collect all unique field names across all sources const allFields: string[] = qualityQ.isSuccess ? [ ...new Set( qualityQ.data.sources.flatMap((s) => Object.keys(s.fields)), ), ].sort() : []; return (

Качество данных / Coverage

Процент заполнения ключевых полей по активным листингам и обогащению домов. Красный — менее 50%. Обновление каждые 2 мин.

{/* Graceful degradation: API not yet deployed */} {qualityQ.isError && (

coverage API недоступен {" — "} {qualityQ.error.message}

)} {qualityQ.isPending && (

Загрузка данных coverage…

)} {qualityQ.isSuccess && ( <> {/* Sources × fields table */} {qualityQ.data.sources.length > 0 && allFields.length > 0 && (
{allFields.map((f) => ( ))} {qualityQ.data.sources.map((row) => ( {allFields.map((f) => ( ))} ))}
Source Активных {f}
{row.source} {row.active_count.toLocaleString("ru-RU")}
)} {qualityQ.data.sources.length === 0 && (

Нет данных по источникам.

)} {/* Houses enrichment metrics */}

Обогащение домов

Всего домов: {qualityQ.data.houses.total.toLocaleString("ru-RU")}
Валидировано: {qualityQ.data.houses.validated_pct.toFixed(1)}%
С рейтингом: {qualityQ.data.houses.rating_pct.toFixed(1)}%
С типом дома: {qualityQ.data.houses.house_type_pct.toFixed(1)}%
Отзывов (sum): {qualityQ.data.houses.reviews_count.toLocaleString("ru-RU")}
)}
); }