diff --git a/packages/api/src/hype-cycle/norton-bass.ts b/packages/api/src/hype-cycle/norton-bass.ts index 35fa45f..a501622 100644 --- a/packages/api/src/hype-cycle/norton-bass.ts +++ b/packages/api/src/hype-cycle/norton-bass.ts @@ -458,11 +458,27 @@ export function computeAllHypeCycles( } export function findTechnology(query: string): TechGeneration | undefined { - const q = query.toLowerCase(); + const q = query.toLowerCase().trim(); const allTechs = [...TECH_GENERATIONS, ...SPECIAL_TECHS]; - return allTechs.find((t) => - t.name.toLowerCase().includes(q) || - q.includes(t.speedGbps.toString()) || - q.includes(t.formFactor.toLowerCase()) - ); + + // 1. Exact name match + const exact = allTechs.find((t) => t.name.toLowerCase() === q); + if (exact) return exact; + + // 2. Name contains query or query contains name + const nameMatch = allTechs.find((t) => t.name.toLowerCase().includes(q)); + if (nameMatch) return nameMatch; + + // 3. Fuzzy: match by speed prefix (e.g. "400G", "1.6T", "800G") + const speedMatch = q.match(/^(\d+(?:\.\d+)?)\s*(g|t)\b/i); + if (speedMatch) { + const num = parseFloat(speedMatch[1]); + const unit = speedMatch[2].toLowerCase(); + const targetGbps = unit === "t" ? num * 1000 : num; + const found = allTechs.find((t) => t.speedGbps === targetGbps); + if (found) return found; + } + + // 4. Match by form factor + return allTechs.find((t) => q.includes(t.formFactor.toLowerCase())); }