fix(pl24): detect "bakınız tablo, konum:" reference phrasing too

PL24 translates "see table" two ways — "bk. tablo:" and "bakınız tablo,
konum:". Detection only matched the first, so the latter rows (e.g. evaporator
housing → 820-020) stayed dead. Broaden the name regex to match either, and
strip both phrasings from the displayed label. The code-in-remark gate still
prevents flagging real parts that merely mention "tablo".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 20:20:30 +03:00
parent c440252aa3
commit 642139de9c
2 changed files with 18 additions and 12 deletions

View File

@@ -1471,15 +1471,20 @@ export class CategoriesService {
};
}
// PL24 BOM "bk. tablo:NNN-NNN" rows are cross-references to another
// illustration, not real parts (oem_code "N/A", target code in `remark`).
// Upstream gives us NO navigable link for them — only the text code — so we
// resolve it ourselves: every illustration's code lives in its category name
// as `{NNN-NNN}`, so we build a code→categoryId index for this vehicle and
// attach it. Codes whose target branch hasn't been lazily seeded yet resolve
// to null; the UI then falls back to a pre-filled catalog search.
// PL24 BOM cross-reference rows point to another illustration, not a real part
// (oem_code "N/A", target code in `remark`). Upstream gives us NO navigable
// link — only the text code — so we resolve it ourselves: every illustration's
// code lives in its category name as `{NNN-NNN}`, so we build a code→categoryId
// index for this vehicle and attach it. Codes whose target branch hasn't been
// lazily seeded yet resolve to null; the UI then drills on demand / falls back
// to a pre-filled catalog search.
//
// The "see table" phrasing varies by PL24's own translation: "bk. tablo:" and
// "bakınız tablo, konum:" both occur — match either (the code-in-remark gate
// below keeps this from flagging real parts that merely mention "tablo").
private static readonly REF_CODE_RE = /\d{3}-\d{3}/g;
private static readonly REF_CODE_IN_NAME_RE = /\{(\d{3}-\d{3})\}/g;
private static readonly REF_NAME_RE = /b(?:k\.?|akınız)\s+tablo/i;
// Build a code→categoryId index for a vehicle from the `{NNN-NNN}` illustration
// codes embedded in category names. Reflects only what's been seeded so far.
@@ -1502,7 +1507,7 @@ export class CategoriesService {
rows: T[],
vehicleId: string | null,
): Promise<(T & { references?: Array<{ code: string; categoryId: string | null }> })[]> {
const isRef = (p: T) => p.name?.includes("bk. tablo");
const isRef = (p: T) => CategoriesService.REF_NAME_RE.test(p.name ?? "");
if (!vehicleId || !rows.some(isRef)) return rows;
const index = await this.buildReferenceIndex(vehicleId);

View File

@@ -202,13 +202,14 @@ export function PartsPanel({ parts, vehicleId, categoryId, isLoading }: PartsPan
const isSelected = group != null && selectedGroup === group;
const isUnavailable = part.unavailable === true;
// PL24 "bk. tablo:" cross-reference row — not a real part, but a
// jump to another illustration. Render the target table code(s)
// as navigable links instead of a dead "N/A" OEM cell.
// PL24 cross-reference row ("bk. tablo:" / "bakınız tablo, konum:")
// — not a real part, but a jump to another illustration. Render
// the target table code(s) as navigable links instead of a dead
// "N/A" OEM cell, dropping the "see table" tail from the label.
const refs = part.references;
if (refs && refs.length > 0) {
const label = part.name
.replace(/bk\.\s*tablo:?/i, "")
.replace(/b(?:k\.?|akınız)\s+tablo.*$/is, "")
.replace(/\s*\/\s*$/, "")
.trim();
return (