fix(vinpin): strict not-found for warm-Fiat full-frame garble check
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Review finding: warmDecode's genuine-not-found decision used VINPIN_OCR.notFound (/…|Catalogue/i) against the FULL frame, where the 'Spare Parts Catalogue' header always matches → every on-panel garble was flagged a genuine miss and null'd out instead of falling back to the cold retry. Add notFoundStrict (no Catalogue token) for the full-frame check so a transient on-panel garble (VIN exists) recovers via the cold path; keep notFound for the runVinFlow modal-region settle poll. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -648,7 +648,12 @@ export class VinpinDriverService implements OnModuleDestroy {
|
||||
// just produced garbage isn't trusted; the daemon re-warms next cycle.
|
||||
const frame = await this.ocrFrame(page);
|
||||
const onFiatPanel = VINPIN_OCR.catalogueReady.test(frame);
|
||||
const genuineNotFound = VINPIN_OCR.notFound.test(frame);
|
||||
// STRICT not-found against the FULL frame: `notFound` includes the loose
|
||||
// `Catalogue` token which the "Spare Parts Catalogue" header always matches,
|
||||
// so it would flag EVERY on-panel garble as a genuine miss and null it out.
|
||||
// `notFoundStrict` requires a real "не найден"/"not found" string, letting a
|
||||
// transient on-panel garble (VIN actually exists) fall through to cold retry.
|
||||
const genuineNotFound = VINPIN_OCR.notFoundStrict.test(frame);
|
||||
if (onFiatPanel && genuineNotFound) {
|
||||
this.logger.log(`warm ${vin}: genuine not-found on the Fiat VIN panel → null`);
|
||||
return null;
|
||||
|
||||
@@ -166,8 +166,16 @@ export const VINPIN_OCR = {
|
||||
/** The decode modal actually carries a result (a model / prod-date / MVS). */
|
||||
modalHit:
|
||||
/MVS|найден|Prod\.?\s*date|TIPO|EGEA|DOBLO|PALIO|PANDA|PUNTO|LINEA|DUCATO|QUBO|FIORINO|ULYSSE/i,
|
||||
/** Genuine "no vehicle found" outcome (the catalog has no record). */
|
||||
/** Genuine "no vehicle found" outcome (the catalog has no record). Used against
|
||||
* the cropped decode-modal region in runVinFlow, where the loose `Catalogue`
|
||||
* token is a useful settle signal. */
|
||||
notFound: /не\s*найден|not\s*found|Catalogue/i,
|
||||
/** STRICT genuine not-found — requires an actual "не найден"/"not found" string,
|
||||
* WITHOUT the loose `Catalogue` token. Use this against the FULL frame (where
|
||||
* the "Spare Parts Catalogue" header is always present, so `notFound` would
|
||||
* false-match), e.g. the warm-Fiat genuine-miss-vs-garble decision — so an
|
||||
* on-panel transient garble falls through to the cold retry instead of null. */
|
||||
notFoundStrict: /не\s*найден|not\s*found/i,
|
||||
|
||||
// ─── Renault flow OCR sets ───
|
||||
/** A catalog app window (Rpartstore / Dialogys / Fiat ePER) is open OVER the
|
||||
|
||||
Reference in New Issue
Block a user