1import{c as I,g as R,M as q,av as B,s as v,j as e,aw as U,ax as $,ay as F,h as E,k as S,E as V,r as y,D as O,a as Q,b as K,d as z,e as H,I as G,ap as Y,az as J,B as T,ab as X,aA as Z,aB as W,i as ee,n as b,Q as se,R as te,o as w,N as re}from"./index-CyCBd4px.js";import{u as ae}from"./useMutation-eawVkqb6.js";import{R as L,D as ne}from"./counterpartyNormalization-C2i3DpgS.js";import{T as ie}from"./triangle-alert-Bhfo5Tdb.js";import{T as le,a as ce,b as P,c as M}from"./tabs-CRirZm4W.js";import{C as oe}from"./clock-CxyfPBmY.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const de=I("GitMerge",[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M6 21V9a9 9 0 0 0 9 9",key:"7kw0sc"}]]);function ue(){const{currentWorkspace:r}=R(),a=r==null?void 0:r.workspace_id;return q({queryKey:["counterparties",a],enabled:!!a,queryFn:async()=>{const{data:c,error:x}=await v.from("counterparties").select("*").eq("workspace_id",a).is("merged_into_id",null).eq("is_workspace_self",!1).order("legal_name");if(x)throw x;return c||[]}})}function me(r){const{currentWorkspace:a}=R(),c=a==null?void 0:a.workspace_id;return q({queryKey:["counterparty","profile",c,r],enabled:!!c&&!!r,queryFn:async()=>{const[x,p,h,j,u]=await Promise.all([v.from("counterparties").select("*").eq("id",r).maybeSingle(),v.from("counterparty_relationships").select("*").eq("counterparty_id",r).order("confidence",{ascending:!1}),v.from("counterparty_aliases").select("raw_name, normalized_name, created_at").eq("counterparty_id",r).order("created_at",{ascending:!1}),v.from("contracts").select("id, contract_ref, title, status, lifecycle_state, value, currency, start_date, end_date").eq("counterparty_id",r).eq("workspace_id",c),v.from("counterparty_relationship_evidence").select("*, counterparty_relationships!inner(counterparty_id)").eq("counterparty_relationships.counterparty_id",r).order("created_at",{ascending:!1}).limit(50)]);if(x.error)throw x.error;const l=x.data,m=p.data||[],o=h.data||[],d=j.data||[],f=u.data||[],N=d.filter(t=>t.lifecycle_state==="ACTIVE"),_=d.filter(t=>m.some(n=>n.commercial_direction==="revenue")).reduce((t,n)=>t+Number(n.value||0),0),s=d.filter(t=>m.some(n=>n.commercial_direction==="spend")).reduce((t,n)=>t+Number(n.value||0),0),i=d.reduce((t,n)=>t+Number(n.value||0),0);return{counterparty:l,relationships:m,aliases:o,contracts:d,evidence:f,stats:{totalContracts:d.length,activeContracts:N.length,revenueExposure:_,spendExposure:s,totalValue:i,countries:(l==null?void 0:l.countries)||[],riskRating:(l==null?void 0:l.risk_rating)??null,lastActivity:(l==null?void 0:l.last_activity_at)??null}}}})}function xe(){const r=B(),{currentWorkspace:a}=R(),c=a==null?void 0:a.workspace_id;return ae({mutationFn:async x=>{if(!c)throw new Error("No workspace context");const{data:p,error:h}=await v.functions.invoke("merge-counterparty",{body:{workspace_id:c,...x}});if(h)throw h;if(p!=null&&p.error)throw new Error(p.error);return p},onSuccess:()=>{r.invalidateQueries({queryKey:["counterparties",c]}),r.invalidateQueries({queryKey:["counterparty","profile",c]}),r.invalidateQueries({queryKey:["contracts"]})}})}const pe={customer:"bg-emerald-500/10 text-emerald-600 border-emerald-500/30",vendor:"bg-orange-500/10 text-orange-600 border-orange-500/30",partner:"bg-sky-500/10 text-sky-600 border-sky-500/30",affiliate:"bg-indigo-500/10 text-indigo-600 border-indigo-500/30",government:"bg-purple-500/10 text-purple-600 border-purple-500/30",internal:"bg-muted text-muted-foreground border-border",unknown:"bg-muted/60 text-muted-foreground border-border/60"},he={signature_block:"Signature block",party_definition:"Party definition",invoice_metadata:"Invoice metadata",payment_clause:"Payment clause",commercial_clause:"Commercial clause",manual_override:"Manual override",backfill:"Historical backfill",import:"Imported"};function fe({relationship:r,direction:a,confidence:c,evidenceCount:x,lastVerifiedAt:p,topEvidence:h,size:j="sm"}){const u=r||"unknown",l=a||"neutral",m=c!=null?Math.round(Number(c)*100):null,o=e.jsxs(S,{variant:"outline",className:`${pe[u]} ${j==="sm"?"text-[10px] px-1.5 py-0":"text-xs"} font-medium cursor-help`,children:[L[u],m!=null&&e.jsxs("span",{className:"ml-1 opacity-70",children:["· ",m,"%"]})]});return e.jsxs(U,{children:[e.jsx($,{asChild:!0,children:e.jsx("span",{className:"inline-flex",children:o})}),e.jsxs(F,{side:"top",className:"w-80 text-xs space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"font-medium text-sm",children:L[u]}),e.jsx("div",{className:"text-muted-foreground",children:ne[l]})]}),m!=null&&e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between text-muted-foreground mb-1",children:[e.jsx("span",{children:"AI confidence"}),e.jsxs("span",{children:[m,"%"]})]}),e.jsx("div",{className:"h-1.5 bg-muted rounded overflow-hidden",children:e.jsx("div",{className:"h-full bg-primary",style:{width:`${m}%`}})})]}),x!=null&&e.jsxs("div",{className:"text-muted-foreground",children:[x," supporting evidence item",x===1?"":"s",p&&e.jsxs(e.Fragment,{children:[" · last verified ",E(p)]})]}),h&&h.length>0&&e.jsx("div",{className:"border-t pt-2 space-y-1.5 max-h-40 overflow-y-auto",children:h.slice(0,3).map((d,f)=>e.jsxs("div",{className:"text-[11px]",children:[e.jsx("div",{className:"font-medium",children:he[d.evidence_type]||d.evidence_type}),d.evidence_snippet&&e.jsxs("div",{className:"text-muted-foreground line-clamp-2",children:['"',d.evidence_snippet,'"']})]},f))})]})]})}function ge({open:r,onOpenChange:a,survivingId:c,survivingName:x}){const{data:p=[]}=ue(),{mutateAsync:h,isPending:j}=xe(),{toast:u}=V(),[l,m]=y.useState(""),[o,d]=y.useState(null),[f,N]=y.useState(""),_=p.filter(i=>i.id!==c).filter(i=>!l||i.legal_name.toLowerCase().includes(l.toLowerCase())),s=async()=>
6{if(o)try{await h({surviving_id:c,merged_id:o,reason:f||void 0}),u({title:"Merged",description:"Counterparty merged. All history is preserved."}),a(!1),d(null),N("")}catch(i){u({variant:"destructive",title:"Merge failed",description:i.message})}};return e.jsx(O,{open:r,onOpenChange:a,children:e.jsxs(Q,{className:"max-w-lg",children:[e.jsxs(K,{children:[e.jsxs(z,{children:["Merge counterparty into ",x]}),e.jsx(H,{children:"Pick a duplicate to merge. Its contracts, obligations, aliases and evidence will be reassigned. A full snapshot is preserved in the merge audit log â nothing is deleted."})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(G,{placeholder:"Search counterpartiesâ¦",value:l,onChange:i=>m(i.target.value)}),e.jsxs("div",{className:"max-h-56 overflow-y-auto border rounded-md divide-y",children:[_.length===0&&e.jsx("div",{className:"p-3 text-sm text-muted-foreground",children:"No other counterparties."}),_.map(i=>e.jsxs("button",{onClick:()=>d(i.id),className:`w-full text-left p-2 text-sm hover:bg-muted ${o===i.id?"bg-primary/10":""}`,children:[e.jsx("div",{className:"font-medium",children:i.legal_name}),i.aliases.length>1&&e.jsxs("div",{className:"text-xs text-muted-foreground truncate",children:["Aliases: ",i.aliases.slice(0,3).join(", ")]})]},i.id))]}),e.jsx(Y,{placeholder:"Reason (optional, recorded in audit log)",value:f,onChange:i=>N(i.target.value),rows:2}),e.jsxs("div",{className:"flex items-start gap-2 text-xs text-muted-foreground bg-muted/50 rounded p-2",children:[e.jsx(ie,{className:"h-3.5 w-3.5 mt-0.5 shrink-0"}),e.jsx("span",{children:"Merges cannot be undone from the UI. The audit log retains a full snapshot for compliance."})]})]}),e.jsxs(J,{children:[e.jsx(T,{variant:"outline",onClick:()=>a(!1),children:"Cancel"}),e.jsx(T,{onClick:s,disabled:!o||j,children:j?"Mergingâ¦":"Merge"})]})]})})}function ve(){const[r,a]=y.useState([]),[c,x]=y.useState([]),[p,h]=y.useState(null),[j,u]=y.useState(!0);y.useEffect(()=>{l(),m()},[]);const l=async()=>{try{const{data:t}=await v.auth.getUser();if(!t.user)return;const{data:n,error:g}=await v.rpc("get_user_permissions",{_user_id:t.user.id,_entity_id:p});if(g)throw g;a(n||[])}catch(t){console.error("Error fetching permissions:",t)}},m=async()=>{var t;try{const{data:n}=await v.auth.getUser();if(!n.user)return;const{data:g,error:C}=await v.rpc("get_user_entities",{_user_id:n.user.id});if(C)throw C;x(g||[]);const A=g==null?void 0:g.find(D=>D.is_primary);h((A==null?void 0:A.entity_id)||((t=g==null?void 0:g[0])==null?void 0:t.entity_id)||null)}catch(n){console.error("Error fetching entities:",n)}finally{u(!1)}},o=t=>r.some(n=>n.permission_name===t);return{permissions:r,entities:c,currentEntity:p,loading:j,hasPermission:o,hasAnyPermission:t=>t.some(n=>o(n)),canAccess:(t,n="view")=>{const g=`${n}_${t}`;return o(g)||o("manage_permissions")},switchEntity:async t=>{h(t);const{data:n}=await v.auth.getUser();if(!n.user)return;const{data:g,error:C}=await v.rpc("get_user_permissions",{_user_id:n.user.id,_entity_id:t});C||a(g||[])},getCurrentEntityName:()=>{const t=c.find(n=>n.entity_id===p);return(t==null?void 0:t.entity_name)||"Unknown Entity"},isAdmin:()=>o("manage_permissions")||o("manage_users"),isPlatformOwner:()=>o("manage_system_settings"),refresh:()=>{l(),m()}}}function Ce(){var _;const{id:r}=X(),{data:a,isLoading:c}=me(r),{isAdmin:x,isPlatformOwner:p}=ve(),[h,j]=y.useState(!1);if(c)return e.jsx("div",{className:"p-8 text-muted-foreground",children:"Loading counterpartyâ¦"});if(!(a!=null&&a.counterparty))return e.jsx("div",{className:"p-8 text-muted-foreground",children:"Counterparty not found."});const{counterparty:u,relationships:l,aliases:m,contracts:o,evidence:d,stats:f}=a,N=x||p;return e.jsxs("div",{className:"p-6 max-w-6xl mx-auto space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(Z,{className:"h-4 w-4"})," Counterparty Registry"]}),e.jsx("h1",{className:"text-3xl font-semibold",children:u.legal_name}),m.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1",children:Array.from(new Set(m.map(s=>
6s.raw_name))).filter(s=>s!==u.legal_name).slice(0,6).map(s=>e.jsx(S,{variant:"secondary",className:"text-[10px]",children:s},s))}),e.jsxs("div",{className:"flex flex-wrap gap-3 text-xs text-muted-foreground",children:[((_=u.countries)==null?void 0:_.length)>0&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(W,{className:"h-3 w-3"})," ",u.countries.join(", ")]}),u.risk_rating&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(ee,{className:"h-3 w-3"})," Risk: ",u.risk_rating]}),f.lastActivity&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(oe,{className:"h-3 w-3"})," Last activity ",E(f.lastActivity)]})]})]}),N&&e.jsxs(T,{variant:"outline",size:"sm",onClick:()=>j(!0),children:[e.jsx(de,{className:"h-4 w-4 mr-1"})," Merge duplicateâ¦"]})]}),e.jsxs(b,{children:[e.jsx(se,{children:e.jsx(te,{className:"text-sm",children:"Relationships"})}),e.jsx(w,{children:l.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No classified relationships yet."}):e.jsx("div",{className:"flex flex-wrap gap-3",children:l.map(s=>e.jsxs("div",{className:"border rounded-md p-3 min-w-[180px]",children:[e.jsx(fe,{relationship:s.relationship_type,direction:s.commercial_direction,confidence:s.confidence,evidenceCount:s.evidence_count,lastVerifiedAt:s.last_verified_at,topEvidence:d.filter(i=>i.relationship_id===s.id).slice(0,3),size:"md"}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1",children:[s.evidence_count," evidence · verified ",E(s.last_verified_at)]})]},s.id))})})]}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3",children:[{label:"Active contracts",value:f.activeContracts},{label:"Total contracts",value:f.totalContracts},{label:"Revenue exposure",value:k(f.revenueExposure)},{label:"Spend exposure",value:k(f.spendExposure)},{label:"Contract value",value:k(f.totalValue)}].map(s=>e.jsx(b,{children:e.jsxs(w,{className:"p-4",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:s.label}),e.jsx("div",{className:"text-lg font-semibold",children:s.value})]})},s.label))}),e.jsxs(le,{defaultValue:"contracts",children:[e.jsxs(ce,{children:[e.jsxs(P,{value:"contracts",children:["Contracts (",o.length,")"]}),e.jsxs(P,{value:"evidence",children:["Evidence (",d.length,")"]}),e.jsxs(P,{value:"aliases",children:["Aliases (",m.length,")"]})]}),e.jsx(M,{value:"contracts",children:e.jsx(b,{children:e.jsx(w,{className:"p-0",children:o.length===0?e.jsx("div",{className:"p-4 text-sm text-muted-foreground",children:"No contracts yet."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-xs text-muted-foreground",children:e.jsxs("tr",{className:"border-b",children:[e.jsx("th",{className:"text-left p-2",children:"Ref"}),e.jsx("th",{className:"text-left p-2",children:"Title"}),e.jsx("th",{className:"text-left p-2",children:"State"}),e.jsx("th",{className:"text-right p-2",children:"Value"})]})}),e.jsx("tbody",{children:o.map(s=>e.jsxs("tr",{className:"border-b hover:bg-muted/40",children:[e.jsx("td",{className:"p-2 font-mono text-xs",children:s.contract_ref}),e.jsx("td",{className:"p-2",children:e.jsx(re,{to:`/contracts/${s.id}`,className:"hover:underline",children:s.title})}),e.jsx("td",{className:"p-2 text-xs",children:s.lifecycle_state}),e.jsx("td",{className:"p-2 text-right",children:s.value?k(s.value,s.currency):"â"})]},s.id))})]})})})}),e.jsx(M,{value:"evidence",children:e.jsx(b,{children:e.jsx(w,{className:"p-4 space-y-2",children:d.length===0?e.jsx("div",{className:"text-sm text-muted-foreground",children:"No evidence recorded."}):d.map(s=>e.jsxs("div",{className:"text-xs border-b pb-2",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"font-medium",children:s.evidence_type}),e.jsxs("span",{className:"text-muted-foreground",children:[E(s.created_at)," · ",Math.round(s.confidence*100),"%"]})]}),s.evidence_snippet&&e.jsxs("div",{className:"text-muted-foreground mt-1",children:['"',s.evidence_snippet,'"']})]},s.id))})})}),e.jsx(M,{value:"aliases",children:e.jsx(b,{children:e.jsx(w,{className:"p-4",children:e.jsx("div",{className:"flex flex-wrap gap-1.5",children:m.map((s,i)=>e.jsx(S,{variant:"outline",className:"text-xs",children:s.raw_name},i))})})})})]}),e.jsx(ge,{open:h,onOpenChange:j,survivingId:u.id,survivingName:u.legal_name})]})}function k(r,a="USD"){if(!r)return"â";try{return new Intl.NumberFormat("en-US",{style:"currency",currency:a,maximumFractionDigits:0}).format(r)}catch{return`${a}
6 ${Math.round(r).toLocaleString()}`}}export{Ce 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.