{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "feature-store-registry",
  "title": "Feature Store Registry",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/feature-store-registry/FeatureStoreRegistry.vue",
      "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport type { HTMLAttributes } from 'vue'\nimport {\n  Activity,\n  Check,\n  CheckCircle2,\n  Clock,\n  Code2,\n  Copy,\n  Cpu,\n  Database,\n  Download,\n  Fingerprint,\n  Key,\n  Layers,\n  Loader2,\n  Search,\n  ShieldCheck,\n  Table2,\n  Workflow,\n  Zap,\n} from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\n\ninterface FeatureDefinition {\n  name: string\n  dtype: 'Float64' | 'Int32' | 'String'\n  description: string\n  aggregationWindow: string\n  onlineCacheKey: string\n  freshness: string\n  status: 'Online & Batch Ready'\n  sourceSql: string\n  sampleValue: string\n}\n\ninterface MetricCard {\n  title: string\n  value: string\n  subtitle: string\n  badge: string\n  icon: any\n}\n\nconst props = defineProps<{\n  class?: HTMLAttributes['class']\n}>()\n\nconst activeTab = ref<'features' | 'python-feast' | 'lineage'>('features')\nconst searchQuery = ref('')\nconst selectedType = ref<'all' | 'Float64' | 'Int32' | 'String'>('all')\nconst isMaterializing = ref(false)\nconst materializeSuccess = ref(false)\nconst isGeneratingDataset = ref(false)\nconst datasetSuccess = ref(false)\nconst copiedFeast = ref(false)\nconst copiedKey = ref<string | null>(null)\nconst selectedEntityId = ref('usr_9a4f201d-7e2b-4d68')\n\nconst metrics: MetricCard[] = [\n  {\n    title: 'Total Features Registered',\n    value: '18 Active Features',\n    subtitle: '5 in this view · 4 views active',\n    badge: '18 in Registry',\n    icon: Layers,\n  },\n  {\n    title: 'Online Cache Hit Rate',\n    value: '99.8%',\n    subtitle: '1.4ms p95 latency · Redis Cluster',\n    badge: '< 2ms SLA',\n    icon: Zap,\n  },\n  {\n    title: 'Daily Ingestion Throughput',\n    value: '14.8M Updates / Day',\n    subtitle: '171.2 req/s avg · Stream + Batch',\n    badge: 'Real-time CDC',\n    icon: Activity,\n  },\n  {\n    title: 'Max Point-in-Time TTL',\n    value: '30 Days',\n    subtitle: 'Lookback window · Anti-leakage safe',\n    badge: 'AS-OF Safe',\n    icon: Clock,\n  },\n]\n\nconst features: FeatureDefinition[] = [\n  {\n    name: 'avg_transaction_value_30d',\n    dtype: 'Float64',\n    description: '30-day sliding average transaction amount in base USD currency',\n    aggregationWindow: '30-day sliding mean',\n    onlineCacheKey: 'user:ft:avg_tx_val_30d',\n    freshness: 'Synced 4m ago',\n    status: 'Online & Batch Ready',\n    sourceSql: 'AVG(amount_usd) OVER (PARTITION BY user_id ROWS BETWEEN 30 PRECEDING AND CURRENT ROW)',\n    sampleValue: '$342.80',\n  },\n  {\n    name: 'failed_logins_24h',\n    dtype: 'Int32',\n    description: 'Failed authentication attempts in rolling 24-hour security window',\n    aggregationWindow: '24-hour count',\n    onlineCacheKey: 'user:ft:fail_login_24h',\n    freshness: 'Synced 2m ago',\n    status: 'Online & Batch Ready',\n    sourceSql: 'SUM(CASE WHEN auth_success = FALSE THEN 1 ELSE 0 END)',\n    sampleValue: '0',\n  },\n  {\n    name: 'lifetime_chargeback_count',\n    dtype: 'Int32',\n    description: 'Total historical dispute and payment chargeback occurrences',\n    aggregationWindow: 'Cumulative lifetime',\n    onlineCacheKey: 'user:ft:cb_cnt_lt',\n    freshness: 'Synced 12m ago',\n    status: 'Online & Batch Ready',\n    sourceSql: 'COUNT(chargeback_id) OVER (PARTITION BY user_id)',\n    sampleValue: '0',\n  },\n  {\n    name: 'preferred_payment_method',\n    dtype: 'String',\n    description: 'Most frequently utilized payment method category across checkout sessions',\n    aggregationWindow: 'Mode category',\n    onlineCacheKey: 'user:ft:pref_pay_method',\n    freshness: 'Synced 18m ago',\n    status: 'Online & Batch Ready',\n    sourceSql: 'MODE(payment_method_code) OVER (PARTITION BY user_id)',\n    sampleValue: '\"apple_pay\"',\n  },\n  {\n    name: 'risk_score_ml_v3',\n    dtype: 'Float64',\n    description: 'Real-time XGBoost inference fraud risk score probability [0.0 - 1.0]',\n    aggregationWindow: 'Real-time inference',\n    onlineCacheKey: 'user:ft:risk_score_v3',\n    freshness: 'Synced 1m ago',\n    status: 'Online & Batch Ready',\n    sourceSql: 'MODEL_PREDICT_FRAUD_V3(features)',\n    sampleValue: '0.042',\n  },\n]\n\nconst pythonFeastSource = `from datetime import timedelta\nfrom feast import (\n    BatchSource,\n    Entity,\n    FeatureView,\n    Field,\n    SnowflakeSource,\n    ValueType,\n)\nfrom feast.types import Float64, Int32, String\n\n# 1. Define Primary Entity\nuser_entity = Entity(\n    name=\"user_id\",\n    value_type=ValueType.STRING,\n    join_keys=[\"user_id\"],\n    description=\"Global UUID representing verified consumer and business accounts\",\n)\n\n# 2. Snowflake Gold DW Batch Offline Source\ntransactions_batch_source = SnowflakeSource(\n    database=\"ANALYTICS_PROD\",\n    schema=\"GOLD_MARTS\",\n    table=\"fct_user_transactions_daily\",\n    timestamp_field=\"event_timestamp\",\n    created_timestamp_column=\"created_at\",\n)\n\n# 3. Dual-Store Feature View Definition (Redis Online + Snowflake Batch)\nuser_30d_transaction_aggregates = FeatureView(\n    name=\"user_30d_transaction_aggregates\",\n    entities=[user_entity],\n    ttl=timedelta(days=30),\n    schema=[\n        Field(\n            name=\"avg_transaction_value_30d\",\n            dtype=Float64,\n            description=\"30-day sliding average transaction amount in base USD currency\",\n        ),\n        Field(\n            name=\"failed_logins_24h\",\n            dtype=Int32,\n            description=\"Failed authentication attempts in rolling 24-hour security window\",\n        ),\n        Field(\n            name=\"lifetime_chargeback_count\",\n            dtype=Int32,\n            description=\"Total historical dispute and payment chargeback occurrences\",\n        ),\n        Field(\n            name=\"preferred_payment_method\",\n            dtype=String,\n            description=\"Most frequently utilized payment method category across checkout sessions\",\n        ),\n        Field(\n            name=\"risk_score_ml_v3\",\n            dtype=Float64,\n            description=\"Real-time XGBoost inference fraud risk score probability [0.0 - 1.0]\",\n        ),\n    ],\n    online=True,\n    source=transactions_batch_source,\n    tags={\n        \"team\": \"fraud-ml\",\n        \"tier\": \"tier-1-prod\",\n        \"online_store\": \"redis_cluster\",\n        \"batch_store\": \"snowflake_gold\",\n        \"sla\": \"sub-2ms\",\n    },\n)`\n\nconst pythonLines = computed(() => pythonFeastSource.split('\\n'))\n\nconst filteredFeatures = computed(() => {\n  const query = searchQuery.value.trim().toLowerCase()\n  return features.filter((f) => {\n    const matchesSearch =\n      !query ||\n      f.name.toLowerCase().includes(query) ||\n      f.description.toLowerCase().includes(query) ||\n      f.onlineCacheKey.toLowerCase().includes(query) ||\n      f.dtype.toLowerCase().includes(query)\n    const matchesType = selectedType.value === 'all' || f.dtype === selectedType.value\n    return matchesSearch && matchesType\n  })\n})\n\nfunction escapeHtml(str: string): string {\n  return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\nfunction highlightPythonLine(line: string): string {\n  if (!line.trim()) return '&nbsp;'\n  const escaped = escapeHtml(line)\n\n  // Comments\n  if (/^\\s*#/.test(escaped)) {\n    return `<span class=\"text-neutral-500 italic\">${escaped}</span>`\n  }\n\n  // Each emitted <span> is parked behind a letter-only placeholder so a later\n  // pass cannot match inside markup an earlier pass produced.\n  const parked: string[] = []\n  const park = (html: string) => {\n    const key = String(parked.length)\n      .split('')\n      .map((d) => String.fromCharCode(97 + Number(d)))\n      .join('')\n    parked.push(html)\n    return `\\u0000${key}\\u0000`\n  }\n\n  let res = escaped\n\n  // Strings\n  res = res.replace(/([\"'])(?:(?=(\\\\?))\\2.)*?\\1/g, (match) =>\n    park(`<span class=\"text-success font-normal\">${match}</span>`),\n  )\n\n  // Keywords\n  res = res.replace(\n    /\\b(from|import|def|class|return|as|True|False|None|with|for|in|and|or|not|is|if|else|elif)\\b/g,\n    (m) => park(`<span class=\"text-chart-1 font-semibold\">${m}</span>`),\n  )\n\n  // Types / Feast Classes\n  res = res.replace(\n    /\\b(Entity|FeatureView|Field|SnowflakeSource|BatchSource|ValueType|Float64|Int32|String|timedelta)\\b/g,\n    (m) => park(`<span class=\"text-warning font-medium\">${m}</span>`),\n  )\n\n  // Arguments\n  res = res.replace(\n    /\\b(name|value_type|join_keys|description|database|schema|table|timestamp_field|created_timestamp_column|entities|ttl|dtype|online|source|tags|days)\\b(?=\\s*=)/g,\n    (m) => park(`<span class=\"text-info\">${m}</span>`),\n  )\n\n  // Numbers\n  res = res.replace(/\\b(\\d+)\\b/g, (m) => park(`<span class=\"text-warning font-medium\">${m}</span>`))\n\n  // Restore every parked span\n  return res.replace(/\\u0000([a-j]+)\\u0000/g, (_, key: string) => {\n    const idx = Number(\n      key\n        .split('')\n        .map((c: string) => String(c.charCodeAt(0) - 97))\n        .join(''),\n    )\n    return parked[idx] ?? ''\n  })\n}\n\nfunction copyToClipboard(text: string, type: 'code' | 'key', keyName?: string) {\n  if (typeof navigator !== 'undefined' && navigator.clipboard) {\n    navigator.clipboard.writeText(text)\n    if (type === 'code') {\n      copiedFeast.value = true\n      setTimeout(() => {\n        copiedFeast.value = false\n      }, 2000)\n    } else if (type === 'key' && keyName) {\n      copiedKey.value = keyName\n      setTimeout(() => {\n        copiedKey.value = null\n      }, 2000)\n    }\n  }\n}\n\nfunction handleMaterialize() {\n  if (isMaterializing.value) return\n  isMaterializing.value = true\n  materializeSuccess.value = false\n\n  setTimeout(() => {\n    isMaterializing.value = false\n    materializeSuccess.value = true\n    setTimeout(() => {\n      materializeSuccess.value = false\n    }, 3000)\n  }, 1200)\n}\n\nfunction handleGenerateDataset() {\n  if (isGeneratingDataset.value) return\n  isGeneratingDataset.value = true\n  datasetSuccess.value = false\n\n  setTimeout(() => {\n    isGeneratingDataset.value = false\n    datasetSuccess.value = true\n    setTimeout(() => {\n      datasetSuccess.value = false\n    }, 3000)\n  }, 1000)\n}\n</script>\n\n<template>\n  <div\n    data-slot=\"feature-store-registry\"\n    :class=\"\n      cn(\n        'bg-background text-foreground border-border flex w-full flex-col overflow-hidden rounded-xl border shadow-xs',\n        props.class,\n      )\n    \"\n  >\n    <!-- TOP FEATURE VIEW HEADER -->\n    <header class=\"border-border bg-card/70 border-b px-4 py-4 sm:px-6\">\n      <div class=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n        <!-- Left: Title, Entity, Stores -->\n        <div class=\"flex flex-wrap items-center gap-3\">\n          <div class=\"bg-primary/10 text-primary flex size-10 items-center justify-center rounded-lg shadow-xs\">\n            <Cpu class=\"size-5\" />\n          </div>\n\n          <div class=\"flex flex-col gap-1\">\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <span class=\"text-muted-foreground font-mono text-xs\">feature_view /</span>\n              <h1 class=\"text-foreground font-mono text-base font-bold tracking-tight break-all sm:text-lg\">\n                user_30d_transaction_aggregates\n              </h1>\n              <Badge wrap variant=\"outline\" class=\"font-mono text-xs font-normal\">v2.4.0</Badge>\n            </div>\n\n            <!-- Metadata Badges Strip -->\n            <div class=\"flex flex-wrap items-center gap-2 pt-0.5\">\n              <!-- Entity Pill -->\n              <div\n                class=\"border-border bg-muted/40 text-foreground inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 font-mono text-xs\"\n              >\n                <Key class=\"text-primary size-3\" />\n                <span class=\"text-muted-foreground\">Entity:</span>\n                <span class=\"font-semibold\">user_id</span>\n                <span class=\"text-muted-foreground\">[UUID]</span>\n              </div>\n\n              <!-- Online Store Pill -->\n              <div\n                class=\"border-success/30 bg-success/10 text-success inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 font-mono text-xs font-medium\"\n              >\n                <span class=\"bg-success size-1.5 animate-pulse rounded-full\" />\n                <span>Redis Cluster · &lt; 2ms latency</span>\n              </div>\n\n              <!-- Batch Store Pill -->\n              <div\n                class=\"border-info/30 bg-info/10 text-info inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 font-mono text-xs font-medium\"\n              >\n                <Database class=\"text-info size-3\" />\n                <span>Snowflake Gold DW</span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Right: Action Buttons -->\n        <div class=\"flex flex-wrap items-center gap-2\">\n          <!-- Generate Training Dataset Button -->\n          <Button\n            aria-label=\"Download attachment\"\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-9 gap-1.5 text-xs font-medium shadow-none\"\n            :disabled=\"isGeneratingDataset\"\n            @click=\"handleGenerateDataset\"\n          >\n            <Loader2 v-if=\"isGeneratingDataset\" class=\"size-3.5 animate-spin\" />\n            <Check v-else-if=\"datasetSuccess\" class=\"text-success size-3.5\" />\n            <Download v-else class=\"size-3.5\" />\n            <span>{{\n              isGeneratingDataset\n                ? 'Building Parquet...'\n                : datasetSuccess\n                  ? 'Dataset Exported (14.2 MB)'\n                  : 'Generate Training Dataset'\n            }}</span>\n          </Button>\n\n          <!-- Materialize Online Features Button -->\n          <Button\n            variant=\"default\"\n            size=\"sm\"\n            class=\"bg-primary text-primary-foreground hover:bg-primary/90 h-9 gap-1.5 text-xs font-semibold shadow-xs\"\n            :disabled=\"isMaterializing\"\n            @click=\"handleMaterialize\"\n          >\n            <Loader2 v-if=\"isMaterializing\" class=\"size-3.5 animate-spin\" />\n            <Check v-else-if=\"materializeSuccess\" class=\"text-success size-3.5\" />\n            <Zap v-else class=\"size-3.5 fill-current\" />\n            <span>{{\n              isMaterializing\n                ? 'Syncing to Redis...'\n                : materializeSuccess\n                  ? 'Materialized 18.4k Keys!'\n                  : 'Materialize Online Features'\n            }}</span>\n          </Button>\n        </div>\n      </div>\n    </header>\n\n    <!-- 4 FEATURE STORE METRIC CARDS -->\n    <div class=\"border-border bg-muted/15 border-b p-4 sm:p-6\">\n      <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n        <Card\n          v-for=\"metric in metrics\"\n          :key=\"metric.title\"\n          class=\"border-border bg-card hover:bg-muted/30 shadow-none transition-colors\"\n        >\n          <CardContent class=\"flex flex-col justify-between gap-3 p-4\">\n            <div class=\"flex items-center justify-between\">\n              <span class=\"text-muted-foreground text-xs font-medium\">{{ metric.title }}</span>\n              <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                <component :is=\"metric.icon\" class=\"size-3.5\" />\n              </div>\n            </div>\n\n            <div>\n              <div class=\"text-foreground font-mono text-xl font-bold tracking-tight\">\n                {{ metric.value }}\n              </div>\n              <div class=\"flex items-center justify-between pt-1 text-xs\">\n                <span class=\"text-muted-foreground truncate\">{{ metric.subtitle }}</span>\n                <Badge wrap variant=\"secondary\" class=\"ml-1 shrink-0 font-mono text-xs font-normal\">\n                  {{ metric.badge }}\n                </Badge>\n              </div>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n    </div>\n\n    <!-- MAIN TABS STUDIO -->\n    <div class=\"flex flex-1 flex-col\">\n      <Tabs v-model=\"activeTab\" default-value=\"features\" class=\"flex flex-1 flex-col\">\n        <!-- Tabs Bar -->\n        <div\n          class=\"border-border bg-card flex flex-wrap items-center justify-between gap-3 border-b px-4 py-2.5 sm:px-6\"\n        >\n          <TabsList class=\"grid h-9 grid-cols-3\">\n            <TabsTrigger value=\"features\" class=\"gap-1.5 text-xs\">\n              <Table2 class=\"text-primary size-3.5\" />\n              <span>Feature Definitions</span>\n              <Badge wrap variant=\"secondary\" class=\"ml-1 h-4 px-1 font-mono text-xs\">{{ features.length }}</Badge>\n            </TabsTrigger>\n            <TabsTrigger value=\"python-feast\" class=\"gap-1.5 text-xs\">\n              <Code2 class=\"text-warning size-3.5\" />\n              <span>Feast Definition</span>\n            </TabsTrigger>\n            <TabsTrigger value=\"lineage\" class=\"gap-1.5 text-xs\">\n              <Workflow class=\"text-info size-3.5\" />\n              <span>Lineage & Architecture</span>\n            </TabsTrigger>\n          </TabsList>\n\n          <div class=\"flex items-center gap-2\">\n            <Badge wrap variant=\"outline\" class=\"text-success gap-1 font-mono text-xs\">\n              <ShieldCheck class=\"size-3\" />\n              <span>Redis Online Serving: ACTIVE</span>\n            </Badge>\n          </div>\n        </div>\n\n        <!-- TAB 1: FEATURE DEFINITIONS TABLE -->\n        <TabsContent value=\"features\" class=\"m-0 flex flex-1 flex-col space-y-5 p-4 sm:p-6\">\n          <!-- Filter / Search Controls -->\n          <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <div class=\"relative w-full sm:w-72\">\n                <Search class=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n                <Input\n                  v-model=\"searchQuery\"\n                  placeholder=\"Filter by feature name, type, or cache key...\"\n                  class=\"h-8 pl-8 font-mono text-xs\"\n                />\n              </div>\n\n              <!-- Type filter pills -->\n              <div class=\"flex items-center gap-1\">\n                <button\n                  v-for=\"t in ['all', 'Float64', 'Int32', 'String'] as const\"\n                  :key=\"t\"\n                  type=\"button\"\n                  :class=\"\n                    cn(\n                      'cursor-pointer rounded-md px-2 py-1 font-mono text-xs transition-colors',\n                      selectedType === t\n                        ? 'bg-primary text-primary-foreground font-medium shadow-xs'\n                        : 'bg-muted/50 text-muted-foreground hover:bg-muted hover:text-foreground',\n                    )\n                  \"\n                  @click=\"selectedType = t\"\n                >\n                  {{ t === 'all' ? 'All Types' : t }}\n                </button>\n              </div>\n            </div>\n\n            <div class=\"text-muted-foreground flex items-center gap-2 font-mono text-xs\">\n              <span>Showing {{ filteredFeatures.length }} of {{ features.length }} features</span>\n            </div>\n          </div>\n\n          <!-- Feature Definitions Table -->\n          <Card class=\"border-border overflow-hidden border shadow-none\">\n            <div class=\"overflow-x-auto\">\n              <Table>\n                <TableHeader>\n                  <TableRow class=\"bg-muted/40 hover:bg-muted/40\">\n                    <TableHead class=\"text-xs font-semibold\">Feature Name & Type</TableHead>\n                    <TableHead class=\"text-xs font-semibold\">Description & Aggregation Window</TableHead>\n                    <TableHead class=\"text-xs font-semibold\">Online Cache Key (Redis)</TableHead>\n                    <TableHead class=\"text-xs font-semibold\">Freshness</TableHead>\n                    <TableHead class=\"text-xs font-semibold\">Status</TableHead>\n                  </TableRow>\n                </TableHeader>\n                <TableBody>\n                  <TableRow v-for=\"feature in filteredFeatures\" :key=\"feature.name\" class=\"text-xs\">\n                    <!-- Feature Name & Type -->\n                    <TableCell class=\"font-mono\">\n                      <div class=\"space-y-1\">\n                        <div class=\"text-foreground font-semibold tracking-tight\">\n                          {{ feature.name }}\n                        </div>\n                        <Badge\n                          wrap\n                          variant=\"secondary\"\n                          :class=\"\n                            cn(\n                              'font-mono text-xs font-normal',\n                              feature.dtype === 'Float64' && 'border-warning/20 bg-warning/10 text-warning border',\n                              feature.dtype === 'Int32' && 'border-info/20 bg-info/10 text-info border',\n                              feature.dtype === 'String' && 'border-chart-1/20 bg-chart-1/10 text-chart-1 border',\n                            )\n                          \"\n                        >\n                          {{ feature.dtype }}\n                        </Badge>\n                      </div>\n                    </TableCell>\n\n                    <!-- Description & Aggregation Window -->\n                    <TableCell class=\"max-w-[280px]\">\n                      <div class=\"space-y-1\">\n                        <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                          {{ feature.description }}\n                        </p>\n                        <Badge wrap variant=\"outline\" class=\"gap-1 font-mono text-xs font-normal\">\n                          <Clock class=\"text-muted-foreground size-2.5\" />\n                          {{ feature.aggregationWindow }}\n                        </Badge>\n                      </div>\n                    </TableCell>\n\n                    <!-- Online Cache Key -->\n                    <TableCell>\n                      <button\n                        type=\"button\"\n                        class=\"border-border/80 bg-muted/60 hover:bg-muted hover:border-primary/40 text-foreground group inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 font-mono text-xs transition-colors\"\n                        title=\"Click to copy Redis key\"\n                        @click=\"copyToClipboard(feature.onlineCacheKey, 'key', feature.name)\"\n                      >\n                        <span class=\"text-primary font-semibold\">GET</span>\n                        <span>{{ feature.onlineCacheKey }}</span>\n                        <Check v-if=\"copiedKey === feature.name\" class=\"text-success size-3 transition-transform\" />\n                        <Copy v-else class=\"text-muted-foreground size-3 opacity-60 group-hover:opacity-100\" />\n                      </button>\n                    </TableCell>\n\n                    <!-- Freshness / Last Synced -->\n                    <TableCell class=\"text-muted-foreground font-mono whitespace-nowrap\">\n                      <div class=\"flex items-center gap-1.5\">\n                        <Clock class=\"text-success size-3\" />\n                        <span>{{ feature.freshness }}</span>\n                      </div>\n                    </TableCell>\n\n                    <!-- Feature Status -->\n                    <TableCell class=\"whitespace-nowrap\">\n                      <Badge\n                        wrap\n                        variant=\"outline\"\n                        class=\"border-success/30 bg-success/10 text-success gap-1.5 font-mono text-xs font-medium\"\n                      >\n                        <span class=\"bg-success size-1.5 rounded-full\" />\n                        {{ feature.status }}\n                      </Badge>\n                    </TableCell>\n                  </TableRow>\n                </TableBody>\n              </Table>\n            </div>\n          </Card>\n\n          <!-- Interactive Entity Live Feature Vector Inspector -->\n          <Card class=\"border-border bg-card/60 space-y-4 border p-4 shadow-none sm:p-5\">\n            <div\n              class=\"border-border/80 flex flex-col gap-2 border-b pb-3 sm:flex-row sm:items-center sm:justify-between\"\n            >\n              <div class=\"flex flex-wrap items-center gap-2\">\n                <Fingerprint class=\"text-primary size-4 shrink-0\" />\n                <span class=\"text-foreground text-xs font-semibold\">Live Online Feature Vector Lookup Simulator</span>\n                <Badge wrap variant=\"secondary\" class=\"font-mono text-xs\">feast.get_online_features()</Badge>\n              </div>\n              <div class=\"flex items-center gap-2\">\n                <span class=\"text-muted-foreground font-mono text-xs\">Target Entity:</span>\n                <span class=\"text-foreground font-mono text-xs font-semibold\">{{ selectedEntityId }}</span>\n              </div>\n            </div>\n\n            <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-5\">\n              <div\n                v-for=\"feature in features\"\n                :key=\"feature.name\"\n                class=\"border-border/70 bg-muted/25 flex flex-col justify-between rounded-lg border p-3\"\n              >\n                <div class=\"space-y-1\">\n                  <span class=\"text-muted-foreground block truncate font-mono text-xs font-medium\">\n                    {{ feature.name }}\n                  </span>\n                  <span class=\"text-muted-foreground text-xs\">{{ feature.aggregationWindow }}</span>\n                </div>\n                <div\n                  class=\"border-border/40 mt-3 flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 border-t pt-2\"\n                >\n                  <span class=\"text-foreground font-mono text-sm font-bold\">{{ feature.sampleValue }}</span>\n                  <span class=\"text-success font-mono text-xs\">&lt; 1.2ms</span>\n                </div>\n              </div>\n            </div>\n          </Card>\n        </TabsContent>\n\n        <!-- TAB 2: PYTHON FEAST DEFINITION CODE BOX -->\n        <TabsContent value=\"python-feast\" class=\"m-0 flex flex-1 flex-col space-y-4 p-4 sm:p-6\">\n          <div class=\"border-border bg-muted/40 overflow-hidden rounded-xl border\">\n            <!-- Code Box Toolbar Header -->\n            <div class=\"border-border bg-card flex items-center justify-between border-b px-4 py-2.5\">\n              <div class=\"flex items-center gap-2\">\n                <div class=\"bg-warning/10 text-warning flex size-6 items-center justify-center rounded\">\n                  <Code2 class=\"size-3.5\" />\n                </div>\n                <span class=\"text-foreground font-mono text-xs font-semibold\">\n                  feature_definitions/user_aggregates.py\n                </span>\n                <Badge wrap variant=\"secondary\" class=\"font-mono text-xs\">Python 3.11 · Feast 0.42+</Badge>\n              </div>\n\n              <Button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"h-7 gap-1.5 text-xs font-medium\"\n                @click=\"copyToClipboard(pythonFeastSource, 'code')\"\n              >\n                <Check v-if=\"copiedFeast\" class=\"text-success size-3\" />\n                <Copy v-else class=\"size-3\" />\n                <span>{{ copiedFeast ? 'Copied Feast Code!' : 'Copy Python Code' }}</span>\n              </Button>\n            </div>\n\n            <!-- Code Gutter and Syntax Highlighter -->\n            <div\n              class=\"relative flex overflow-x-auto bg-neutral-950 font-mono text-xs leading-relaxed text-neutral-100 dark:bg-neutral-950\"\n            >\n              <!-- Line Numbers Gutter -->\n              <div\n                class=\"w-11 shrink-0 overflow-hidden border-r border-neutral-800 bg-neutral-900/60 py-3 pr-2 text-right text-neutral-500 select-none\"\n              >\n                <div v-for=\"(_, idx) in pythonLines\" :key=\"idx\">{{ idx + 1 }}</div>\n              </div>\n\n              <!-- Python Code Content -->\n              <div class=\"flex-1 overflow-x-auto p-3 whitespace-pre select-text\">\n                <div\n                  v-for=\"(line, idx) in pythonLines\"\n                  :key=\"idx\"\n                  class=\"h-5 font-mono leading-5\"\n                  v-html=\"highlightPythonLine(line)\"\n                />\n              </div>\n            </div>\n\n            <!-- Code Footer Meta -->\n            <div\n              class=\"border-border/60 bg-muted/20 text-muted-foreground flex items-center justify-between border-t px-4 py-1.5 font-mono text-xs\"\n            >\n              <div class=\"flex items-center gap-3\">\n                <span>{{ pythonLines.length }} lines</span>\n                <span>·</span>\n                <span>UTF-8</span>\n                <span>·</span>\n                <span>Feast Entity &amp; FeatureView DSL</span>\n              </div>\n              <div class=\"text-success flex items-center gap-1.5\">\n                <CheckCircle2 class=\"size-3.5\" />\n                <span>Valid Feast Schema Contract</span>\n              </div>\n            </div>\n          </div>\n        </TabsContent>\n\n        <!-- TAB 3: STORAGE & LINEAGE ARCHITECTURE -->\n        <TabsContent value=\"lineage\" class=\"m-0 flex flex-1 flex-col space-y-4 p-4 sm:p-6\">\n          <div class=\"grid grid-cols-1 gap-4 lg:grid-cols-2\">\n            <!-- Offline Batch Lineage Card -->\n            <Card class=\"border-border bg-card space-y-3 border p-5 shadow-none\">\n              <div class=\"border-border flex items-center justify-between border-b pb-2.5\">\n                <div class=\"flex items-center gap-2\">\n                  <Database class=\"text-info size-4\" />\n                  <span class=\"text-foreground text-xs font-semibold\">Offline Batch Store Architecture</span>\n                </div>\n                <Badge wrap variant=\"secondary\" class=\"font-mono text-xs\">Snowflake Gold</Badge>\n              </div>\n\n              <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                Immutable historical logs for time-travel queries, training set generation, and AS-OF joins without\n                point-in-time data leakage.\n              </p>\n\n              <div class=\"border-border/60 bg-muted/20 space-y-2 rounded-lg border p-3 font-mono text-xs\">\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Database &amp; Schema:</span>\n                  <span class=\"text-foreground font-semibold\">ANALYTICS_PROD.GOLD_MARTS</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Source Table:</span>\n                  <span class=\"text-foreground font-semibold\">fct_user_transactions_daily</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Timestamp Partition:</span>\n                  <span class=\"text-foreground\">event_timestamp (UTC)</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Historical Depth:</span>\n                  <span class=\"text-foreground\">3 Years (Lookback TTL 30 Days)</span>\n                </div>\n              </div>\n            </Card>\n\n            <!-- Online Low-Latency Cache Card -->\n            <Card class=\"border-border bg-card space-y-3 border p-5 shadow-none\">\n              <div class=\"border-border flex items-center justify-between border-b pb-2.5\">\n                <div class=\"flex items-center gap-2\">\n                  <Zap class=\"text-success size-4\" />\n                  <span class=\"text-foreground text-xs font-semibold\">Online Key-Value Cache Architecture</span>\n                </div>\n                <Badge wrap variant=\"outline\" class=\"border-success/30 text-success font-mono text-xs\">\n                  Redis 7.2 Cluster\n                </Badge>\n              </div>\n\n              <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                Ultra-low latency memory tier providing sub-2 millisecond retrieval for online model inference\n                microservices and fraud scoring.\n              </p>\n\n              <div class=\"border-border/60 bg-muted/20 space-y-2 rounded-lg border p-3 font-mono text-xs\">\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Cluster Topology:</span>\n                  <span class=\"text-foreground font-semibold\">3 Master Shards + 3 Replicas</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Key Prefix Pattern:</span>\n                  <span class=\"text-foreground font-semibold\">user:ft:{feature_name}</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Read SLA (p95):</span>\n                  <span class=\"text-success font-semibold\">&lt; 1.4ms Latency</span>\n                </div>\n                <div class=\"flex justify-between\">\n                  <span class=\"text-muted-foreground\">Materialization Schedule:</span>\n                  <span class=\"text-foreground\">Every 15 mins via Feast Job</span>\n                </div>\n              </div>\n            </Card>\n          </div>\n        </TabsContent>\n      </Tabs>\n    </div>\n  </div>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/FeatureStoreRegistry.vue"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/table.json",
    "https://uipkge.dev/r/vue/tabs.json"
  ],
  "description": "Feast and Tecton style machine learning feature store registry with entity definitions, low-latency Redis online cache status, Snowflake batch source lineage, feature schema inspection table, throughput metrics, and Python Feast feature view code generator.",
  "categories": [
    "ai",
    "app",
    "devops"
  ]
}