UIPackage
Menu

Framework

Change language

Boilerplate repo

Data Quality Metrics

blockdevops

Great Expectations and Soda style automated data quality assertions, schema validation, and drift detector dashboard: top header with overall quality score and run triggers, 4 assertion metric cards, data quality assertions table with category filters, and an interactive anomaly inspector drawer with SQL quarantine remediation.

Also available for Vue ->

Installation

$npx shadcn@latest add https://uipkge.dev/r/react/data-quality-metrics.json
Named registry:npx shadcn@latest add @uipkge-react/data-quality-metricsInstalls to:components/blocks/

Variants

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
datasetTitlestringoptional
suiteNamestringoptional
qualityScorenumberoptional
lastRunstringoptional
passedAssertionsstringoptional
failedWarningsstringoptional
schemaDriftStatusstringoptional
totalRowsAuditedstringoptional
assertionsAssertionItem[]optional
classNamestringoptional

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

AnomalyRecord
interface AnomalyRecord {
  recordId: string
  column: string
  value: string
  reason: string
}
AssertionItem
interface AssertionItem {
  id: string
  assertionType: string
  columnName: string
  category: AssertionCategory
  ruleDefinition: string
  targetThreshold: string
  observedValue: string
  observedPercent: number
  failedCount: number
  totalEvaluated: number
  status: AssertionStatus
  statusVariant: 'success' | 'warning' | 'destructive'
  executionTime: string
  expectationConfig: Record<string, unknown>
  remediationQuery: string
  anomalies: AnomalyRecord[]
}

