fix(equivalences): spec-matcher no longer bypasses review
spec-matcher.ts inserted every JOIN match straight into status=auto_approved at a flat confidence=0.85 -- no standard_name check, no fiber_type check, no recent-competitor-price check, none of the discrimination catalog-reconcile.ts uses before auto-approving. That is real ground live: of the 1,455 currently auto_approved spec-basis equivalences, ~19% would fail a recent-price check and ~8% have a conflicting standard_name if re-scored against the rigorous bar (see sql/140 for the one-time reclassification of the existing rows). Fix: spec matches now insert as pending with re_research_due_at=NOW(), so they flow through the same maintenance:re-research-equivalences job (fixed 2026-07-17, sql/139) that already scores catalog-reconcile.ts pending rows -- real evidence-based confidence before anything is served as approved, not a blanket 0.85. opn-matcher.ts is untouched: OPN matches are manufacturer-confirmed ground truth from fx_compatibilities, not a heuristic guess, so blanket auto_approve there remains correct.
This commit is contained in:
parent
723dfe7bdc
commit
e7299ac779
@ -14,9 +14,18 @@
|
|||||||
* - Max 30 competitor matches per FX product (safety cap)
|
* - Max 30 competitor matches per FX product (safety cap)
|
||||||
*
|
*
|
||||||
* Match quality:
|
* Match quality:
|
||||||
* confidence = 0.85
|
* confidence = 0.85 (starting prior only)
|
||||||
* match_basis = '{spec}'
|
* match_basis = '{spec}'
|
||||||
* status = 'auto_approved'
|
* status = 'pending' — unlike OPN matches (manufacturer-confirmed ground
|
||||||
|
* truth), spec matches are a coarse JOIN with no standard_name / fiber_type /
|
||||||
|
* recent-price discrimination, so they route into the same
|
||||||
|
* maintenance:re-research-equivalences pipeline as catalog-reconcile.ts's
|
||||||
|
* pending rows (evaluateEquivalenceResearch(), scheduler.ts) for real
|
||||||
|
* confidence scoring before ever being served as an approved equivalence.
|
||||||
|
* Found live 2026-07-17: of the equivalences this matcher had previously put
|
||||||
|
* straight into 'auto_approved', ~19% failed a recent-competitor-price check
|
||||||
|
* and ~8% had a conflicting standard_name — i.e. real false-positive risk
|
||||||
|
* was going live unreviewed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { pool } from "../utils/db";
|
import { pool } from "../utils/db";
|
||||||
@ -39,13 +48,14 @@ const INSERT_SPEC_MATCHES = `
|
|||||||
match_basis,
|
match_basis,
|
||||||
match_notes,
|
match_notes,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at,
|
||||||
|
re_research_due_at
|
||||||
)
|
)
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
fx.id AS flexoptix_id,
|
fx.id AS flexoptix_id,
|
||||||
comp.id AS competitor_id,
|
comp.id AS competitor_id,
|
||||||
0.85 AS confidence,
|
0.85 AS confidence,
|
||||||
'auto_approved' AS status,
|
'pending' AS status,
|
||||||
ARRAY['spec'] AS match_basis,
|
ARRAY['spec'] AS match_basis,
|
||||||
'Spec match: ' || fx.form_factor || ' ' || fx.speed_gbps || 'G ' ||
|
'Spec match: ' || fx.form_factor || ' ' || fx.speed_gbps || 'G ' ||
|
||||||
CASE WHEN fx.reach_meters <= 300 THEN 'SR'
|
CASE WHEN fx.reach_meters <= 300 THEN 'SR'
|
||||||
@ -57,7 +67,8 @@ const INSERT_SPEC_MATCHES = `
|
|||||||
THEN ' @' || tip_extract_wavelength_nm(fx.wavelengths) || 'nm'
|
THEN ' @' || tip_extract_wavelength_nm(fx.wavelengths) || 'nm'
|
||||||
ELSE '' END AS match_notes,
|
ELSE '' END AS match_notes,
|
||||||
NOW() AS created_at,
|
NOW() AS created_at,
|
||||||
NOW() AS updated_at
|
NOW() AS updated_at,
|
||||||
|
NOW() AS re_research_due_at
|
||||||
FROM transceivers fx
|
FROM transceivers fx
|
||||||
JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%'
|
JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%'
|
||||||
JOIN transceivers comp
|
JOIN transceivers comp
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user