← back to Tk10640 Redirect Prune
rebuild-done-from-live.mjs
30 lines
// TK-10653 — RECOVERY: rebuild done-remediation.jsonl from LIVE Shopify truth.
// For every REPOINT row in remediation-map, read the redirect's current live target by id.
// If it already equals new_target -> it was applied; write a {repointed} done-line.
// This reconstructs the authoritative applied-set after the local done-log was corrupted.
// READ-ONLY on Shopify (only urlRedirect(id) reads); rewrites the LOCAL done-log.
import { readFileSync, writeFileSync } from 'node:fs';
const HOME=process.env.HOME;
const txt=readFileSync(`${HOME}/Projects/secrets-manager/.env`,'utf8');
const env={}; for(const l of txt.split('\n')){const m=l.match(/^([A-Z0-9_]+)=(.*)$/); if(m) env[m[1]]=m[2].replace(/^["']|["']$/g,'');}
const STORE=env.SHOPIFY_STORE_DOMAIN||'designer-laboratory-sandbox.myshopify.com', TOKEN=env.SHOPIFY_FULL_ACCESS_TOKEN, API='2024-10';
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
async function gql(q,v={}){for(let a=0;a<12;a++){try{
const res=await fetch(`https://${STORE}/admin/api/${API}/graphql.json`,{method:'POST',headers:{'Content-Type':'application/json','X-Shopify-Access-Token':TOKEN},body:JSON.stringify({query:q,variables:v})});
const tx=await res.text();let j;try{j=JSON.parse(tx);}catch{await sleep(1200*(a+1));continue;}
if(j.errors){if(/THROTTLED/i.test(JSON.stringify(j.errors))){await sleep(1200*(a+1));continue;}throw new Error(JSON.stringify(j.errors));}
return j.data;
}catch(e){if(a<11){await sleep(1200*(a+1));continue;}throw e;}}}
const rows=readFileSync(`${HOME}/Projects/tk10640-redirect-prune/data/full-scan/remediation-map.jsonl`,'utf8').trim().split('\n').filter(Boolean).map(JSON.parse);
const reps=rows.filter(r=>r.action==='REPOINT');
const out=[]; let applied=0, notyet=0, i=0;
for(const r of reps){
const d=await gql(`query($id:ID!){ urlRedirect(id:$id){ target } }`,{id:r.id});
const cur=d.urlRedirect? d.urlRedirect.target : null;
if(cur===r.new_target){ out.push(JSON.stringify({id:r.id,path:r.path,repointed:r.new_target})); applied++; }
else notyet++;
if(++i%500===0) process.stderr.write(` ${i}/${reps.length} applied=${applied} notyet=${notyet}\n`);
}
writeFileSync(`${HOME}/Projects/tk10640-redirect-prune/data/full-scan/done-remediation.jsonl`, out.join('\n')+(out.length?'\n':''));
console.log(JSON.stringify({repoint_rows:reps.length, live_applied_repoints:applied, not_applied:notyet},null,2));