PageSourceSearch

https://getdeplo.com/assets/RepairPage-BVnjUHQs.js

js getdeplo.com collected 2026-10-02 01:31:14 UTC 37,261 bytes, 31 lines download raw bytes

1import{j as e}from"./vendor-xyflow-Bqj2XMRf.js";import{r as c,L as ae}from"./vendor-react-Mx8zmtJs.js";import{g as E,d as Se,e as Re,a3 as j,q as B,X as H,L as U,p as q,j as re,E as ne,A as M,C as Ce,D as Ee,b as Ae,a as Ie}from"./index-C_xpKSSY.js";import{S as Te}from"./SearchableSelect-DRJ0soge.js";import{L as de}from"./loader-circle-D5X8hXw9.js";import{T as C}from"./triangle-alert-D1u4XH4j.js";import{Z as xe}from"./zap-Cn_rsvr4.js";import{R as G}from"./rotate-ccw-CEELEABL.js";import{A as X}from"./arrow-right-ChVVABHC.js";import{C as F}from"./circle-x-CfQdo4D7.js";import{U as _e}from"./user-cog-D6QwnE_u.js";import{G as ze}from"./git-branch-CLBhGT4q.js";import{C as W}from"./circle-check-BSK4rklu.js";/**
2 * @license lucide-react v1.16.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 Pe=[["path",{d:"M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z",key:"kmsa83"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],me=E("circle-play",Pe);/**
7 * @license lucide-react v1.16.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const De=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],Me=E("circle-question-mark",De);/**
12 * @license lucide-react v1.16.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const $e=[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1",key:"tgr4d6"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2",key:"116196"}],["path",{d:"M12 11h4",key:"1jrz19"}],["path",{d:"M12 16h4",key:"n85exb"}],["path",{d:"M8 11h.01",key:"1dfujw"}],["path",{d:"M8 16h.01",key:"18s6g9"}]],Oe=E("clipboard-list",$e);/**
17 * @license lucide-react v1.16.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const Le=[["path",{d:"M13 21h8",key:"1jsn5i"}],["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]],Be=E("pen-line",Le);/**
22 * @license lucide-react v1.16.0 - ISC
23 *
24 * This source code is licensed under the ISC license.
25 * See the LICENSE file in the root directory of this source tree.
26 */const Fe=[["path",{d:"m17 2 4 4-4 4",key:"nntrym"}],["path",{d:"M3 11v-1a4 4 0 0 1 4-4h14",key:"84bu3i"}],["path",{d:"m7 22-4-4 4-4",key:"1wqhfi"}],["path",{d:"M21 13v1a4 4 0 0 1-4 4H3",key:"1rx37r"}]],We=E("repeat",Fe);/**
27 * @license lucide-react v1.16.0 - ISC
28 *
29 * This source code is licensed under the ISC license.
30 * See the LICENSE file in the root directory of this source tree.
31 */const He=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],ie=E("wrench",He),le=new Set(["Account","Contact","Opportunity","Order","OrderItem","Contract","Asset"]);function $(s){return s==null||s===""?"∅":Array.isArray(s)?s.length?s.join(", "):"∅":typeof s=="object"?JSON.stringify(s):String(s).slice(0,200)}function ce({risk:s}){const a=s==="HIGH"?"bg-risk-high/10 text-risk-high border-risk-high/30":s==="MEDIUM"?"bg-risk-medium/10 text-risk-medium border-risk-medium/30":"bg-risk-low/10 text-risk-low border-risk-low/30";return e.jsxs("span",{className:`inline-flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide rounded-full px-2 py-0.5 border ${a}`,children:[s==="HIGH"&&e.jsx(q,{size:10,strokeWidth:2}),s]})}function pe({value:s}){const a=Math.round(s*100),o=a>=80?"bg-green-500":a>=60?"bg-amber-500":"bg-red-500";return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-16 h-1.5 rounded-full bg-surface-2 overflow-hidden",children:e.jsx("div",{className:`h-full ${o}`,style:{width:`${a}%`}})}),e.jsxs("span",{className:"text-[11px] font-mono text-ink-3 tabular-nums",children:[a,"%"]})]})}function Ue({t:s}){const[a,o]=c.useState(!1),l=Object.keys(s.proposedState).filter(m=>JSON.stringify(s.currentState[m])!==JSON.stringify(s.proposedState[m]));return e.jsxs("div",{className:"card overflow-hidden",children:[e.jsxs("button",{type:"button",onClick:()=>o(!a),className:"w-full px-3 py-2.5 flex items-center gap-2 text-left hover:bg-surface-2 transition-colors",children:[a?e.jsx(Ce,{size:12}):e.jsx(Ee,{size:12}),e.jsx("span",{className:"font-medium text-sm text-ink flex-1 truncate",children:s.displayName}),e.jsx("span",{className:"chip text-[10px]",children:s.objectApiName}),e.jsx("span",{className:"text-xs text-ink-4 font-mono",children:s.id}),e.jsxs("span",{className:"text-xs text-ink-4",children:[l.length," field",l.length===1?"":"s"]})]}),a&&e.jsxs("div",{className:"border-t border-default px-3 py-3 bg-surface-2/50",children:[l.length===0?e.jsx("p",{className:"text-xs text-ink-4 italic",children:"No field changes proposed for this record."}):e.jsxs("div",{className:"grid grid-cols-[140px_1fr_auto_1fr] gap-2 text-xs items-center",children:[e.jsx("div",{className:"text-[10px] font-semibold text-ink-3 uppercase tracking-wide",children:"Field"}),e.jsx("div",{className:"text-[10px] font-semibold text-ink-3 uppercase tracking-wide",children:"Current"}),e.jsx("div",{}),e.jsx("div",{className:"text-[10px] font-semibold text-ink-3 uppercase tracking-wide",children:"Proposed"}),l.map(m=>e.jsxs("div",{className:"contents",children:[e.jsx("code",{className:"font-mono text-ink-3 truncate",children:m}),e.jsx("span",{className:"text-ink-3 font-mono truncate",children:$(s.currentState[m])}
31),e.jsx(X,{size:10,className:"text-ink-4"}),e.jsx("span",{className:"text-ink font-mono font-medium truncate",children:$(s.proposedState[m])})]},m))]}),s.fieldHistoryReason&&e.jsxs("p",{className:"mt-3 pt-3 border-t border-default text-[11px] text-ink-3 italic",children:[e.jsx("strong",{className:"font-medium not-italic text-ink-2",children:"Audit reason: "}),s.fieldHistoryReason]})]})]})}const oe={update:{Icon:Be,label:"Update",accent:"border-l-ink-4",chipCls:"bg-surface-2 text-ink-3"},transition:{Icon:X,label:"Transition",accent:"border-l-sky-500",chipCls:"bg-sky-50 text-sky-700 dark:bg-sky-900/30 dark:text-sky-300"},reparent:{Icon:ze,label:"Reparent",accent:"border-l-purple-500",chipCls:"bg-purple-50 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300"},reassign_owner:{Icon:_e,label:"Reassign owner",accent:"border-l-amber-500",chipCls:"bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300"},recall_approval:{Icon:F,label:"Recall approval",accent:"border-l-red-500",chipCls:"bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-300"},reopen_approval:{Icon:We,label:"Submit approval",accent:"border-l-green-500",chipCls:"bg-green-50 text-green-700 dark:bg-green-900/30 dark:text-green-300"}};function qe({a:s}){const a=oe[s.type]??oe.update,o=a.Icon,l=s.type==="recall_approval"||s.type==="reopen_approval";return e.jsxs("div",{className:`card border-l-2 ${a.accent} p-3`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[e.jsx(o,{size:12,strokeWidth:1.8,className:"text-ink-3"}),e.jsx("span",{className:`chip text-[10px] uppercase tracking-wide ${a.chipCls}`,children:a.label}),e.jsxs("span",{className:"font-mono text-xs text-ink-3 truncate flex-1",children:[s.target.objectApiName," / ",s.target.recordId]}),e.jsx(pe,{value:s.confidence})]}),e.jsx("p",{className:"text-xs text-ink-2 leading-relaxed",children:s.rationale}),l&&s.type==="recall_approval"&&e.jsxs("div",{className:"mt-2 flex items-start gap-1.5 text-[11px] text-red-700 dark:text-red-300 bg-red-50/60 dark:bg-red-900/20 rounded px-2 py-1.5",children:[e.jsx(C,{size:11,className:"mt-0.5 shrink-0"}),e.jsx("span",{children:"Not auto-reversible. The original approval routing is lost the moment this runs; rollback can only warn — it can't re-issue the approval automatically."})]}),Object.entries(s.changes).length>0&&e.jsx("div",{className:"mt-2 pt-2 border-t border-default text-[11px] space-y-0.5",children:Object.entries(s.changes).map(([m,h])=>e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("code",{className:"font-mono text-ink-3 w-[140px] shrink-0 truncate",children:m}),e.jsx("span",{className:"font-mono text-ink-3 truncate",children:$(h.before)}),e.jsx(X,{size:9,className:"text-ink-4"}),e.jsx("span",{className:"font-mono text-ink font-medium truncate",children:$(h.after)})]},m))})]})}const Ge=new Set(["ValidationRule","Flow","Trigger"]);function Xe({b:s}){const a=Ge.has(s.metadataType);return e.jsxs("div",{className:"card border-l-2 border-l-amber-500 p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[e.jsx(U,{size:11,strokeWidth:2,className:"text-amber-600 dark:text-amber-400"}),e.jsx("span",{className:"chip text-[10px]",children:s.metadataType}),e.jsx("code",{className:"font-mono text-xs text-ink truncate flex-1",children:s.metadataName}),e.jsx("span",{className:"text-[10px] text-ink-4",children:s.scope.replace(/_/g," ")})]}),e.jsx("p",{className:"text-xs text-ink-2 leading-relaxed",children:s.reason}),!a&&e.jsxs("div",{className:"mt-2 flex items-start gap-1.5 text-[11px] text-ink-3 bg-surface-2 rounded px-2 py-1.5",children:[e.jsx(C,{size:11,className:"mt-0.5 shrink-0 text-ink-4"}),e.jsxs("span",{children:[e.jsx("strong",{children:s.metadataType})," uses the Metadata API — each toggle is a full SF deploy (~15–45s).",s.metadataType==="ApprovalProcess"&&" This deactivates the approval process for ALL records in the org while the repair runs, not just the target. If you only need this record's lock removed, re-plan with a recall_approval action instead.",s.metadataType==="WorkflowRule"&&" Workflow Rules are deprecated by Salesforce — if you have the option, prefer migrating to a Flow."]})]}),e.jsx("p",{className:"mt-1.5 text-[10px] text-ink-4",children:s.restoreAfter?s.scope==="time_bounded"&&s.duration?.seconds?`⏱ Will auto-restore in ${Ve(s.duration.seconds)}. Visible under Pending restorations until then.`:"✓ Will be restored at the end of the repair (this-repair-only scope).":"⚠ Bypass is persistent — admin must re-enable manually."})]})}function Ve(s){if(s<60)return`${s}s`;const a=Math.floor(s/60);if(a<60)return`${a}m`;const o=Math.floor(a/60);if(o<24)return a%60?`${o}h ${a%60}m`:`${o}h`;const l=Math.floor(o/24);return o%24?`${l}d ${o%24}h`:`${l}d`}function Je({e:s}){const a=s.type==="email_sends"?H:s.type==="flow_fires"?xe:s.type==="audit_log_entry"?Oe:C;return e.jsxs("div",{className:"card p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(a,{size:12,strokeWidth:1.8,className:"text-ink-3"}),e.jsx("span",{className:"text-[10px] text-ink-4 uppercase tracking-wide",children:s.type.replace(/_/g," ")}),typeof s.estimatedCount=="number"&&e.jsxs("span",{className:"text-[10px] text-ink-4",children:["~",s.estimatedCount]}),s.reversible?e.jsx(W,{size:11,strokeWidth:2,className:"ml-auto text-green-600"}):e.jsx(C,{size:11,strokeWidth:2,className:"ml-auto text-risk-medium"})]}),e.jsx("p",{className:"text-xs text-ink-2 leading-relaxed",children:s.description})]})}function Qe({s}){return e.jsxs("div",{className:"card p-3 border-l-2 border-l-sky-500",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(G,{size:11,strokeWidth:1.8,className:"text-sky-600 dark:text-sky-400"}),e.jsx("span",{className:"text-[10px] text-ink-4 uppercase tracking-wide",children:"Rollback step"})]}),e.jsx("p",{className:"text-xs text-ink-2 leading-relaxed",children:s.description})]})}function hs(){const{status:s}=Se(),{orgs:a,loading:o}=Re(),[l,m]=c.useState(""),[h,N]=c.useState(""),[d,x]=c.useState(""),[f,u]=c.useState(!1),[i,y]=c.useState(null),[r,g]=c.useState(!1),[b,p]=c.useState(!1),[v,w]=c.useState(null),[A,S]=c.useState(null),[_,I]=c.useState([]),[he,O]=c.useState(!1),[V,J]=c.useState(!1),[Q,Z]=c.useState(""),[Y,K]=c.useState(!1),[T,ee]=c.useState(null),[ue,z]=c.useState(null),[ge,L]=c.useState(null);c.useEffect(()=>{let t=!1;return j.listProposals(10).catch(()=>[]).then(k=>{t||I(k)}),()=>{t=!0}},[]),c.useEffect(()=>{a.length>0&&!l&&m(a[0].id)},[a]);const P=s?.tier??"free",D=a.find(t=>
31t.id===l)??null,be=D?.orgType==="sandbox"||D?.orgType==="developer",se=!(P==="starter"||P==="growth"||P==="inline"),te=P==="starter"&&D!==null&&!be,fe=se||te,ke=!!l&&/^[a-zA-Z0-9]{15}([a-zA-Z0-9]{3})?$/.test(h.trim())&&d.trim().length>=5&&!f&&!fe;async function je(){S(null),u(!0);try{const t=await j.plan({orgId:l,recordId:h.trim(),goal:d.trim()});y(t),re.track(ne.RECORDS_DOCTOR_PLAN_CREATED,{proposalId:t.id,riskScore:t.payload.riskScore,confidence:t.payload.confidence,targetCount:t.payload.targetRecords.length,approvalRequired:t.payload.approvalRequired}),j.listProposals(10).then(I).catch(()=>{})}catch(t){S(t instanceof M?t.message:"Could not generate repair plan."),y(null)}finally{u(!1)}}async function Ne(t){S(null),ee(null);try{const k=await j.getProposal(t);y(k),N(k.payload.targetRecords[0]?.id??""),x(k.payload.goal)}catch{S("Could not load that proposal.")}}function ye(){z(null),L(null),J(!1),Z(""),O(!0)}async function ve(){if(i){z(null),L(null),K(!0);try{const t=await j.execute(i.id,{acknowledgeSensitive:V,confirmText:Q});re.track(ne.RECORDS_DOCTOR_EXECUTED,{proposalId:i.id,finalStatus:t.finalStatus}),ee(t),O(!1);const k=await j.getProposal(i.id);y(k),j.listProposals(10).then(I).catch(()=>{})}catch(t){t instanceof M?(z(t.message),L(t.code??null)):z("Execution failed.")}finally{K(!1)}}}const we=a.map(t=>{const k=t.orgType?` · ${t.orgType}`:"";return{value:t.id,label:`${t.orgName||t.instanceUrl}${k}`,sub:t.instanceUrl}}),n=i?.payload;return e.jsxs("div",{className:"max-w-7xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1.5",children:[e.jsx(B,{size:20,strokeWidth:1.8,className:"text-accent"}),e.jsx("h1",{className:"text-2xl font-bold text-ink",children:"Records Doctor"}),e.jsx("span",{className:"chip chip-accent text-[10px]",children:"new"})]}),e.jsx("p",{className:"text-sm text-ink-3 max-w-2xl",children:"Paste a stuck record ID and describe what you need fixed. Deplo walks the metadata graph, diagnoses what's blocking the change, produces a structured repair plan, and — once you approve — executes the writes with automatic pre-snapshot, rollback-on-failure, and full audit logging."})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1fr_280px] gap-6",children:[e.jsxs("div",{children:[se&&e.jsxs("div",{className:"card mb-5 p-4 flex flex-col sm:flex-row sm:items-center gap-3 border-l-2 border-l-accent",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-semibold text-ink mb-0.5",children:"Records Doctor is a Pro feature"}),e.jsx("p",{className:"text-xs text-ink-3 leading-relaxed",children:"Diagnose stuck records, get an AI-planned fix flow with pre-snapshot + rollback, and approve before any writes touch your org. Pro covers sandbox and developer orgs; Team adds production writes."})]}),e.jsx(ae,{to:"/pricing",className:"btn btn-primary text-xs shrink-0",children:"See plans"})]}),te&&e.jsxs("div",{className:"card mb-5 p-4 flex flex-col sm:flex-row sm:items-center gap-3 border-l-2 border-l-risk-med",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-semibold text-ink mb-0.5",children:"Production writes require the Team plan"}),e.jsxs("p",{className:"text-xs text-ink-3 leading-relaxed",children:["Your Pro plan supports Records Doctor on ",e.jsx("span",{className:"font-medium text-ink",children:"sandbox and developer orgs"}),". ",e.jsx("span",{className:"font-medium text-ink",children:D?.orgName??"The selected org"})," is classified as production by Salesforce. Switch to a sandbox org from the dropdown, or upgrade to Team to enable production writes."]})]}),e.jsx(ae,{to:"/pricing",className:"btn btn-primary text-xs shrink-0",children:"Upgrade to Team"})]}),e.jsxs("div",{className:"card p-5 mb-5",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-[200px_1fr] gap-3 mb-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-ink-3 mb-1.5",children:"Org"}),o?e.jsx("div",{className:"h-9 rounded-md bg-surface-2 animate-pulse"}
31):e.jsx(Te,{options:we,value:l,onChange:m,placeholder:"Select org"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-ink-3 mb-1.5",children:"Record ID"}),e.jsx("input",{type:"text",value:h,onChange:t=>N(t.target.value),placeholder:"0061a00000XXXXXXAAA — paste the stuck record's 15 or 18-char ID",className:"w-full px-3 h-9 rounded-md border border-default bg-surface-1 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-accent/40 focus:border-accent"})]})]}),e.jsxs("div",{className:"mb-3",children:[e.jsx("label",{className:"block text-xs font-medium text-ink-3 mb-1.5",children:"Goal"}),e.jsx("textarea",{value:d,onChange:t=>x(t.target.value),placeholder:'Describe what needs to change, e.g. "Reopen this Opportunity — it was closed by mistake last Friday and the team needs to update the Close Date."',rows:3,className:"w-full px-3 py-2 rounded-md border border-default bg-surface-1 text-sm resize-none focus:outline-none focus:ring-2 focus:ring-accent/40 focus:border-accent"})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("p",{className:"text-[11px] text-ink-4",children:"Planning is read-only — no data changes are applied. AI cost: ~1 Sonnet call per plan."}),e.jsx("button",{type:"button",onClick:je,disabled:!ke,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-accent text-white text-sm font-medium hover:bg-accent-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:f?e.jsxs(e.Fragment,{children:[e.jsx(de,{size:14,className:"animate-spin"})," Planning…"]}):e.jsxs(e.Fragment,{children:[e.jsx(ie,{size:14})," Generate plan"]})})]}),A&&e.jsxs("div",{className:"mt-3 flex items-start gap-2 text-sm text-risk-high bg-risk-high/10 border border-risk-high/20 rounded-md px-3 py-2",children:[e.jsx(C,{size:14,className:"mt-0.5 shrink-0"}),e.jsx("span",{children:A})]})]}),n&&i&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"card p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(ce,{risk:i.risk}),n.targetRecords.length>10&&e.jsxs("span",{className:"chip text-[10px] bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300 inline-flex items-center gap-1",children:[e.jsx(H,{size:9,strokeWidth:2}),"Bulk · ",n.targetRecords.length," records"]}),e.jsx("span",{className:"text-[11px] text-ink-3",children:"confidence"}),e.jsx(pe,{value:i.confidence}),e.jsx("span",{className:"text-[11px] text-ink-3 ml-3",children:"approval"}),e.jsx("span",{className:"chip text-[10px]",children:i.approvalRequired.replace(/_/g," ")}),e.jsx("span",{className:"text-[11px] text-ink-3 ml-3",children:"est."}),e.jsxs("span",{className:"text-[11px] text-ink-2 font-mono",children:[n.estimatedDuration.seconds,"s"]})]}),e.jsx("h2",{className:"text-base font-semibold text-ink mb-2",children:n.summary||"(no summary)"}),n.diagnosis&&e.jsx("div",{className:"text-sm text-ink-2 leading-relaxed border-l-2 border-l-accent/40 pl-3 italic",children:n.diagnosis})]}),n.openQuestions.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(Me,{size:14}),title:"Open questions",count:n.openQuestions.length,variant:"warning"}),e.jsxs("div",{className:"card border-risk-medium/30 bg-risk-medium/5 p-4",children:[e.jsx("ol",{className:"list-decimal pl-5 space-y-1 text-sm text-ink-2",children:n.openQuestions.map((t,k)=>e.jsx("li",{children:t},k))}),e.jsx("p",{className:"mt-3 text-xs text-ink-3",children:"Refine the goal above to answer these, then re-run the plan."})]})]}),n.targetRecords.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(B,{size:14}),title:"Target records",count:n.targetRecords.length}),e.jsx("div",{className:"space-y-2",children:n.targetRecords.map(t=>e.jsx(Ue,{t},t.id))})]}),n.requiredActions.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(ie,{size:14}),title:"Required actions",count:n.requiredActions.length}),e.jsx("div",{className:"space-y-2",children:n.requiredActions.map(t=>e.jsx(qe,{a:t},t.actionId))})]}),n.metadataBypasses.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(U,{size:14}),title:"Metadata bypasses",count:n.metadataBypasses.length,variant:"warning"}),e.jsx("div",{className:"space-y-2",children:n.metadataBypasses.map(t=>e.jsx(Xe,{b:t},t.bypassId))})]}),n.sideEffects.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(xe,{size:14}),title:"Side effects",count:n.sideEffects.length}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-2",children:n.sideEffects.map(t=>e.jsx(Je,{e:t},t.effectId))})]}),n.rollbackPlan.length>0&&e.jsxs("section",{children:[e.jsx(R,{icon:e.jsx(G,{size:14}),title:"Rollback plan",count:n.rollbackPlan.length}),e.jsx("div",{className:"space-y-2",children:n.rollbackPlan.map(t=>e.jsx(Qe,{s:t},t.stepId))})]}),T&&e.jsx(Ye,{result:T}),!T&&i.status==="planned"&&e.jsx("div",{className:"card p-4 border-amber-200 dark:border-amber-800 bg-amber-50/50 dark:bg-amber-900/10",children:e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-start gap-2 min-w-0 flex-1",children:[e.jsx(q,{size:16,strokeWidth:1.8,className:"text-amber-600 dar
31k:text-amber-400 mt-0.5 shrink-0"}),e.jsxs("div",{className:"text-xs text-ink-2 leading-relaxed",children:[e.jsx("strong",{className:"text-ink",children:"Ready to execute."})," ","Clicking Execute will write to Salesforce: ",e.jsxs("strong",{className:"text-ink",children:[n.targetRecords.length," record",n.targetRecords.length===1?"":"s"]}),n.metadataBypasses.length>0&&` + ${n.metadataBypasses.length} metadata bypass${n.metadataBypasses.length===1?"":"es"}`,". Pre-snapshot captures the original state for rollback. All steps logged to the audit trail."]})]}),e.jsxs("button",{type:"button",onClick:ye,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-accent text-white text-sm font-medium hover:bg-accent-hover transition-colors shrink-0",children:[e.jsx(me,{size:14}),"Execute"]})]})}),!T&&i.status!=="planned"&&e.jsxs("div",{className:"card p-3 text-xs text-ink-3",children:["This proposal is in status ",e.jsx("strong",{className:"text-ink",children:i.status}),".",i.status==="executed"&&" All writes applied successfully.",i.status==="rolled_back"&&" An Apply step failed; previously-applied writes were rolled back.",i.status==="failed"&&" Execution halted; check the audit log for details.",i.status==="expired"&&" This proposal is past its 7-day expiry. Generate a fresh plan to retry."," ",e.jsx("button",{type:"button",className:"text-accent hover:underline",onClick:async()=>{const t=!r;if(g(t),t&&v===null&&!b){p(!0);try{w(await j.getAudit(i.id))}catch{w([])}finally{p(!1)}}},children:r?"Hide audit log":"View audit log"})]}),r&&!T&&i.status!=="planned"&&e.jsxs("section",{id:`proposal-${i.id}-audit`,className:"card p-4",children:[e.jsx("p",{className:"text-[11px] font-semibold uppercase tracking-[.08em] text-ink-3 mb-3",children:"Audit Trail"}),b&&e.jsx("p",{className:"text-xs text-ink-3",children:"Loading…"}),!b&&v!==null&&v.length===0&&e.jsx("p",{className:"text-xs text-ink-3",children:"No audit entries recorded for this proposal."}),!b&&v!==null&&v.length>0&&e.jsx("ol",{className:"space-y-2 m-0 p-0 list-none",children:v.map(t=>e.jsxs("li",{className:"flex items-start gap-2.5 text-xs",children:[e.jsx("span",{className:`shrink-0 mt-0.5 px-2 py-0.5 rounded-full text-[10px] font-semibold uppercase tracking-wide ${t.result==="success"?"bg-accent-soft text-accent":t.result==="skipped"?"bg-surface-2 text-ink-3":"bg-risk-high-bg text-risk-high"}`,children:t.phase}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"text-ink-2",children:t.label||t.result}),t.error&&e.jsx("span",{className:"block text-risk-high mt-0.5",children:t.error})]}),e.jsx("span",{className:"shrink-0 text-ink-4 tabular-nums",children:new Date(t.occurredAt).toLocaleTimeString()})]},t.id))})]})]}),he&&i&&n&&e.jsx(Ze,{proposal:i,ackSensitive:V,setAckSensitive:J,confirmText:Q,setConfirmText:Z,executing:Y,error:ue,errorCode:ge,onCancel:()=>!Y&&O(!1),onConfirm:ve}),!i&&!f&&e.jsxs("div",{className:"card p-8 text-center",children:[e.jsx(B,{size:32,strokeWidth:1.5,className:"text-ink-4 mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-ink-3 mb-1",children:"No repair plan yet."}),e.jsxs("p",{className:"text-xs text-ink-4",children:["Paste a record ID and describe the goal above, then click ",e.jsx("strong",{children:"Generate plan"}),"."]})]})]}),e.jsxs("aside",{className:"space-y-4",children:[e.jsxs("div",{className:"card p-4",children:[e.jsx("h3",{className:"text-xs font-semibold text-ink-3 uppercase tracking-wide mb-3",children:"Recent plans"}),_.length===0?e.jsx("p",{className:"text-xs text-ink-4",children:"Nothing yet — your repair plans will show up here."}):e.jsx("ul",{className:"space-y-2",children:_.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>Ne(t.id),className:"w-full text-left p-2 rounded-md hover:bg-surface-2 transition-colors",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-0.5",children:[e.jsx(ce,{risk:t.risk}),e.jsx("span",{className:"text-[10px] text-ink-4",children:t.status})]}),e.jsx("div",{className:"text-xs text-ink truncate",children:t.payload.summary||t.payload.goal}),e.jsx("div",{className:"text-[10px] text-ink-4 mt-0.5",children:new Date(t.createdAt).toLocaleDateString()})]})},t.id))})]}),e.jsx(Ke,{})]})]})]})}
31function R({icon:s,title:a,count:o,variant:l}){return e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("span",{className:l==="warning"?"text-risk-medium":"text-ink-3",children:s}),e.jsx("h3",{className:"text-sm font-semibold text-ink",children:a}),e.jsxs("span",{className:"text-xs text-ink-4",children:["(",o,")"]})]})}function Ze({proposal:s,ackSensitive:a,setAckSensitive:o,confirmText:l,setConfirmText:m,executing:h,error:N,errorCode:d,onCancel:x,onConfirm:f}){const u=s.payload,i=u.targetRecords.some(p=>le.has(p.objectApiName)),y=Array.from(new Set(u.targetRecords.filter(p=>le.has(p.objectApiName)).map(p=>p.objectApiName))),r=s.risk==="HIGH",g=u.targetRecords.length>10,b=!h&&(!i||a)&&(!r||l.trim().toUpperCase()==="EXECUTE");return e.jsx("div",{className:"fixed inset-0 z-50 bg-black/50 flex items-center justify-center p-4",onClick:x,children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-label":"Execute repair",className:"bg-bg border border-default rounded-lg w-full max-w-md p-5 shadow-xl",onClick:p=>p.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(q,{size:16,strokeWidth:2,className:"text-amber-600 dark:text-amber-400"}),e.jsx("h3",{className:"text-base font-semibold text-ink",children:"Execute repair?"})]}),e.jsx("p",{className:"text-xs text-ink-3 leading-relaxed mb-4",children:"This will write to your Salesforce org. The pre-snapshot is captured first so writes are rolled back automatically if any step fails. Disabled validation rules are always re-enabled afterward."}),e.jsxs("div",{className:"space-y-2 mb-4 text-xs",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-3",children:"Records to update"}),e.jsx("span",{className:"font-medium text-ink",children:u.targetRecords.length})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-3",children:"Validation rules to bypass"}),e.jsx("span",{className:"font-medium text-ink",children:u.metadataBypasses.length})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-3",children:"Risk"}),e.jsx("span",{className:`font-medium ${s.risk==="HIGH"?"text-risk-high":s.risk==="MEDIUM"?"text-risk-medium":"text-risk-low"}`,children:s.risk})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-3",children:"Confidence"}),e.jsxs("span",{className:"font-medium text-ink",children:[(s.confidence*100).toFixed(0),"%"]})]})]}),g&&e.jsx("div",{className:"mb-3 text-xs text-ink-2 leading-relaxed p-3 rounded-md border border-amber-200 bg-amber-50/50 dark:border-amber-800 dark:bg-amber-900/10",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(H,{size:14,strokeWidth:1.8,className:"text-amber-600 dark:text-amber-400 mt-0.5 shrink-0"}),e.jsxs("div",{children:[e.jsx("strong",{className:"text-ink",children:"Bulk operation"})," — ",u.targetRecords.length," records. Executor will use Salesforce Composite REST (chunked to 200 per round-trip with allOrNone=true within each chunk). Pre-snapshot + rollback both use bulk reads/writes too. Total runtime roughly ",Math.max(2,Math.ceil(u.targetRecords.length/200)*3),"–",Math.ceil(u.targetRecords.length/200)*15,"s depen
31ding on SF response times.",e.jsx("strong",{className:"block mt-1 text-ink",children:"Requires the Business tier in production (REPAIR_BULK_ENABLED env var server-side)."})]})]})}),i&&e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer text-xs text-ink-2 mb-3 p-3 rounded-md border border-amber-200 bg-amber-50/50 dark:border-amber-800 dark:bg-amber-900/10",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:p=>o(p.target.checked),disabled:h,className:"mt-0.5"}),e.jsxs("span",{children:[e.jsx("strong",{className:"text-ink",children:"I acknowledge"})," this modifies a sensitive object (",y.join(", "),"). I've reviewed the proposed changes and rollback plan above."]})]}),r&&e.jsxs("div",{className:"mb-3",children:[e.jsxs("label",{className:"block text-xs text-ink-3 mb-1.5",children:["This is a HIGH-risk repair. Type ",e.jsx("code",{className:"font-mono text-ink bg-surface-2 px-1 rounded",children:"EXECUTE"})," to confirm:"]}),e.jsx("input",{type:"text",value:l,onChange:p=>m(p.target.value),disabled:h,autoComplete:"off",autoFocus:!0,placeholder:"EXECUTE",className:"w-full px-3 h-9 rounded-md border border-default bg-surface-1 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-accent/40 focus:border-accent disabled:opacity-50"})]}),N&&e.jsxs("div",{className:"mb-3 text-xs text-risk-high bg-risk-high/10 border border-risk-high/20 rounded-md px-3 py-2",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(C,{size:12,className:"mt-0.5 shrink-0"}),e.jsx("span",{children:N})]}),d==="PERMISSION_TIER_INSUFFICIENT"&&e.jsxs("div",{className:"mt-2 pt-2 border-t border-risk-high/20 flex flex-wrap gap-2",children:[e.jsx("a",{href:"/settings?tab=security",target:"_blank",rel:"noreferrer",className:"btn btn-sm flex items-center gap-1",children:"Open workspace settings ↗"}),e.jsx("a",{href:"/orgs",target:"_blank",rel:"noreferrer",className:"btn btn-sm flex items-center gap-1",children:"Open Orgs page ↗"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",disabled:h,onClick:x,className:"btn btn-ghost btn-sm disabled:opacity-50",children:"Cancel"}),e.jsx("button",{type:"button",disabled:!b,onClick:f,className:"flex items-center gap-2 px-4 py-2 rounded-lg bg-accent text-white text-sm font-medium hover:bg-accent-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors",children:h?e.jsxs(e.Fragment,{children:[e.jsx(de,{size:14,className:"animate-spin"})," Executing…"]}):e.jsxs(e.Fragment,{children:[e.jsx(me,{size:14})," Execute now"]})})]})]})})}function Ye({result:s}){const a={pre_snapshot:"Pre-snapshot",bypass:"Bypass",apply:"Apply",rollback:"Rollback",restore:"Restore",verify:"Verify"},o=s.finalStatus==="executed"?"border-green-300 dark:border-green-800 bg-green-50/50 dark:bg-green-900/10":s.finalStatus==="rolled_back"?"border-amber-300 dark:border-amber-800 bg-amber-50/50 dark:bg-amber-900/10":"border-red-300 dark:border-red-800 bg-red-50/50 dark:bg-red-900/10",l=s.finalStatus==="executed"?e.jsx(W,{size:18,className:"text-green-600"}):s.finalStatus==="rolled_back"?e.jsx(G,{size:18,className:"text-amber-600"}):e.jsx(F,{size:18,className:"text-red-600"}),h=["pre_snapshot","bypass","apply","rollback","restore","verify"].map(d=>({phase:d,label:a[d],steps:s.steps.filter(x=>x.phase===d)})).filter(d=>d.steps.length>0),N=new Date(s.finishedAt).getTime()-new Date(s.startedAt).getTime();return e.jsxs("div",{className:`card p-5 border-2 ${o}`,children:[e.jsxs("div",{className:"flex items-start gap-3 mb-3",children:[l,e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm font-semibold text-ink mb-1 capitalize",children:s.finalStatus.replace(/_/g," ")}),e.jsx("div",{className:"text-xs text-ink-2 leading-relaxed",children:s.message}),e.jsxs("div",{className:"text-[10px] text-ink-4 mt-1 font-mono",children:["Attempt ",s.attemptId.slice(0,8)," · ",(N/1e3).toFixed(1),"s"]})]})]}),e.jsx("div",{className:"space-y-3 mt-4 pt-4 border-t border-default",children:h.map(d=>e.jsxs("div",{children:[e.jsxs("div",{className:"text-[10px] font-semibold text-ink-3 uppercase tracking-wide mb-1.5",children:[d.label,e.jsxs("span",{className:"ml-1.5 text-ink-4 font-normal normal-case",children:["(",d.steps.filter(x=>x.status==="success").length,"/",d.steps.length," ok)"]})]}),e.jsx("ul",{className:"space-y-1",children:d.steps.map((x,f)=>e.jsxs("li",{className:"flex items-start gap-1.5 text-xs",children:[x.status==="success"?e.jsx(W,{size:11,className:"mt-0.5 text-green-600 shrink-0"}):x.status==="skipped"?e.jsx(U,{size:11,className:"mt-0.5 text-ink-4 shrink-0"}):e.jsx(F,{size:11,className:"mt-0.5 text-red-600 shrink-0"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:x.status==="failure"?"text-risk-high":"text-ink-2",children:x.label}),x.error&&e.jsx("div",{className:"text-[10px] text-ink-4 italic mt-0.5 break-all",children:x.error})]})]},f))})]},d.phase))})]})}function Ke(){const s=Ae(),{workspaceRole:a}=Ie(),o=a==="admin",[l,m]=c.useState([]),[h,N]=c.useState(!0),[d,x]=c.useState(null);async function f(){try{const r=await j.listPendingRestores(30);m(r)}catch{}finally{N(!1)}}c.useEffect(()=>{f()},[]);async function u(r){if(confirm("Run the restore immediately? This re-enables the bypassed metadata right now and cancels the scheduled auto-restore.")){x(r);try{await j.restoreNow(r),s.success("Restore ran successfully."),await f()}catch(g){s.error(g instanceof M?g.message:"Restore failed.")}finally{x(null)}}}async function i(r){const g=prompt("Cancel reason (optional, will be saved in the audit log):");if(g!==null){x(r);try{await j.cancelRestore(r,g||void 0),s.success("Auto-restore cancelled."),await f()}catch(b){s.error(b instanceof M?b.message:"Could not cancel.")}finally{x(null)}}}const y=l.filter(r=>r.status==="pending"||r.status==="in_progress").length;return e.jsxs("div",{className:"card p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold text-ink-3 uppercase tracking-wide",children:"Pending restorations"}),y>0&&e.jsx("span",{className:"chip chip-accent text-[10px]",children:y})]}),h?e.jsx("div",{className:"text-xs text-ink-4",children:"Loading…"}):l.length===0?e.jsx("p",{className:"text-xs text-ink-4 leading-relaxed",children:"No time-bounded restores in flight. When you run a repair with a time-bounded bypass scope, the scheduled auto-restore will show up here."}):e.jsx("ul",{className:"space-y-2.5",children:l.map(r=>{const g=new Date(r.scheduledAt),b=r.status==="pending",p=r.status==="in_progress",v=r.status==="completed",w=r.status==="failed",A=r.status==="cancelled",S=g.getTime()-Date.now(),_=v?`Completed ${r.completedAt?new Date(r.completedAt).toLocaleStr
31ing():""}`:A?"Cancelled":p?"Running now…":w?`Failed after ${r.attempts} attempt${r.attempts===1?"":"s"}`:S<=0?"Due now (next cron tick)":`Due ${g.toLocaleString()}`,I=v?"text-green-700 dark:text-green-300":w?"text-risk-high":A?"text-ink-4":p?"text-amber-700 dark:text-amber-300":"text-ink-3";return e.jsxs("li",{className:"text-xs",children:[e.jsx("div",{className:"font-mono text-ink truncate mb-0.5",children:r.bypassLabel}),e.jsx("div",{className:`text-[11px] ${I}`,children:_}),r.lastError&&e.jsx("div",{className:"text-[10px] text-risk-high mt-0.5 italic line-clamp-2",title:r.lastError,children:r.lastError}),o&&(b||w)&&e.jsxs("div",{className:"flex gap-1.5 mt-1.5",children:[b&&e.jsx("button",{type:"button",disabled:d===r.id,onClick:()=>void u(r.id),className:"btn btn-ghost btn-sm text-[10px] py-0.5 px-2 disabled:opacity-50",children:d===r.id?"…":"Restore now"}),e.jsx("button",{type:"button",disabled:d===r.id,onClick:()=>void i(r.id),className:"btn btn-ghost btn-sm text-[10px] py-0.5 px-2 text-risk-high disabled:opacity-50",children:"Cancel"})]})]},r.id)})})]})}export{hs 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.