(category: string)
| 410 | } |
| 411 | |
| 412 | getConsensus(category: string): PatternUsageStats[string] | null { |
| 413 | const categoryPatterns = this.patterns.get(category); |
| 414 | if (!categoryPatterns || categoryPatterns.size === 0) return null; |
| 415 | |
| 416 | const total = Array.from(categoryPatterns.values()).reduce((a, b) => a + b, 0); |
| 417 | const sorted = Array.from(categoryPatterns.entries()).sort((a, b) => b[1] - a[1]); |
| 418 | |
| 419 | const [primaryName, primaryCount] = sorted[0]; |
| 420 | const primaryFreq = Math.round((primaryCount / total) * 100); |
| 421 | const exampleKey = `${category}:${primaryName}`; |
| 422 | const canonicalExample = this.canonicalExamples.get(exampleKey); |
| 423 | |
| 424 | const primaryDate = this.getRobustDate(category, primaryName); |
| 425 | const primaryTrend = calculateTrend(primaryDate); |
| 426 | |
| 427 | let hasRisingAlternative = false; |
| 428 | let alternatives: Array<{ |
| 429 | name: string; |
| 430 | count: number; |
| 431 | frequency: number; |
| 432 | date: Date | undefined; |
| 433 | trend: PatternTrend | undefined; |
| 434 | }> = []; |
| 435 | |
| 436 | if (sorted.length > 1) { |
| 437 | alternatives = sorted.slice(1, 4).map(([name, count]) => { |
| 438 | const altDate = this.getRobustDate(category, name); |
| 439 | const altTrend = calculateTrend(altDate); |
| 440 | const altFreq = Math.round((count / total) * 100); |
| 441 | if (altTrend === 'Rising') hasRisingAlternative = true; |
| 442 | return { name, count, frequency: altFreq, date: altDate, trend: altTrend }; |
| 443 | }); |
| 444 | } |
| 445 | |
| 446 | // Generate actionable guidance from percentage + trend, now aware of rising alternatives |
| 447 | const primaryGuidance = this.generateGuidance( |
| 448 | primaryName, |
| 449 | primaryFreq, |
| 450 | primaryTrend, |
| 451 | false, |
| 452 | hasRisingAlternative |
| 453 | ); |
| 454 | |
| 455 | const result: PatternUsageStats[string] = { |
| 456 | primary: { |
| 457 | name: primaryName, |
| 458 | count: primaryCount, |
| 459 | frequency: `${primaryFreq}%`, |
| 460 | examples: canonicalExample ? [canonicalExample.file] : [], |
| 461 | canonicalExample: canonicalExample, |
| 462 | newestFileDate: primaryDate?.toISOString(), |
| 463 | trend: primaryTrend, |
| 464 | guidance: primaryGuidance |
| 465 | } |
| 466 | }; |
| 467 | |
| 468 | if (alternatives.length > 0) { |
| 469 | result.alsoDetected = alternatives.map((alt) => ({ |
no test coverage detected