Files
claudetools/projects/dataforth-dos/tools/derive-dsca-templates.js
Mike Swanson 67de39a9d0 dataforth: handoff doc for AD2 session — Fix 2 (DSCA rebuild) STAGE 2-3 + Fix 5 + cleanup
Remote SSH/VPN to AD2 keeps flapping; hand the remaining datasheet fixes to the
local AD2 session. Includes the per-subtype approach (DSCA_TEMPLATES from staged
originals — STAGE 1 done, dsca-templates.json on AD2 = 126 models), the render-wiring
+ per-subtype byte-validation gate, Fix 5 (379 backfill via legacy_cert_text), the
discipline (backup/save-state/validate-before-publish), and the derive-dsca-templates
tool. Ref ticket #32441.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 05:59:05 -07:00

54 lines
3.3 KiB
JavaScript

// Fix 2 STAGE 1 (read-only build): extract per-model DSCA Final-Test templates from staged originals.
// Uses the '===' separator line under the Final-Test header to get exact column spans.
const fs = require('fs'), path = require('path');
const STAGE = 'C:/Shares/test/STAGE';
const OUT = 'C:/Shares/testdatadb/dsca-templates.json';
function walk(d, out) { let it = []; try { it = fs.readdirSync(d, { withFileTypes: true }); } catch { return out; } for (const e of it) { const p = path.join(d, e.name); if (e.isDirectory()) walk(p, out); else if (/\.txt$/i.test(e.name)) out.push(p); } return out; }
function colSpans(sep) { const cols = []; let m; const re = /=+/g; while ((m = re.exec(sep))) cols.push([m.index, m.index + m[0].length]); return cols; }
function extract(t) {
const lines = t.replace(/\r\n/g, '\n').split('\n');
const accHdr = lines.find(l => /Error \(%\)/.test(l) && /Status/.test(l)) || '';
const accOut = (accHdr.match(/Output \((?:V|mA)\)|Vout \(V\)/) || ['?'])[0];
let fi = lines.findIndex(l => /FINAL TEST RESULTS/.test(l)); if (fi < 0) return null;
let hi = -1; for (let i = fi + 1; i < lines.length; i++) { if (/Parameter\s+Measured/.test(lines[i])) { hi = i; break; } } if (hi < 0) return null;
const sep = lines[hi + 1] || ''; if (!/=/.test(sep)) return null;
const cols = colSpans(sep); if (cols.length < 4) return null;
const [pc, mc, sc, stc] = cols;
const rows = [];
for (let i = hi + 2; i < lines.length; i++) {
const l = lines[i];
if (/Check List|^\s*_{5,}/.test(l)) break;
if (!l.trim()) continue;
const name = (l.slice(pc[0], mc[0]) || '').trim();
const spec = (l.slice(sc[0], stc[0]) || '').trim();
if (!name && !spec) continue;
rows.push({ name, spec });
}
return { accOut, rows };
}
(async () => {
const files = walk(STAGE, []);
const byModel = {};
for (const f of files) {
let t; try { t = fs.readFileSync(f, 'utf8'); } catch { continue; }
const model = (t.match(/^\s*Model:\s*(\S+)/m) || [])[1] || '';
if (!/^DSCA/i.test(model)) continue;
const tpl = extract(t); if (!tpl) continue;
// keep the sheet with the MOST rows per model (most complete; avoids truncated samples)
if (!byModel[model] || tpl.rows.length > byModel[model].rows.length) byModel[model] = { ...tpl, sheets: (byModel[model] ? byModel[model].sheets : 0) + 1 };
else byModel[model].sheets++;
}
const models = Object.keys(byModel).sort();
console.log('DSCA models templated: ' + models.length);
const out = {}; for (const m of models) out[m] = { accOut: byModel[m].accOut, rows: byModel[m].rows };
fs.writeFileSync(OUT, JSON.stringify(out));
console.log('wrote ' + OUT + ' (' + fs.statSync(OUT).size + ' bytes)');
const rc = {}; for (const m of models) { const n = byModel[m].rows.length; rc[n] = (rc[n] || 0) + 1; }
console.log('row-count distribution (rows:models): ' + Object.entries(rc).sort((a, b) => a[0] - b[0]).map(([n, c]) => n + ':' + c).join(' '));
for (const probe of ['DSCA38-05', 'DSCA34-01', 'DSCA38-08C', 'DSCA30-01']) {
const s = out[probe];
if (s) { console.log('\n' + probe + ' accOut=' + s.accOut + ' rows=' + s.rows.length); s.rows.forEach(r => console.log(' ' + r.name.padEnd(28) + ' | ' + r.spec)); }
else console.log('\n' + probe + ': NOT FOUND');
}
})().catch(e => { console.error('ERR ' + e.message); });