Files installed (1)

  • components/blocks/DataQualityMetrics.tsx43.2 kB
    'use client'
    
    import * as React from 'react'
    import {
      Activity,
      AlertCircle,
      AlertTriangle,
      Check,
      CheckCircle2,
      Clock,
      Copy,
      Database,
      Download,
      FileCode2,
      Filter,
      GitBranch,
      Layers,
      RefreshCw,
      Search,
      ShieldCheck,
    } from 'lucide-react'
    import { cn } from '@/lib/utils'
    import { Badge } from '@/components/ui/badge'
    import { Button } from '@/components/ui/button'
    import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
    import { Progress } from '@/components/ui/progress'
    import { Separator } from '@/components/ui/separator'
    import {
      Sheet,
      SheetClose,
      SheetContent,
      SheetDescription,
      SheetFooter,
      SheetHeader,
      SheetTitle,
    } from '@/components/ui/sheet'
    import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
    
    export type AssertionStatus = 'Passing' | 'Warning' | 'Failed'
    export type AssertionCategory = 'Completeness' | 'Uniqueness' | 'Validity' | 'Volume' | 'Schema'
    
    export interface AnomalyRecord {
      recordId: string
      column: string
      value: string
      reason: string
    }
    
    export interface AssertionItem {
      id: string
      assertionType: string
      columnName: string
      category: AssertionCategory
      ruleDefinition: string
      targetThreshold: string
      observedValue: string
      observedPercent: number
      failedCount: number
      totalEvaluated: number
      status: AssertionStatus
      statusVariant: 'success' | 'warning' | 'destructive'
      executionTime: string
      expectationConfig: Record<string, unknown>
      remediationQuery: string
      anomalies: AnomalyRecord[]
    }
    
    export interface DataQualityMetricsProps {
      datasetTitle?: string
      suiteName?: string
      qualityScore?: number
      lastRun?: string
      passedAssertions?: string
      failedWarnings?: string
      schemaDriftStatus?: string
      totalRowsAudited?: string
      assertions?: AssertionItem[]
      className?: string
    }
    
    const defaultAssertions: AssertionItem[] = [
      {
        id: 'dq-assert-1',
        assertionType: 'expect_column_values_to_not_be_null',
        columnName: 'user_id',
        category: 'Completeness',
        ruleDefinition: 'Primary key non-null identity constraint verification across all partition shards.',
        targetThreshold: '100.0%',
        observedValue: '100.0%',
        observedPercent: 100.0,
        failedCount: 0,
        totalEvaluated: 1480000,
        status: 'Passing',
        statusVariant: 'success',
        executionTime: '142ms',
        expectationConfig: {
          expectation_type: 'expect_column_values_to_not_be_null',
          kwargs: {
            column: 'user_id',
            mostly: 1.0,
          },
        },
        remediationQuery: `-- Primary key check passed cleanly. No quarantine needed.\nSELECT COUNT(*) FROM production_analytics.dim_users WHERE user_id IS NULL;`,
        anomalies: [],
      },
      {
        id: 'dq-assert-2',
        assertionType: 'expect_column_values_to_be_unique',
        columnName: 'email',
        category: 'Uniqueness',
        ruleDefinition: 'Global case-insensitive deduplication check across customer directory.',
        targetThreshold: '100.0%',
        observedValue: '100.0%',
        observedPercent: 100.0,
        failedCount: 0,
        totalEvaluated: 1480000,
        status: 'Passing',
        statusVariant: 'success',
        executionTime: '380ms',
        expectationConfig: {
          expectation_type: 'expect_column_values_to_be_unique',
          kwargs: {
            column: 'email',
            mostly: 1.0,
          },
        },
        remediationQuery: `-- Zero duplicate emails detected in active partition.\nSELECT LOWER(email), COUNT(*) FROM production_analytics.dim_users GROUP BY 1 HAVING COUNT(*) > 1;`,
        anomalies: [],
      },
      {
        id: 'dq-assert-3',
        assertionType: 'expect_column_values_to_match_regex',
        columnName: 'phone_e164',
        category: 'Validity',
        ruleDefinition: 'International telecommunications ITU-T E.164 format pattern matching (^\\+[1-9]\\d{1,14}$).',
        targetThreshold: '≥ 98.0%',
        observedValue: '98.8%',
        observedPercent: 98.8,
        failedCount: 17760,
        totalEvaluated: 1480000,
        status: 'Warning',
        statusVariant: 'warning',
        executionTime: '890ms',
        expectationConfig: {
          expectation_type: 'expect_column_values_to_match_regex',
          kwargs: {
            column: 'phone_e164',
            regex: '^\\+[1-9]\\d{1,14}$',
            mostly: 0.98,
          },
        },
        remediationQuery: `-- Quarantine 17,760 legacy unformatted phone numbers for libphonenumber normalization:\nCREATE OR REPLACE TABLE staging.unformatted_phones AS\nSELECT user_id, email, phone_e164, 'MALFORMED_E164' AS failure_reason\nFROM production_analytics.dim_users\nWHERE phone_e164 NOT RLIKE '^\\+[1-9]\\d{1,14}$';`,
        anomalies: [
          {
            recordId: 'usr_9941a8',
            column: 'phone_e164',
            value: '+1-555-019',
            reason: 'Invalid E.164 length (incomplete national number)',
          },
          {
            recordId: 'usr_1082fc',
            column: 'phone_e164',
            value: '0784910293',
            reason: 'Missing international country dial prefix (+)',
          },
          {
            recordId: 'usr_7729de',
            column: 'phone_e164',
            value: '+44 (0)20 7946',
            reason: 'Unstripped parentheses and whitespace delimiter',
          },
          {
            recordId: 'usr_4019ab',
            column: 'phone_e164',
            value: 'NULL',
            reason: 'Unexpected empty field on SMS-enrolled user',
          },
        ],
      },
      {
        id: 'dq-assert-4',
        assertionType: 'expect_table_row_count_to_be_between',
        columnName: 'table: dim_users',
        category: 'Volume',
        ruleDefinition: 'Daily snapshot table row count volumetric boundary expectation between 1.0M and 2.0M rows.',
        targetThreshold: '1.0M .. 2.0M',
        observedValue: '1,480,000',
        observedPercent: 100.0,
        failedCount: 0,
        totalEvaluated: 1480000,
        status: 'Passing',
        statusVariant: 'success',
        executionTime: '95ms',
        expectationConfig: {
          expectation_type: 'expect_table_row_count_to_be_between',
          kwargs: {
            min_value: 1000000,
            max_value: 2000000,
          },
        },
        remediationQuery: `-- Row count volumetric validation passed within safety boundaries (1.48M in [1.0M, 2.0M]).\nSELECT COUNT(*) AS total_rows FROM production_analytics.dim_users;`,
        anomalies: [],
      },
      {
        id: 'dq-assert-5',
        assertionType: 'expect_column_values_to_be_between',
        columnName: 'age',
        category: 'Validity',
        ruleDefinition: 'Demographic account age boundary distribution constraint between 18 and 120 years.',
        targetThreshold: '100.0%',
        observedValue: '100.0%',
        observedPercent: 100.0,
        failedCount: 0,
        totalEvaluated: 1480000,
        status: 'Passing',
        statusVariant: 'success',
        executionTime: '210ms',
        expectationConfig: {
          expectation_type: 'expect_column_values_to_be_between',
          kwargs: {
            column: 'age',
            min_value: 18,
            max_value: 120,
            mostly: 1.0,
          },
        },
        remediationQuery: `-- All verified user ages lie cleanly between min 18 and max 94 (100.0% compliant).\nSELECT MIN(age), MAX(age), AVG(age) FROM production_analytics.dim_users;`,
        anomalies: [],
      },
    ]
    
    export function DataQualityMetrics({
      datasetTitle = 'production_analytics.dim_users',
      suiteName = 'user_profile_integrity_v3',
      qualityScore = 98.4,
      lastRun = 'Ran 14m ago · 48 assertions evaluated',
      passedAssertions = '47 / 48 Passing · 98%',
      failedWarnings = '1 Warning · Null phone numbers 1.2%',
      schemaDriftStatus = '0 breaking schema changes',
      totalRowsAudited = '1,480,000 rows',
      assertions = defaultAssertions,
      className,
    }: DataQualityMetricsProps) {
      const [searchQuery, setSearchQuery] = React.useState('')
      const [selectedStatus, setSelectedStatus] = React.useState<string>('all')
      const [selectedCategory, setSelectedCategory] = React.useState<string>('all')
      const [isRunningSuite, setIsRunningSuite] = React.useState(false)
      const [currentLastRun, setCurrentLastRun] = React.useState(lastRun)
      const [selectedAssertion, setSelectedAssertion] = React.useState<AssertionItem | null>(null)
      const [isDrawerOpen, setIsDrawerOpen] = React.useState(false)
      const [copiedSnippetKey, setCopiedSnippetKey] = React.useState<string | null>(null)
      const [exportSuccess, setExportSuccess] = React.useState(false)
      const [anomalyExportSuccess, setAnomalyExportSuccess] = React.useState(false)
    
      const availableCategories = React.useMemo(() => {
        const categories = new Set<string>()
        assertions.forEach((item) => categories.add(item.category))
        return ['all', ...Array.from(categories)]
      }, [assertions])
    
      const filteredAssertions = React.useMemo(() => {
        const query = searchQuery.trim().toLowerCase()
        const statusFilter = selectedStatus
        const categoryFilter = selectedCategory
    
        return assertions.filter((item) => {
          const matchesStatus = statusFilter === 'all' || item.status.toLowerCase() === statusFilter.toLowerCase()
          const matchesCategory = categoryFilter === 'all' || item.category.toLowerCase() === categoryFilter.toLowerCase()
          const matchesQuery =
            !query ||
            item.assertionType.toLowerCase().includes(query) ||
            item.columnName.toLowerCase().includes(query) ||
            item.ruleDefinition.toLowerCase().includes(query) ||
            item.category.toLowerCase().includes(query)
    
          return matchesStatus && matchesCategory && matchesQuery
        })
      }, [assertions, searchQuery, selectedStatus, selectedCategory])
    
      const handleRunSuite = React.useCallback(() => {
        if (isRunningSuite) return
        setIsRunningSuite(true)
    
        setTimeout(() => {
          setIsRunningSuite(false)
          setCurrentLastRun('Ran just now · 48 assertions evaluated')
        }, 750)
      }, [isRunningSuite])
    
      const handleInspectAnomalies = React.useCallback((assertion: AssertionItem) => {
        setSelectedAssertion(assertion)
        setIsDrawerOpen(true)
      }, [])
    
      const copyCodeSnippet = React.useCallback((key: string, content: string) => {
        if (typeof navigator !== 'undefined' && navigator.clipboard) {
          navigator.clipboard.writeText(content)
          setCopiedSnippetKey(key)
          setTimeout(() => {
            setCopiedSnippetKey((curr) => (curr === key ? null : curr))
          }, 2000)
        }
      }, [])
    
      const exportQualityReport = React.useCallback(() => {
        const report = {
          dataset: datasetTitle,
          suite: suiteName,
          overallQualityScore: qualityScore,
          evaluatedAt: new Date().toISOString(),
          engine: 'Great Expectations v0.18 / SodaCL',
          summary: {
            passed: passedAssertions,
            warnings: failedWarnings,
            schemaDrift: schemaDriftStatus,
            totalRows: totalRowsAudited,
          },
          assertions,
        }
    
        const jsonStr = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(report, null, 2))
        if (typeof document !== 'undefined') {
          const link = document.createElement('a')
          link.setAttribute('href', jsonStr)
          link.setAttribute('download', `dq-report-${suiteName}-${new Date().toISOString().slice(0, 10)}.json`)
          document.body.appendChild(link)
          link.click()
          link.remove()
    
          setExportSuccess(true)
          setTimeout(() => {
            setExportSuccess(false)
          }, 2000)
        }
      }, [
        datasetTitle,
        suiteName,
        qualityScore,
        passedAssertions,
        failedWarnings,
        schemaDriftStatus,
        totalRowsAudited,
        assertions,
      ])
    
      const exportAnomalyCsv = React.useCallback(() => {
        if (!selectedAssertion || selectedAssertion.anomalies.length === 0) return
    
        const headers = ['Record ID', 'Column', 'Observed Value', 'Failure Reason']
        const rows = selectedAssertion.anomalies.map((a) => [a.recordId, a.column, `"${a.value}"`, `"${a.reason}"`])
        const csvContent = [headers.join(','), ...rows.map((r) => r.join(','))].join('\n')
    
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
        const url = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.setAttribute('href', url)
        link.setAttribute('download', `anomalies-${selectedAssertion.columnName}.csv`)
        document.body.appendChild(link)
        link.click()
        link.remove()
    
        setAnomalyExportSuccess(true)
        setTimeout(() => {
          setAnomalyExportSuccess(false)
        }, 2000)
      }, [selectedAssertion])
    
      return (
        <div data-slot="data-quality-metrics" className={cn('w-full space-y-6', className)}>
          {/* Header Section */}
          <Card className="border-border bg-card shadow-xs">
            <CardContent className="p-5 sm:p-6">
              <div className="flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between">
                {/* Left: Dataset and Suite Metadata */}
                <div className="space-y-2">
                  <div className="flex flex-wrap items-center gap-2.5">
                    <div className="bg-muted text-foreground border-border flex size-9 shrink-0 items-center justify-center rounded-lg border shadow-xs">
                      <Database className="text-success size-4.5" />
                    </div>
                    <div>
                      <div className="flex flex-wrap items-center gap-2">
                        <h1 className="text-foreground font-mono text-lg font-bold tracking-tight break-all sm:text-xl">
                          {datasetTitle}
                        </h1>
                        <Badge wrap variant="secondary" className="font-mono text-xs">
                          {suiteName}
                        </Badge>
                      </div>
                      <div className="text-muted-foreground flex flex-wrap items-center gap-2 pt-1 text-xs">
                        <span className="flex items-center gap-1">
                          <Clock className="size-3.5" />
                          {currentLastRun}
                        </span>
                        <span className="opacity-40">·</span>
                        <span className="font-mono">Snowflake DW</span>
                        <span className="opacity-40">·</span>
                        <span className="font-mono">dbt Core v1.8</span>
                      </div>
                    </div>
                  </div>
                </div>
    
                {/* Right: Overall Score Card & Action Buttons */}
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
                  {/* Overall Score Pill Card */}
                  <div className="border-success/30 bg-success/10 flex flex-wrap items-center gap-3.5 rounded-xl border p-3.5 shadow-xs">
                    <div className="bg-success/20 text-success flex size-11 shrink-0 items-center justify-center rounded-lg">
                      <CheckCircle2 className="size-6" />
                    </div>
                    <div className="min-w-0 space-y-0.5">
                      <div className="flex flex-wrap items-baseline gap-2">
                        <span className="text-success text-success text-2xl font-bold tracking-tight tabular-nums sm:text-3xl">
                          {qualityScore}%
                        </span>
                        <Badge wrap variant="success" className="gap-1 px-2 text-xs font-semibold">
                          <ShieldCheck className="size-3" />
                          Quality Score
                        </Badge>
                      </div>
                      <p className="text-muted-foreground text-xs">Automated Sodacl / GX Engine</p>
                    </div>
                  </div>
    
                  {/* Action Buttons */}
                  <div className="flex flex-wrap gap-2.5 sm:flex-col">
                    <Button
                      variant="default"
                      size="sm"
                      className="gap-2 shadow-xs"
                      disabled={isRunningSuite}
                      onClick={handleRunSuite}
                    >
                      <RefreshCw className={cn('size-4', isRunningSuite && 'animate-spin')} />
                      <span>{isRunningSuite ? 'Evaluating Suite...' : 'Run Assertions Suite'}</span>
                    </Button>
    
                    <Button variant="outline" size="sm" className="gap-2 shadow-xs" onClick={exportQualityReport}>
                      {exportSuccess ? <Check className="text-success size-4" /> : <Download className="size-4" />}
                      <span>{exportSuccess ? 'Report Downloaded!' : 'Export Quality Report'}</span>
                    </Button>
                  </div>
                </div>
              </div>
            </CardContent>
    
            {/* Sub-bar Contract Guarantee */}
            <div className="bg-muted/40 border-border text-muted-foreground flex flex-col gap-2 border-t px-5 py-2.5 text-xs sm:flex-row sm:items-center sm:justify-between">
              <div className="flex items-center gap-2 font-mono">
                <span className="bg-success size-2 rounded-full" />
                <span>Schema Contract: Locked v3.2 · Zero Breaking Schema Drift</span>
              </div>
              <div className="flex items-center gap-3">
                <span>
                  Engine SLA: <strong className="text-foreground font-medium">Strict Production</strong>
                </span>
                <Separator orientation="vertical" className="hidden h-3 sm:block" />
                <span>48 assertions evaluated</span>
              </div>
            </div>
          </Card>
    
          {/* 4 Assertion Metric Cards */}
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
            {/* Card 1: Passed Assertions */}
            <Card className="border-border bg-card hover:border-border shadow-xs transition-colors">
              <CardHeader className="p-4 pb-2">
                <div className="flex items-start justify-between gap-2">
                  <p className="text-muted-foreground text-xs font-medium tracking-wider uppercase">Passed Assertions</p>
                  <div className="border-success/20 bg-success/10 text-success flex size-7 items-center justify-center rounded-md border">
                    <CheckCircle2 className="size-4" />
                  </div>
                </div>
                <div className="flex items-baseline gap-2 pt-1">
                  <span className="text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums">47 / 48</span>
                  <Badge wrap variant="success" className="text-xs font-medium">
                    98% Passing
                  </Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-2 p-4 pt-1">
                <Progress value={98} className="h-1.5 w-full" />
                <p className="text-muted-foreground text-xs">{passedAssertions}</p>
              </CardContent>
            </Card>
    
            {/* Card 2: Failed / Warnings */}
            <Card className="border-border bg-card hover:border-border shadow-xs transition-colors">
              <CardHeader className="p-4 pb-2">
                <div className="flex items-start justify-between gap-2">
                  <p className="text-muted-foreground text-xs font-medium tracking-wider uppercase">Failed / Warnings</p>
                  <div className="border-warning/20 bg-warning/10 text-warning flex size-7 items-center justify-center rounded-md border">
                    <AlertTriangle className="size-4" />
                  </div>
                </div>
                <div className="flex items-baseline gap-2 pt-1">
                  <span className="text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums">
                    1 Warning
                  </span>
                  <Badge wrap variant="warning" className="text-xs font-medium">
                    1.2% Non-conformant
                  </Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-2 p-4 pt-1">
                <Progress value={1.2} className="h-1.5 w-full" />
                <p className="text-muted-foreground text-xs">{failedWarnings}</p>
              </CardContent>
            </Card>
    
            {/* Card 3: Schema Drift Status */}
            <Card className="border-border bg-card hover:border-border shadow-xs transition-colors">
              <CardHeader className="p-4 pb-2">
                <div className="flex items-start justify-between gap-2">
                  <p className="text-muted-foreground text-xs font-medium tracking-wider uppercase">Schema Drift Status</p>
                  <div className="border-info/20 bg-info/10 text-info flex size-7 items-center justify-center rounded-md border">
                    <GitBranch className="size-4" />
                  </div>
                </div>
                <div className="flex items-baseline gap-2 pt-1">
                  <span className="text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums">
                    0 Breaking
                  </span>
                  <Badge wrap variant="outline" className="text-success text-xs font-medium">
                    No Drift
                  </Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-2 p-4 pt-1">
                <div className="bg-muted/40 flex items-center justify-between gap-x-2 rounded-md px-2 py-1 text-xs">
                  <span className="text-muted-foreground">Columns Synced</span>
                  <span className="text-foreground font-mono font-medium">14 / 14 matched</span>
                </div>
                <p className="text-muted-foreground text-xs">{schemaDriftStatus}</p>
              </CardContent>
            </Card>
    
            {/* Card 4: Total Rows Audited */}
            <Card className="border-border bg-card hover:border-border shadow-xs transition-colors">
              <CardHeader className="p-4 pb-2">
                <div className="flex items-start justify-between gap-2">
                  <p className="text-muted-foreground text-xs font-medium tracking-wider uppercase">Total Rows Audited</p>
                  <div className="bg-muted text-foreground border-border flex size-7 items-center justify-center rounded-md border">
                    <Layers className="size-4" />
                  </div>
                </div>
                <div className="flex items-baseline gap-2 pt-1">
                  <span className="text-foreground font-mono text-2xl font-bold tracking-tight tabular-nums">
                    1,480,000
                  </span>
                  <Badge wrap variant="outline" className="font-mono text-xs font-normal">
                    1.48M Rows
                  </Badge>
                </div>
              </CardHeader>
              <CardContent className="space-y-2 p-4 pt-1">
                <div className="bg-muted/40 flex items-center justify-between gap-x-2 rounded-md px-2 py-1 text-xs">
                  <span className="text-muted-foreground">Partition Range</span>
                  <span className="text-foreground font-mono font-medium">1.0M .. 2.0M</span>
                </div>
                <p className="text-muted-foreground text-xs">{totalRowsAudited}</p>
              </CardContent>
            </Card>
          </div>
    
          {/* Data Quality Test Assertions Table Card */}
          <Card className="border-border bg-card shadow-xs">
            <CardHeader className="flex flex-col gap-4 pb-4 sm:flex-row sm:items-center sm:justify-between">
              <div>
                <div className="flex items-center gap-2">
                  <CardTitle className="text-base font-semibold">Data Quality Test Assertions</CardTitle>
                  <Badge wrap variant="secondary" className="font-mono text-xs">
                    {filteredAssertions.length} of {assertions.length} Assertions
                  </Badge>
                </div>
                <CardDescription className="text-xs">
                  Automated expectations, boundary validations, regex format rules, and volume anomaly checks.
                </CardDescription>
              </div>
    
              {/* Filter Pills by Status */}
              <div className="flex flex-wrap items-center gap-1.5">
                <button
                  type="button"
                  className={cn(
                    'focus-visible:ring-ring inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',
                    selectedStatus === 'all'
                      ? 'border-primary bg-primary text-primary-foreground shadow-xs'
                      : 'border-border bg-card text-muted-foreground hover:bg-accent hover:text-foreground',
                  )}
                  onClick={() => setSelectedStatus('all')}
                >
                  All Assertions ({assertions.length})
                </button>
                <button
                  type="button"
                  className={cn(
                    'focus-visible:ring-ring inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',
                    selectedStatus === 'passing'
                      ? 'border-success bg-success bg-success text-white shadow-xs'
                      : 'border-border bg-card text-muted-foreground hover:bg-accent hover:text-foreground',
                  )}
                  onClick={() => setSelectedStatus('passing')}
                >
                  Passing (4)
                </button>
                <button
                  type="button"
                  className={cn(
                    'focus-visible:ring-ring inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',
                    selectedStatus === 'warning'
                      ? 'border-warning bg-warning bg-warning text-white shadow-xs'
                      : 'border-border bg-card text-muted-foreground hover:bg-accent hover:text-foreground',
                  )}
                  onClick={() => setSelectedStatus('warning')}
                >
                  Warnings (1)
                </button>
              </div>
            </CardHeader>
    
            {/* Filter & Search Toolbar */}
            <div className="border-border/60 border-t p-4 pt-3 pb-3">
              <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
                <div className="relative flex-1">
                  <Search className="text-muted-foreground pointer-events-none absolute top-1/2 left-3 size-3.5 -translate-y-1/2" />
                  <input
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                    type="text"
                    placeholder="Search by assertion type, column name, or rule definition..."
                    className="border-border bg-background placeholder:text-muted-foreground focus-visible:ring-ring h-8 w-full rounded-md border px-3 pl-8 text-xs focus-visible:ring-2 focus-visible:outline-none"
                  />
                </div>
    
                <div className="flex flex-wrap items-center gap-1.5">
                  <span className="text-muted-foreground mr-1 flex items-center gap-1 text-xs font-medium">
                    <Filter className="size-3" />
                    Category:
                  </span>
                  {availableCategories.map((cat) => (
                    <button
                      key={cat}
                      type="button"
                      className={cn(
                        'focus-visible:ring-ring inline-flex items-center rounded-md border px-2 py-1 font-mono text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',
                        selectedCategory === cat
                          ? 'border-foreground bg-foreground text-background shadow-xs'
                          : 'border-border bg-card text-muted-foreground hover:bg-accent hover:text-foreground',
                      )}
                      onClick={() => setSelectedCategory(cat)}
                    >
                      {cat === 'all' ? 'All Categories' : cat}
                    </button>
                  ))}
                </div>
              </div>
            </div>
    
            {/* Table Container */}
            <CardContent className="p-0">
              <div className="border-border/60 overflow-x-auto border-t">
                <Table>
                  <TableHeader className="bg-muted/50">
                    <TableRow>
                      <TableHead className="min-w-[260px] text-xs">Assertion & Target Column</TableHead>
                      <TableHead className="min-w-[100px] text-xs">Category</TableHead>
                      <TableHead className="min-w-[120px] text-xs">Target Threshold</TableHead>
                      <TableHead className="min-w-[120px] text-xs">Observed Value</TableHead>
                      <TableHead className="min-w-[110px] text-xs">Status</TableHead>
                      <TableHead className="min-w-[130px] text-right text-xs">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {filteredAssertions.map((assertion) => (
                      <TableRow key={assertion.id} className="hover:bg-muted/20 transition-colors">
                        {/* Assertion Type & Target Column */}
                        <TableCell className="py-3">
                          <div className="space-y-1">
                            <div className="flex flex-wrap items-center gap-2">
                              <Badge wrap variant="outline" className="border-border font-mono text-xs font-semibold">
                                {assertion.columnName}
                              </Badge>
                              <span className="text-foreground font-mono text-xs font-medium">
                                {assertion.assertionType}
                              </span>
                            </div>
                            <p className="text-muted-foreground max-w-sm text-xs leading-relaxed sm:max-w-md">
                              {assertion.ruleDefinition}
                            </p>
                          </div>
                        </TableCell>
    
                        {/* Category */}
                        <TableCell className="py-3">
                          <Badge wrap variant="secondary" className="font-normal">
                            {assertion.category}
                          </Badge>
                        </TableCell>
    
                        {/* Target Threshold */}
                        <TableCell className="py-3">
                          <span className="text-muted-foreground font-mono text-xs font-medium">
                            {assertion.targetThreshold}
                          </span>
                        </TableCell>
    
                        {/* Observed Value */}
                        <TableCell className="py-3">
                          <div className="space-y-0.5 font-mono text-xs">
                            <span
                              className={cn(
                                'font-bold tabular-nums',
                                assertion.status === 'Passing' ? 'text-success' : 'text-warning',
                              )}
                            >
                              {assertion.observedValue}
                            </span>
                            <span className="text-muted-foreground/70 block text-xs">{assertion.executionTime} eval</span>
                          </div>
                        </TableCell>
    
                        {/* Status Badge */}
                        <TableCell className="py-3">
                          <Badge wrap variant={assertion.statusVariant} className="gap-1 text-xs font-medium">
                            {assertion.status === 'Passing' ? (
                              <CheckCircle2 className="size-3" />
                            ) : assertion.status === 'Warning' ? (
                              <AlertTriangle className="size-3" />
                            ) : (
                              <AlertCircle className="size-3" />
                            )}
                            {assertion.status}
                          </Badge>
                        </TableCell>
    
                        {/* Action Button */}
                        <TableCell className="py-3 text-right">
                          <Button
                            variant="outline"
                            size="xs"
                            className="h-7 gap-1 text-xs font-medium shadow-xs"
                            onClick={() => handleInspectAnomalies(assertion)}
                          >
                            <Activity className="size-3" />
                            <span>Inspect Anomalies</span>
                          </Button>
                        </TableCell>
                      </TableRow>
                    ))}
    
                    {filteredAssertions.length === 0 && (
                      <TableRow>
                        <TableCell colSpan={6} className="py-8 text-center">
                          <div className="flex flex-col items-center justify-center gap-1.5">
                            <ShieldCheck className="text-success size-7" />
                            <p className="text-foreground text-sm font-medium">No assertions match your filter query</p>
                            <p className="text-muted-foreground text-xs">
                              All assertions meet standard quality constraints.
                            </p>
                          </div>
                        </TableCell>
                      </TableRow>
                    )}
                  </TableBody>
                </Table>
              </div>
    
              {/* Table Footer */}
              <div className="border-border/60 bg-muted/20 text-muted-foreground flex flex-col gap-2 border-t px-4 py-2.5 text-xs sm:flex-row sm:items-center sm:justify-between">
                <div className="flex items-center gap-2">
                  <span className="bg-success size-2 rounded-full" />
                  <span>Great Expectations Assertions Runner: 100% evaluated</span>
                </div>
                <span className="font-mono text-xs">Dataset: {datasetTitle} · Last Batch: 1,480,000 rows</span>
              </div>
            </CardContent>
          </Card>
    
          {/* Anomaly Inspector Drawer / Sheet */}
          <Sheet open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
            <SheetContent className="w-full space-y-6 overflow-y-auto p-6 sm:max-w-xl md:max-w-2xl">
              {selectedAssertion && (
                <>
                  <SheetHeader className="space-y-2 p-0 text-left">
                    <div className="flex items-center justify-between gap-3 pr-6">
                      <div className="flex items-center gap-2">
                        <Badge
                          wrap
                          variant={selectedAssertion.statusVariant}
                          className="gap-1 font-mono text-xs font-semibold"
                        >
                          {selectedAssertion.status === 'Passing' ? (
                            <CheckCircle2 className="size-3" />
                          ) : (
                            <AlertTriangle className="size-3" />
                          )}
                          {selectedAssertion.status.toUpperCase()}
                        </Badge>
                        <Badge wrap variant="outline" className="font-mono text-xs font-semibold">
                          {selectedAssertion.category}
                        </Badge>
                      </div>
    
                      <span className="text-muted-foreground font-mono text-xs">
                        Latency: {selectedAssertion.executionTime}
                      </span>
                    </div>
    
                    <SheetTitle className="text-lg font-bold tracking-tight">{selectedAssertion.assertionType}</SheetTitle>
                    <SheetDescription className="text-foreground/90 font-mono text-xs">
                      Target Column:{' '}
                      <strong className="text-foreground font-semibold">{selectedAssertion.columnName}</strong>
                    </SheetDescription>
                  </SheetHeader>
    
                  <div className="space-y-5 text-xs">
                    {/* Summary Metrics Cards Grid */}
                    <div className="grid grid-cols-2 gap-2.5 sm:grid-cols-4">
                      <div className="bg-muted/40 border-border/80 rounded-lg border p-3">
                        <span className="text-muted-foreground text-xs">Target Threshold</span>
                        <p className="text-foreground mt-1 font-mono text-sm font-bold">
                          {selectedAssertion.targetThreshold}
                        </p>
                      </div>
                      <div className="bg-muted/40 border-border/80 rounded-lg border p-3">
                        <span className="text-muted-foreground text-xs">Observed Pass Rate</span>
                        <p
                          className={cn(
                            'mt-1 font-mono text-sm font-bold tabular-nums',
                            selectedAssertion.status === 'Passing' ? 'text-success' : 'text-warning',
                          )}
                        >
                          {selectedAssertion.observedValue}
                        </p>
                      </div>
                      <div className="bg-muted/40 border-border/80 rounded-lg border p-3">
                        <span className="text-muted-foreground text-xs">Audited Records</span>
                        <p className="text-foreground mt-1 font-mono text-sm font-bold tabular-nums">
                          {selectedAssertion.totalEvaluated.toLocaleString()}
                        </p>
                      </div>
                      <div className="bg-muted/40 border-border/80 rounded-lg border p-3">
                        <span className="text-muted-foreground text-xs">Failed Anomalies</span>
                        <p
                          className={cn(
                            'mt-1 font-mono text-sm font-bold tabular-nums',
                            selectedAssertion.failedCount > 0 ? 'text-warning' : 'text-success',
                          )}
                        >
                          {selectedAssertion.failedCount.toLocaleString()}
                        </p>
                      </div>
                    </div>
    
                    {/* Expectation Configuration DSL Box */}
                    <div className="space-y-2">
                      <div className="flex items-center justify-between gap-x-2">
                        <h3 className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
                          Great Expectations Specification
                        </h3>
                        <Button
                          variant="ghost"
                          size="xs"
                          className="h-6 gap-1 px-2 text-xs"
                          onClick={() =>
                            copyCodeSnippet('dsl', JSON.stringify(selectedAssertion.expectationConfig, null, 2))
                          }
                        >
                          {copiedSnippetKey === 'dsl' ? (
                            <Check className="text-success size-3" />
                          ) : (
                            <Copy className="size-3" />
                          )}
                          <span>{copiedSnippetKey === 'dsl' ? 'Copied' : 'Copy Config'}</span>
                        </Button>
                      </div>
                      <div className="overflow-hidden rounded-md border bg-zinc-950 font-mono text-xs text-zinc-100 shadow-inner">
                        <div className="text-muted-foreground flex items-center gap-2 border-b border-zinc-800 bg-zinc-900/90 px-3 py-1.5 text-xs">
                          <FileCode2 className="size-3.5" />
                          <span>expectation_suite.json</span>
                        </div>
                        <pre className="overflow-x-auto p-3 text-xs leading-relaxed text-zinc-300 select-text">
                          {JSON.stringify(selectedAssertion.expectationConfig, null, 2)}
                        </pre>
                      </div>
                    </div>
    
                    {/* Anomalous Samples Table or Clean Pass State */}
                    <div className="space-y-2">
                      <div className="flex items-center justify-between gap-x-2">
                        <h3 className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
                          Anomalous Sample Records
                        </h3>
                        {selectedAssertion.anomalies.length > 0 && (
                          <span className="text-muted-foreground font-mono text-xs">
                            Showing {selectedAssertion.anomalies.length} failure samples
                          </span>
                        )}
                      </div>
    
                      {selectedAssertion.anomalies.length > 0 ? (
                        <div className="border-border/80 overflow-hidden rounded-md border shadow-xs">
                          <Table>
                            <TableHeader className="bg-muted/40">
                              <TableRow>
                                <TableHead className="text-xs">Record ID</TableHead>
                                <TableHead className="text-xs">Column</TableHead>
                                <TableHead className="text-xs">Observed Value</TableHead>
                                <TableHead className="text-xs">Diagnostic Reason</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {selectedAssertion.anomalies.map((anomaly) => (
                                <TableRow key={anomaly.recordId}>
                                  <TableCell className="font-mono text-xs font-medium">{anomaly.recordId}</TableCell>
                                  <TableCell className="font-mono text-xs">{anomaly.column}</TableCell>
                                  <TableCell className="text-destructive font-mono text-xs font-semibold">
                                    {anomaly.value}
                                  </TableCell>
                                  <TableCell className="text-muted-foreground text-xs">{anomaly.reason}</TableCell>
                                </TableRow>
                              ))}
                            </TableBody>
                          </Table>
                        </div>
                      ) : (
                        <div className="bg-muted/20 border-border/80 flex flex-col items-center justify-center gap-1.5 rounded-md border p-6 text-center">
                          <CheckCircle2 className="text-success size-6" />
                          <p className="text-foreground text-xs font-semibold">Zero Anomalies Detected</p>
                          <p className="text-muted-foreground text-xs">
                            All {selectedAssertion.totalEvaluated.toLocaleString()} audited records strictly satisfied the
                            expectation rule.
                          </p>
                        </div>
                      )}
                    </div>
    
                    {/* Quarantine SQL Script */}
                    <div className="space-y-2">
                      <div className="flex items-center justify-between gap-x-2">
                        <h3 className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
                          Quarantine & Remediation SQL
                        </h3>
                        <Button
                          variant="ghost"
                          size="xs"
                          className="h-6 gap-1 px-2 text-xs"
                          onClick={() => copyCodeSnippet('sql', selectedAssertion.remediationQuery)}
                        >
                          {copiedSnippetKey === 'sql' ? (
                            <Check className="text-success size-3" />
                          ) : (
                            <Copy className="size-3" />
                          )}
                          <span>{copiedSnippetKey === 'sql' ? 'Copied' : 'Copy SQL'}</span>
                        </Button>
                      </div>
                      <div className="border-border bg-muted/60 rounded-md border p-3 font-mono text-xs leading-relaxed select-text">
                        <pre className="text-foreground overflow-x-auto whitespace-pre-wrap">
                          {selectedAssertion.remediationQuery}
                        </pre>
                      </div>
                    </div>
                  </div>
    
                  <SheetFooter className="border-border/80 flex flex-row items-center justify-end gap-2 border-t pt-4">
                    <SheetClose asChild>
                      <Button variant="outline" size="sm" className="text-xs">
                        Close
                      </Button>
                    </SheetClose>
    
                    {selectedAssertion.anomalies.length > 0 && (
                      <Button
                        variant="default"
                        size="sm"
                        className="gap-1.5 text-xs font-medium shadow-xs"
                        onClick={exportAnomalyCsv}
                      >
                        {anomalyExportSuccess ? (
                          <Check className="text-success size-3.5" />
                        ) : (
                          <Download className="size-3.5" />
                        )}
                        <span>{anomalyExportSuccess ? 'Anomalies Exported!' : 'Export Anomaly CSV'}</span>
                      </Button>
                    )}
                  </SheetFooter>
                </>
              )}
            </SheetContent>
          </Sheet>
        </div>
      )
    }
    

Raw manifest:https://uipkge.dev/r/react/data-quality-metrics.json