PageSourceSearch

https://founder-spark-63.lovable.app/assets/EnterpriseEntityReconciler-CifDZVYQ.js

js founder-spark-63.lovable.app collected 2026-10-03 03:32:55 UTC 11,957 bytes, 3 lines download raw bytes

1import{j as e}from"./query-_koPiPsI.js";import{h as me,r as a}from"./react-vendor-h1rQ_Bae.js";import{s as o,P as he,B as c,L as H,C as v,n as x,o as I,G as xe,p as O,q as Y,I as G,O as pe,k as V,a1 as ge,aF as fe,aG as ye,aH as je,aI as ve,aJ as Ne,g as r}from"./index-Dq2zLArw.js";import{u as we,a as _e,E as be,c as Se}from"./EngineLoopBar-yOmfrlWe.js";import{S as Ce}from"./switch-CyEfQhNS.js";import{W as ke}from"./wand-sparkles-DjjB0AGR.js";import{I as Re}from"./info-DI8_flyN.js";import{T as K}from"./trash-2-DwNrObEE.js";import{C as Ee}from"./circle-play-JCqM3Pnw.js";import{C as Q}from"./copy-BJMOZJfL.js";import"./ui-radix-CKwvnS8F.js";import"./supabase-DL6nu9mS.js";import"./charts-Xu79y1bN.js";import"./motion-nVmI7L5T.js";const Le=(S,d)=>({"@context":"https://schema.org","@type":"Organization",name:S,[d.field]:d.suggested_value??d.value_a??d.value_b??""}),X={high:0,medium:1,low:2};function Me(){const{enabled:S,loading:d}=we(),{lastRun:N,loading:T,save:Z}=_e("entity"),[D]=me(),C=D.get("run_id"),k=D.get("brand_id"),[p,w]=a.useState(""),[R,_]=a.useState(""),[i,g]=a.useState(!1),[z,F]=a.useState(!1),[l,f]=a.useState(null),[ee,E]=a.useState([]),[se,P]=a.useState(null),[te,W]=a.useState(null),[B,J]=a.useState(!1),[u,U]=a.useState(null),[ae,y]=a.useState(null),[m,j]=a.useState(null),[b,ne]=a.useState(null),[L,re]=a.useState(null);a.useEffect(()=>{if(C){f(C),g(!1);return}if(!T)if(N?.run_id){f(N.run_id);const s=N.input??{};s.entity_name&&w(s.entity_name),s.source_url&&_(s.source_url),g(!1)}else g(!0)},[C,T,N]),a.useEffect(()=>{if(!k){W(null);return}(async()=>{const{data:s}=await o.from("brand_properties").select("display_name, domain").eq("id",k).maybeSingle(),t=s;if(t&&(W(t.display_name||t.domain||null),t.display_name&&(ne(t.display_name),w(n=>n||t.display_name)),t.domain)){const n=t.domain.startsWith("http")?t.domain:`https://${t.domain}`;re(n),_(h=>h||n)}})()},[k]),a.useEffect(()=>{if(i||!l)return;const s=async()=>{const[{data:n},{data:h}]=await Promise.all([o.from("entity_reconciliations").select("status, mismatch_detected").eq("id",l).maybeSingle(),o.from("entity_contradictions").select("id,field,source_a,value_a,source_b,value_b,suggested_value,severity,resolved,patch_jsonld,metadata").eq("reconciliation_id",l)]),M=n;y(M?.status??null),j(M?.mismatch_detected??null),E(h??[])};s();const t=setInterval(s,4e3);return()=>clearInterval(t)},[l,i]);const q=i?Se:ee,A=a.useMemo(()=>[...q].sort((s,t)=>(X[s.severity]??3)-(X[t.severity]??3)),[q]),ie=async()=>{if(!p)return r.error("Entity name required");F(!0),j(null),y(null);try{const{data:s,error:t}=await o.functions.invoke("start-entity-scan",{body:{entity_name:p,source_url:R||void 0}});if(t)throw t;if(f(s.reconciliation_id),g(!1),await Z(s.reconciliation_id,{entity_name:p,source_url:R||null}),s.status==="entity_mismatch")j(s.mismatch),y("entity_mismatch"),r.warning("We may have matched the wrong entity — check the banner and rescan.");else{const n=s.contradictions_count??0;r.success(n>0?`Found ${n} contradiction${n===1?"":"s"} — review below.`:"Scan complete — no contradictions detected.")}}catch(s){r.error(s.message??"Failed to start")}finally{F(!1)}},$=async()=>{f(null),E([]),j(null),y(null);try{const{data:s}=await o.auth.getUser();s.user&&await o.from("enterprise_last_runs").delete().eq("user_id",s.user.id).eq("engine","entity")}catch{}r.success("Run discarded. Enter your brand and run again.")},oe=()=>{b&&w(b),L&&_(L),j(null),y(null),f(null),E([]),setTimeout(()=>{const s=document.getElementById("entity-input");s?.scrollIntoView({behavior:"smooth",block:"center"}
1),s?.focus()},100)},ce=async(s,t)=>{const n=`<script type="application/ld+json">
2${JSON.stringify(t,null,2)}
3<\/script>`;await navigator.clipboard.writeText(n),P(s),setTimeout(()=>P(null),1500),r.success("JSON-LD patch copied")},le=async s=>{if(!s.id||i)return;const{error:t}=await o.from("entity_contradictions").update({resolved:!s.resolved}).eq("id",s.id);t&&r.error(t.message)},de=async()=>{if(!l||i){r.error("Run a real scan first");return}J(!0);try{const{data:s,error:t}=await o.functions.invoke("entity-autofix",{body:{reconciliation_id:l}});if(t)throw t;if(!s?.ok)throw new Error(s?.error??"Auto-fix failed");U(s),r.success(`Consolidated ${s.count} contradiction${s.count===1?"":"s"} into one JSON-LD block`)}catch(s){r.error(s.message??"Auto-fix failed")}finally{J(!1)}},ue=async()=>{u&&(await navigator.clipboard.writeText(u.script),r.success("Consolidated JSON-LD copied"))};return d?e.jsx("div",{className:"p-6",children:"Loading…"}):S?e.jsxs("div",{className:"p-6 space-y-6",children:[e.jsxs("header",{children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight",children:"Entity-Graph Reconciler"}),e.jsx("p",{className:"text-muted-foreground",children:"Detect contradictions across Wikipedia, Crunchbase, LinkedIn, and your site — then patch them with structured data."})]}),e.jsx(be,{engine:"entity",brandLabel:te,actions:e.jsxs(c,{size:"sm",variant:"secondary",onClick:de,disabled:B||i,children:[B?e.jsx(H,{className:"w-3 h-3 mr-1 animate-spin"}):e.jsx(ke,{className:"w-3 h-3 mr-1"}),"Auto-fix all"]})}),e.jsx(v,{className:"border-dashed bg-muted/30",children:e.jsxs(x,{className:"py-3 text-xs text-muted-foreground flex gap-2",children:[e.jsx(Re,{className:"w-4 h-4 shrink-0 mt-0.5 text-primary"}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-foreground",children:"How to use:"})," Enter your brand name ",e.jsx("em",{children:"exactly as it appears on your site"})," (e.g. ",e.jsx("em",{children:"ThoughtForge"}),") and paste your site URL. We cross-check facts across Wikipedia, Perplexity-cited sources and your own site. Each contradiction comes with a copy-paste JSON-LD patch — add it to your site's ",e.jsx("code",{children:"<head>"})," and re-scan in 2–3 days. Click ",e.jsx("strong",{children:"Mark done"})," on any row where your site is already correct or you've added the patch. Your last run is remembered."]})]})}),ae==="entity_mismatch"&&m&&!i&&e.jsxs(v,{className:"border-destructive/60 bg-destructive/5",children:[e.jsx(I,{className:"pb-2",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(xe,{className:"w-5 h-5 text-destructive mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(O,{className:"text-lg",children:"Wrong entity matched — rescan needed"}),e.jsxs(Y,{className:"text-sm mt-1",children:["You searched for ",e.jsxs("strong",{children:['"',m.user_entity,'"']})," but public sources returned ",e.jsxs("strong",{children:['"',m.canonical_entity,'"']}),m.canonical_url&&e.jsxs(e.Fragment,{children:[" (",new URL(m.canonical_url).hostname,")"]}),". ",m.reason," No contradictions were saved."]})]})]})}),e.jsxs(x,{className:"flex flex-wrap gap-2",children:[(b||L)&&e.jsxs(c,{size:"sm",onClick:oe,children:["Rescan as ",b??"your brand"]}),e.jsxs(c,{size:"sm",variant:"outline",onClick:$,children:[e.jsx(K,{className:"w-3 h-3 mr-1"})," Discard this run"]})]})]}),e.jsxs(v,{children:[e.jsx(I,{children:e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx(O,{children:"New Reconciliation"}),e.jsx(Y,{children:"We compare canonical facts across public sources and flag mismatches."})]}),l&&!i&&e.jsxs(c,{size:"sm",variant:"ghost",onClick:$,title:"Clear the current run and start fresh",children:[e.jsx(K,{className:"w-3 h-3 mr-1"})," Discard run"]})]})}),e.jsxs(x,{className:"space-y-3",children:[e.jsx(G,{id:"entity-input",placeholder:"Brand name as it appears on your site (e.g. ThoughtForge)",value:p,onChange:s=>w(s.target.value)}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(G,{placeholder:"Your site URL (e.g. https://thoughtforge.app)",value:R,onChange:s=>_(s.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Provide your site URL — we use it to confirm we matched the right entity."})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ce,{id:"sm2",checked:i,onCheckedChange:g}),e.jsx(pe,{htmlFor:"sm2",className:"text-sm",children:"Sample data"})]}),e.jsxs(c,{onClick:ie,disabled:z,children:[z?e.jsx(H,{className:"mr-2 h-4 w-4 animate-spin"}):e.jsx(Ee,{className:"mr-2 h-4 w-4"}),"Run Reconciliation"]})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[A.map((s,t)=>{const n=s.id??`${s.field}-${t}`,h=s.patch_jsonld&&Object.keys(s.patch_jsonld).length>0?s.patch_jsonld:Le(p||"Your Organization",s);return e.jsxs(v,{className:s.resolved?"opacity-60":"",children:[e.jsx(I,{className:"pb-2",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(V,{variant:s.severity==="high"?"destructive":s.severity==="medium"?"default":"secondary",children:s.severity}),e.jsx(O,{className:"text-lg capitalize",children:s.field.replace(/_/g," ")})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(c,{size:"sm",variant:"outline",onClick:()=>ce(n,h),children:[se===n?e.jsx(ge,{className:"mr-1 h-3 w-3"}):e.jsx(Q,{className:"mr-1 h-3 w-3"}),"Copy JSON-LD"]}),!i&&e.jsx(c,{size:"sm",variant:"ghost",onClick:()=>le(s),title:"Hide this row — either you added the patch or your site is already correct",children:s.resolved?"Reopen":"Mark done"})]})]})}),e.jsxs(x,{className:"grid grid-cols-3 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:s.source_a}),e.jsx("div",{className:"font-mono p-2 bg-muted rounded",children:s.value_a||"—"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:s.source_b}),e.jsx("div",{className:"font-mono p-2 bg-muted rounded",children:s.value_b||"—"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground mb-1",children:"Suggested"}),e.jsx("div",{className:"font-mono p-2 bg-primary/10 rounded font-semibold",children:s.suggested_value||"—"})]})]}),e.jsxs(x,{className:"pt-0 space-y-2",children:[s.metadata?.source_url&&e.jsxs("a",{href:s.metadata.source_url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 text-xs text-primary hover:underline",children:[e.jsx(V,{variant:"outline",className:"text-[10px]",children:s.metadata.source_name??"Source"}),e.jsx("span",{className:"truncate max-w-[420px]",children:s.metadata.source_url})]}),s.metadata?.reasoning&&e.jsx("p",{className:"text-xs text-muted-foreground italic",children:s.metadata.reasoning}),e.jsxs("details",{children:[e.jsx("summary",{className:"text-xs text-muted-foreground cursor-pointer",children:"Schema patch"}),e.jsx("pre",{className:"mt-2 text-[10px] bg-muted p-3 rounded overflow-auto",children:JSON.stringify(h,null,2)})]})]})]},n)}),A.length===0&&e.jsx(v,{children:e.jsx(x,{className:"p-6 text-center text-sm text-muted-foreground",children:"No contradictions yet. Toggle sample data or run a scan."})})]}),e.jsx(fe,{open:!!u,onOpenChange:s=>!s&&U(null),children:e.jsxs(ye,{className:"w-[560px] sm:max-w-lg overflow-y-auto",children:[e.jsxs(je,{children:[e.jsx(ve,{children:"Consolidated JSON-LD"}),e.jsxs(Ne,{children:["One Organization block covers ",u?.count??0," unresolved contradiction",u?.count===1?"":"s",". Paste into your site's ",e.jsx("code",{children:"<head>"})," and re-scan."]})]}),e.jsxs("div",{className:"mt-4 space-y-3",children:[e.jsxs(c,{size:"sm",onClick:ue,children:[e.jsx(Q,{className:"w-3 h-3 mr-1"})," Copy script tag"]}),e.jsx("pre",{className:"text-[10px] bg-muted p-3 rounded overflow-auto max-h-[60vh]",children:u?.script??""})]})]})})]}):e.jsxs("div",{className:"p-8 max-w-xl mx-auto text-center space-y-3",children:[e.jsx(he,{className:"mx-auto h-10 w-10 text-muted-foreground"}),e.jsx("h1",{className:"text-2xl font-semibold",children:"Enterprise Only"}),e.jsx("p",{className:"text-muted-foreground",children:"The Entity Reconciler is an Enterprise-tier engine."})]})}
3export{Me as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.