shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

scripts/finalize-bulk-top-review.mjs

import fs from "node:fs"
import assert from "node:assert/strict"
import crypto from "node:crypto"
const read=p=>JSON.parse(fs.readFileSync(p,"utf8"))
const sha=p=>crypto.createHash("sha256").update(fs.readFileSync(p)).digest("hex")
const log=fs.readFileSync("reports/swap-validation.log","utf8")
const steps=log.split("\n").flatMap(l=>{try{const x=JSON.parse(l);return x.step?[x]:[]}catch{return []}})
const required=["style-current","physical-regression","protected-copper","tests","stock","bom","typecheck","shorts","check-all","style-cli","warnings","continuity","copper","drill","dfm","solder","kelvin","motor","gerbers","artwork","verify"]
assert.equal(steps.length,required.length,"Full validation must finish before acceptance")
for(const step of required)assert.equal(steps.find(s=>s.step===step)?.exit,0,step)
const circuitSha256=sha("dist/index/circuit.json"),verification=read("verification.json")
assert.equal(verification.circuitSha256,circuitSha256)
assert.equal(verification.fabricationReady,false,"Software gates do not qualify first-article/process concerns")
const style=read("reports/review-style/analysis.json"),warnings=read("reports/review-warning-regression.json")
const continuity=read("reports/connectivity-audit.json"),stock=read("reports/jlcpcb-stock-audit.json")
for(const r of [style,warnings,continuity,stock])assert.equal(r.circuitSha256,circuitSha256)
assert.equal(style.issueCount,0);assert.deepEqual(warnings.errors,[]);assert.deepEqual(warnings.regressions,[])
assert.equal(continuity.sourceFailures,0);assert.equal(continuity.disconnectedTerminalIslands,0)
assert.ok(stock.parts.every(p=>p.status==="in-stock"&&p.orderableStock>=p.requiredForBatch))
const copper=read("reports/coil-all-copper-preflight-meta.json")
assert.equal(copper.circuitSha256,circuitSha256)
assert.equal(copper.physicalCopperSha256,sha("routing/physical-copper.json"));assert.equal(copper.failureCount,0)
assert.deepEqual(read("reports/solder-process-audit.json").ordinaryPadDrillIntersections,[])
const protectedCopper=read("reports/review-protected-copper.json")
assert.deepEqual(protectedCopper.unintendedChanges,[])
const imported=read("routing/swap-import/import-report.json")
assert.deepEqual(imported.failures,[]);assert.equal(imported.physical_island_links,0)
assert.equal(imported.audit_only,false);assert.equal(imported.ignored_protected,false)
const preservedWorkingBoard="../f1c100s-linux-nema17-review-v053-rRqNFa"
const preserved={"routing/complete-routes.json":"460917659b4a3cfb160f1b334ff78536fef03b6e42363ab835ad6f2f83c34d50","routing/expected-input.json":"0f117ece223d388772c79f265f04e432be26b8cb4d69dd278cd97470f14ace11","dist/index/circuit.json":"5ef95a63259bd18f1cdfcebb24f6a98c088edc7676d0ce93965921f5ec596e73"}
for(const [p,s] of Object.entries(preserved))assert.equal(sha(preservedWorkingBoard+"/"+p),s)
assert.match(fs.readFileSync("reports/review-tests.log","utf8"),/54 pass\s+0 fail/)
const report={checkedAt:new Date().toISOString(),status:"local_hardware_and_schematic_regression_gates_passed",circuitSha256,
  capacitorTopRelocationCompleted:true,tvsLayer:"bottom",changedPlacements:read("review-placement.json"),
  sourcePathsImported:imported.paths,testsPassed:54,testsFailed:0,schematicStyleIssues:0,
  nativeErrors:0,inheritedNativeWarnings:warnings.currentWarnings,addedWarnings:0,
  sourceContinuityFailures:0,disconnectedTerminalIslands:0,independentCopperFindings:0,gerberShorts:0,
  ordinaryPadDrillIntersections:0,protectedNetsUnchanged:protectedCopper.protectedNetCount,
  jlcpcbPartCodesChecked:stock.uniquePartCount,populatedParts:stock.populatedComponentCount,
  stockBoardQuantity:stock.boardQuantity,vias:{holeDiameterMm:.3,padDiameterMm:.45,span:"L1-L4 through only"},
  priorWorkingBoardPreserved:true,published:false,fabricationReady:false,
  qualificationGaps:verification.fabricationBlockers,
  reports:Object.fromEntries(["reports/swap-validation.log","reports/review-tests.log","reports/review-style/analysis.json","reports/review-warning-regression.json","reports/bulk-top-regression.json","reports/review-protected-copper.json","reports/connectivity-audit.json","reports/coil-all-copper-preflight-meta.json","reports/jlcpcb-stock-audit.json","reports/bom-validation.json","reports/solder-process-audit.json","reports/drill-clearance-regression.json","verification.json","routing/complete-routes.json","routing/expected-input.json","routing/physical-copper.json"].map(p=>[p,sha(p)]))}
fs.writeFileSync("reports/bulk-top-review-acceptance.json",JSON.stringify(report,null,2)+"\n")
console.log(JSON.stringify(report))