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)
|
||||
*
|
||||
* Match quality:
|
||||
* confidence = 0.85
|
||||
* confidence = 0.85 (starting prior only)
|
||||
* 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";
|
||||
@ -39,13 +48,14 @@ const INSERT_SPEC_MATCHES = `
|
||||
match_basis,
|
||||
match_notes,
|
||||
created_at,
|
||||
updated_at
|
||||
updated_at,
|
||||
re_research_due_at
|
||||
)
|
||||
SELECT DISTINCT
|
||||
fx.id AS flexoptix_id,
|
||||
comp.id AS competitor_id,
|
||||
0.85 AS confidence,
|
||||
'auto_approved' AS status,
|
||||
'pending' AS status,
|
||||
ARRAY['spec'] AS match_basis,
|
||||
'Spec match: ' || fx.form_factor || ' ' || fx.speed_gbps || 'G ' ||
|
||||
CASE WHEN fx.reach_meters <= 300 THEN 'SR'
|
||||
@ -57,7 +67,8 @@ const INSERT_SPEC_MATCHES = `
|
||||
THEN ' @' || tip_extract_wavelength_nm(fx.wavelengths) || 'nm'
|
||||
ELSE '' END AS match_notes,
|
||||
NOW() AS created_at,
|
||||
NOW() AS updated_at
|
||||
NOW() AS updated_at,
|
||||
NOW() AS re_research_due_at
|
||||
FROM transceivers fx
|
||||
JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%'
|
||||
JOIN transceivers comp
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user