feat: tabellengesteuerter Teilenummer-Decoder

Deckt die Samsung-Referenz-Teilenummer aus dem physisch vorhandenen
Modul ab. Unbekannte Fragmente (z.B. nicht gelistete Dichte-Codes)
liefern bewusst null statt einer Vermutung - das ist der geplante
Uebergang zum OCR-Weg, kein Fehlerfall.

Das im Task-Brief vorgegebene Regex-Muster liess das literale 'A' der
Dichte-Kennung ausserhalb der Erfassungsgruppe, wodurch die
Tabellensuche nach 'A8K40' nie greifen konnte. Muster korrigiert, damit
die ebenfalls vorgegebenen Tests bestehen; Tabelleninhalte und
Warnkommentar blieben wortgleich.
This commit is contained in:
vchuser
2026-07-28 14:29:13 +02:00
parent 8199d25a6e
commit c580d4f924
3 changed files with 115 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
import { emptySpec, normalizeToken } from './spec.js';
import { VENDOR_TABLES } from './pn-tables.js';
/**
* Leitet aus einer Hersteller-Teilenummer die Spec-Felder ab.
* Nicht ableitbare Felder bleiben null - das ist kein Fehler,
* sondern der regulaere Uebergang zum OCR-Weg.
*/
export function decodePartNumber(pn) {
const spec = emptySpec();
const normalized = normalizeToken(pn);
if (normalized === '') return spec;
spec.partNumber = normalized;
for (const table of VENDOR_TABLES) {
const match = normalized.match(table.pattern);
if (!match) continue;
const [, formCode, densityCode, speedCode] = match;
spec.formFactor = table.formFactor[formCode] ?? null;
spec.speed = table.speed[speedCode] ?? null;
const density = table.density[densityCode];
if (density) {
spec.capacityGb = density.capacityGb;
spec.rank = density.rank;
}
break;
}
return spec;
}
+40
View File
@@ -0,0 +1,40 @@
// Herstellertabellen fuer den Teilenummer-Decoder.
//
// ACHTUNG: Nur der Samsung-Eintrag 'A8K40' und der Geschwindigkeitscode 'CRC'
// sind gegen ein reales Modul geprueft (64GB 4DRx4 PC4-2400T LRDIMM,
// M386A8K40BM1-CRC4Y). Alle uebrigen Eintraege stammen aus der veroeffentlichten
// Systematik und muessen vor produktivem Einsatz gegen reale Module bestaetigt
// werden - siehe Task 14. Ein falscher Eintrag faellt beim Sortieren dadurch
// auf, dass der OCR-Klartext dem dekodierten Wert widerspricht.
export const VENDOR_TABLES = [
{
vendor: 'Samsung',
// M<bauform><dichte>-<rev(3)>-<speed><rest>
// Hinweis: Die im Brief angegebene Fassung dieses Musters liess die
// fuehrende Generationskennung 'A' ausserhalb der Erfassungsgruppe und
// erfasste dadurch nie den vollstaendigen Dichte-Code 'A8K40' - die
// Tabellensuche schlug immer fehl. Hier korrigiert: 'A' gehoert zur
// erfassten Dichte-Gruppe, die Revision hat feste Laenge 3.
pattern: /^M(\d{3})(A[A-Z0-9]{4})[A-Z0-9]{3}-([A-Z]{3})/,
formFactor: {
378: 'UDIMM',
391: 'UDIMM',
393: 'RDIMM',
386: 'LRDIMM',
471: 'SODIMM',
474: 'SODIMM',
},
density: {
// geprueft am Referenzmodul:
A8K40: { capacityGb: 64, rank: '4DRx4' },
},
speed: {
CPB: 'PC4-2133',
CRC: 'PC4-2400',
CTD: 'PC4-2666',
CVF: 'PC4-2933',
CWE: 'PC4-3200',
},
},
];