feat(vinpin): Renault/Dacia decode akışı (Rpartstore + Dialogys)
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

VINPIN köprüsüne Fiat'ın yanına Renault/Dacia desteği eklendi.

- Marka yönlendirme: selectVinpinBrandFlow(vin) WMI'den akışı seçer
  (Renault/Dacia → Rpartstore/Dialogys, geri kalan → mevcut Fiat ePER,
  Fiat davranışı byte-identical). isVinpinBrandAllowed allowlist'i
  fiat + renault + dacia'ya genişletildi.
- Renault akışı durum-toleranslı: koltuk son katalogu (Rpartstore)
  sunucu-taraflı hatırlayıp açık resume ediyor; ensureRpartstore grid /
  submenu / açık-pencere / yükleniyor durumlarını tanıyıp kendini
  toparlıyor. Rpartstore ana akış, Dialogys best-effort fallback.
- Ortak ensureBrandGrid artık resume olmuş yabancı katalog penceresini
  (Rpartstore/Dialogys/ePER) kapatıp grid'e dönüyor → Renault↔Fiat
  ardışık decode'ları (tek koltuk) artık kırılmıyor.
- parseRenaultHeader/isUsableRenaultParse: OCR başlığından model+marka
  (RENAULT/DACIA) + yıl; bilinen-token allowlist ile contiguous model
  koşusu. Matcher + processor kararlaştırılan markaya göre PL24
  catalog_vehicle eşliyor (Fiat varsayılan korunur).
- Testler: Renault parser + marka-yönlendirme/allowlist birim testleri.

Flag-gated (VINPIN_ENABLED). Canlı doğrulama: 5/5 Renault/Dacia VIN
(Kadjar, Clio II, Clio IV, Dacia Duster, Latitude) doğru decode; Fiat
Egea spot-check korunuyor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 08:44:00 +03:00
parent 24716d03a9
commit 77c93af9a0
7 changed files with 681 additions and 35 deletions

View File

@@ -1,5 +1,10 @@
import { describe, expect, it } from "vitest";
import { isUsableParse, parseVinpinModal } from "./vinpin.parser";
import {
isUsableParse,
isUsableRenaultParse,
parseRenaultHeader,
parseVinpinModal,
} from "./vinpin.parser";
const SAMPLE =
"MVS, найденные по vin NM435600006H43436 6J - TIPO - EGEA (2015-2021) 356G37001162 - 3V HIGH PLUS 1.6 120CV D5 CM E6 GS TR Двигатель: 8165300 Автомобиль: 279476 Prod. date: 2/8/2017 Vin: NM435600006H43436";
@@ -50,3 +55,43 @@ describe("parseVinpinModal", () => {
expect(isUsableParse(p)).toBe(false); // → not a real decode
});
});
describe("parseRenaultHeader", () => {
it("parses an Rpartstore RENAULT header (model + brand)", () => {
const p = parseRenaultHeader("RENAULT KADJAR (RFE) Şasi: VF1RFE00653633190");
expect(p.model).toBe("KADJAR");
expect(p.brand).toBe("RENAULT");
expect(isUsableRenaultParse(p)).toBe(true);
});
it("reads DACIA as the brand when the header carries it", () => {
const p = parseRenaultHeader("DACIA DUSTER (HSA) Şasi: VF1HJD40865644941");
expect(p.model).toBe("DUSTER");
expect(p.brand).toBe("DACIA");
});
it("extracts the base model and ignores the generation numeral (CLIO IV)", () => {
const p = parseRenaultHeader("RENAULT CLIO IV (R0G) Şasi: VF15R0G0H49335605");
expect(p.model).toBe("CLIO");
expect(p.brand).toBe("RENAULT");
});
it("handles a Dialogys header with no explicit brand (defaults RENAULT)", () => {
const p = parseRenaultHeader("Clio II (X65), 1.5 dCi");
expect(p.model).toBe("CLIO");
expect(p.brand).toBe("RENAULT");
});
it("captures a model year when the header carries one", () => {
const p = parseRenaultHeader("RENAULT LATITUDE (2011-2015)");
expect(p.model).toBe("LATITUDE");
expect(p.modelYear).toBe("2011");
});
it("returns no model / unusable for headers without a known token", () => {
const p = parseRenaultHeader("İlişikli araç bulunamadı");
expect(p.model).toBeNull();
expect(isUsableRenaultParse(p)).toBe(false);
expect(isUsableRenaultParse(parseRenaultHeader(""))).toBe(false);
});
});