@@ -326,6 +326,22 @@ export class V9GroupedReportFormatter {
326326 markdown . push ( '' ) ;
327327 }
328328
329+ // Business Impact Analysis (aggregate from issues)
330+ markdown . push ( this . generateBusinessImpact ( issues , groups ) ) ;
331+ markdown . push ( '' ) ;
332+
333+ // Educational Resources (aggregate from issues)
334+ markdown . push ( this . generateEducationalResources ( issues ) ) ;
335+ markdown . push ( '' ) ;
336+
337+ // Analysis Metadata (performance metrics)
338+ markdown . push ( this . generateAnalysisMetadata ( metadata ) ) ;
339+ markdown . push ( '' ) ;
340+
341+ // PR Comment (personalized, ready-to-paste)
342+ markdown . push ( this . generatePRComment ( issues , groups , metadata ) ) ;
343+ markdown . push ( '' ) ;
344+
329345 // Footer
330346 markdown . push ( this . generateFooter ( groups , attachments , ideFixFiles ) ) ;
331347
@@ -1729,6 +1745,256 @@ ${qualityResult.categoryScores ? `
17291745 } ;
17301746 }
17311747
1748+ /**
1749+ * Generate Business Impact Analysis (simplified for grouped report)
1750+ */
1751+ private generateBusinessImpact ( issues : EnrichedIssue [ ] , groups : IssueGroup [ ] ) : string {
1752+ const critical = issues . filter ( i => i . severity === 'critical' ) ;
1753+ const high = issues . filter ( i => i . severity === 'high' ) ;
1754+ const blocking = issues . filter ( i =>
1755+ ( i . category === 'NEW' || i . category === 'EXISTING_MODIFIED' ) &&
1756+ ( i . severity === 'critical' || i . severity === 'high' )
1757+ ) ;
1758+
1759+ // Calculate risk by category
1760+ const securityIssues = issues . filter ( i => i . detectedCategory === 'Security' ) ;
1761+ const performanceIssues = issues . filter ( i => i . detectedCategory === 'Performance' ) ;
1762+ const reliabilityIssues = issues . filter ( i => i . detectedCategory === 'Reliability' ) ;
1763+
1764+ const immediateRisk = blocking . length > 0 ? 'High' :
1765+ critical . length > 0 ? 'Moderate' : 'Low' ;
1766+
1767+ return `## 💼 Business Impact Analysis
1768+
1769+ ### Executive Summary
1770+ This analysis evaluates the business risks and financial implications of the identified code quality issues.
1771+
1772+ ### Risk Assessment
1773+ - **Immediate Risk:** ${ immediateRisk } (${ blocking . length } blocking issues require attention before deployment)
1774+ - **Future Risk:** ${ critical . length + high . length } issues could lead to increased technical debt if not addressed
1775+
1776+ ### Financial Impact
1777+ | Metric | Value | Explanation |
1778+ |--------|-------|-------------|
1779+ | Fix Cost | ${ Math . ceil ( ( critical . length * 4 + high . length * 2 ) / 8 ) } developer-days | Estimated time to resolve critical and high-severity issues |
1780+ | Potential Exploit Cost | ${ securityIssues . length > 0 ? 'High' : 'Low' } | ${ this . getExploitCostExplanation ( critical . length , high . length , securityIssues . length ) } |
1781+ | Return on Investment | ${ blocking . length > 0 ? '10-50x' : '5-10x' } | Ratio of prevention cost vs potential exploit/incident cost |
1782+
1783+ ### Risk Matrix by Category
1784+ | Category | Critical | High | Total Issues | Impact |
1785+ |----------|----------|------|--------------|--------|
1786+ | Security | ${ securityIssues . filter ( i => i . severity === 'critical' ) . length } | ${ securityIssues . filter ( i => i . severity === 'high' ) . length } | ${ securityIssues . length } | ${ this . getRiskImpactLevel ( securityIssues ) } |
1787+ | Performance | ${ performanceIssues . filter ( i => i . severity === 'critical' ) . length } | ${ performanceIssues . filter ( i => i . severity === 'high' ) . length } | ${ performanceIssues . length } | ${ this . getRiskImpactLevel ( performanceIssues ) } |
1788+ | Reliability | ${ reliabilityIssues . filter ( i => i . severity === 'critical' ) . length } | ${ reliabilityIssues . filter ( i => i . severity === 'high' ) . length } | ${ reliabilityIssues . length } | ${ this . getRiskImpactLevel ( reliabilityIssues ) } |
1789+
1790+ **Note:** Each issue group section above includes detailed business impact analysis specific to that issue type.` ;
1791+ }
1792+
1793+ /**
1794+ * Get exploit cost explanation helper
1795+ */
1796+ private getExploitCostExplanation ( criticalCount : number , highCount : number , securityCount : number ) : string {
1797+ if ( criticalCount > 0 && securityCount > 0 ) {
1798+ return `${ criticalCount } critical security vulnerabilities could lead to data breach, system compromise, or service disruption` ;
1799+ } else if ( highCount > 0 && securityCount > 0 ) {
1800+ return `${ highCount } high-severity security issues could result in security incidents or operational failures` ;
1801+ } else if ( criticalCount > 0 ) {
1802+ return `${ criticalCount } critical issues could cause system instability or reliability problems` ;
1803+ } else {
1804+ return `Low risk of security incidents; main concerns are code quality and maintainability` ;
1805+ }
1806+ }
1807+
1808+ /**
1809+ * Get risk impact level helper
1810+ */
1811+ private getRiskImpactLevel ( categoryIssues : EnrichedIssue [ ] ) : string {
1812+ const critical = categoryIssues . filter ( i => i . severity === 'critical' ) . length ;
1813+ const high = categoryIssues . filter ( i => i . severity === 'high' ) . length ;
1814+
1815+ if ( critical >= 3 ) return '🔴 Critical' ;
1816+ if ( critical >= 1 || high >= 5 ) return '🟠 High' ;
1817+ if ( high >= 2 || categoryIssues . length >= 10 ) return '🟡 Medium' ;
1818+ if ( categoryIssues . length > 0 ) return '🟢 Low' ;
1819+ return '⚪ None' ;
1820+ }
1821+
1822+ /**
1823+ * Generate Educational Resources (aggregate from detected categories)
1824+ */
1825+ private generateEducationalResources ( issues : EnrichedIssue [ ] ) : string {
1826+ const categories = Array . from ( new Set ( issues . map ( i => i . detectedCategory ) . filter ( Boolean ) ) ) ;
1827+
1828+ if ( categories . length === 0 ) {
1829+ return `## 📚 Educational Resources
1830+
1831+ ✅ **No specific educational resources needed at this time.**
1832+
1833+ Your code quality is good! Consider reviewing general best practices to maintain this standard.` ;
1834+ }
1835+
1836+ let content = `## 📚 Educational Resources
1837+
1838+ **Curated learning materials based on your code analysis:**
1839+
1840+ ` ;
1841+
1842+ categories . forEach ( category => {
1843+ const categoryIssues = issues . filter ( i => i . detectedCategory === category ) ;
1844+ content += `### ${ category } (${ categoryIssues . length } issues)\n\n` ;
1845+
1846+ switch ( category ) {
1847+ case 'Security' :
1848+ content += `- [📚 OWASP Top 10](https://owasp.org/www-project-top-ten/) - Essential security vulnerabilities\n` ;
1849+ content += `- [🔒 Secure Coding Practices](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/) - Quick reference guide\n` ;
1850+ content += `- [🎬 Security Fundamentals](https://www.youtube.com/results?search_query=web+application+security+fundamentals) - Video tutorials\n\n` ;
1851+ break ;
1852+ case 'Performance' :
1853+ content += `- [⚡ Performance Best Practices](https://web.dev/performance/) - Web performance guide\n` ;
1854+ content += `- [📖 High Performance Programming](https://pragprog.com/titles/iobgp/high-performance-programming/) - Optimization techniques\n` ;
1855+ content += `- [🔧 Profiling Tools](https://www.baeldung.com/java-profilers) - Performance profiling\n\n` ;
1856+ break ;
1857+ case 'Architecture' :
1858+ content += `- [🏗️ Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) - Architecture principles\n` ;
1859+ content += `- [📚 Design Patterns](https://refactoring.guru/design-patterns) - Common design patterns\n` ;
1860+ content += `- [🎯 SOLID Principles](https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design) - OOD fundamentals\n\n` ;
1861+ break ;
1862+ case 'Dependencies' :
1863+ content += `- [📦 Dependency Management](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) - Maven guide\n` ;
1864+ content += `- [🛡️ Security Scanning](https://snyk.io/learn/application-security/) - Vulnerability scanning\n` ;
1865+ content += `- [🔄 Update Strategies](https://semver.org/) - Semantic versioning\n\n` ;
1866+ break ;
1867+ case 'Code Quality' :
1868+ default :
1869+ content += `- [🧹 Clean Code](https://www.oreilly.com/library/view/clean-code-a/9780136083238/) - Code quality principles\n` ;
1870+ content += `- [📏 Refactoring Guide](https://refactoring.guru/refactoring) - Code improvement techniques\n` ;
1871+ content += `- [✅ Testing Best Practices](https://testingjavascript.com/) - Testing strategies\n\n` ;
1872+ break ;
1873+ }
1874+ } ) ;
1875+
1876+ content += `**💡 Tip:** Resources are also linked in each issue's detailed section above.` ;
1877+
1878+ return content ;
1879+ }
1880+
1881+ /**
1882+ * Generate Analysis Metadata (performance metrics)
1883+ */
1884+ private generateAnalysisMetadata ( metadata : any ) : string {
1885+ const totalDuration = metadata . totalDuration || metadata . analysisTime || 0 ;
1886+ const cloneTime = metadata . cloneTime || 0 ;
1887+ const analysisTime = metadata . analysisTime || 0 ;
1888+ const reportTime = metadata . reportGenerationTime || 0 ;
1889+
1890+ return `## 📊 Analysis Metadata
1891+
1892+ ### Performance Metrics
1893+ | Metric | Value |
1894+ |--------|-------|
1895+ | Repository Clone | ${ ( cloneTime / 1000 ) . toFixed ( 1 ) } s |
1896+ | Code Analysis | ${ ( analysisTime / 1000 ) . toFixed ( 1 ) } s |
1897+ | Report Generation | ${ ( reportTime / 1000 ) . toFixed ( 1 ) } s |
1898+ | **Total Duration** | **${ ( totalDuration / 1000 ) . toFixed ( 1 ) } s** |
1899+
1900+ ### Analysis Coverage
1901+ | Metric | Value |
1902+ |--------|-------|
1903+ | Total Repository Files | ${ ( metadata . totalFiles || 0 ) . toLocaleString ( ) } |
1904+ | Lines of Code | ${ ( metadata . totalLinesOfCode || 0 ) . toLocaleString ( ) } |
1905+ | Files Modified | ${ metadata . filesModified || 0 } |
1906+ | Lines Changed | ${ ( metadata . linesAdded || 0 ) + ( metadata . linesDeleted || 0 ) } (+${ metadata . linesAdded || 0 } /-${ metadata . linesDeleted || 0 } ) |
1907+
1908+ ### System Information
1909+ - **Analyzer Version:** ${ metadata . analyzerVersion || 'V9 Grouped Report Formatter' }
1910+ - **Analysis Date:** ${ metadata . analyzedAt ? new Date ( metadata . analyzedAt ) . toLocaleString ( ) : new Date ( ) . toLocaleString ( ) }
1911+ - **Report Format:** Grouped (Compact)` ;
1912+ }
1913+
1914+ /**
1915+ * Generate PR Comment (personalized, ready-to-paste)
1916+ */
1917+ private generatePRComment ( issues : EnrichedIssue [ ] , groups : IssueGroup [ ] , metadata : any ) : string {
1918+ const blocking = issues . filter ( i =>
1919+ ( i . category === 'NEW' || i . category === 'EXISTING_MODIFIED' ) &&
1920+ ( i . severity === 'critical' || i . severity === 'high' )
1921+ ) ;
1922+ const resolved = issues . filter ( i => i . category === 'RESOLVED' ) ;
1923+
1924+ const emoji = metadata . decision === 'APPROVED' ? '✅' : '⛔' ;
1925+ const decision = metadata . decision || 'PENDING' ;
1926+
1927+ const greeting = this . getPersonalizedGreeting ( metadata . prAuthor ) ;
1928+ const encouragement = this . getPersonalizedEncouragement ( blocking . length , resolved . length ) ;
1929+
1930+ return `## 💬 PR Comment Template
1931+
1932+ **Ready-to-paste comment for your pull request:**
1933+
1934+ \`\`\`markdown
1935+ ## ${ emoji } Code Quality Analysis: ${ decision }
1936+
1937+ ${ greeting } @${ metadata . prAuthor || 'developer' } ! I've completed a comprehensive analysis of your PR.
1938+
1939+ ${ encouragement }
1940+
1941+ ### Summary
1942+ - **Total Issues:** ${ issues . length } (${ groups . length } unique types)
1943+ - **Blocking Issues:** ${ blocking . length } ${ blocking . length > 0 ? '⛔' : '✅' }
1944+ - **Resolved Issues:** ${ resolved . length } ${ resolved . length > 0 ? '🎉' : '' }
1945+ - **Analysis Time:** ${ ( ( metadata . analysisTime || 0 ) / 1000 ) . toFixed ( 1 ) } s
1946+
1947+ ${ blocking . length > 0 ? `### ⛔ Blocking Issues
1948+ Please fix these before merge:
1949+ ${ blocking . slice ( 0 , 5 ) . map ( i => `- **${ i . rule } ** in \`${ i . file } \`${ i . line ? `:${ i . line } ` : '' } ` ) . join ( '\n' ) }
1950+ ${ blocking . length > 5 ? `\n... and ${ blocking . length - 5 } more` : '' } ` : '### ✅ No Blocking Issues\nThis PR can be merged once approved by reviewers.' }
1951+
1952+ ### 💡 Quick Stats
1953+ - Auto-fixable: ${ groups . filter ( g => this . canAutoFix ( g ) ) . length } /${ groups . length } issue types
1954+ - Critical: ${ issues . filter ( i => i . severity === 'critical' ) . length }
1955+ - High: ${ issues . filter ( i => i . severity === 'high' ) . length }
1956+ - Medium: ${ issues . filter ( i => i . severity === 'medium' ) . length }
1957+ - Low: ${ issues . filter ( i => i . severity === 'low' ) . length }
1958+
1959+ ---
1960+ *Generated by V9 Code Quality Analyzer | [View Full Report](${ metadata . repoUrl || '#' } )*
1961+ \`\`\`
1962+
1963+ **📋 Instructions:**
1964+ 1. Copy the markdown content above
1965+ 2. Paste it as a comment on your pull request
1966+ 3. Customize if needed (greeting, additional context, etc.)` ;
1967+ }
1968+
1969+ /**
1970+ * Get personalized greeting
1971+ */
1972+ private getPersonalizedGreeting ( author ?: string ) : string {
1973+ if ( ! author ) return 'Hello' ;
1974+
1975+ const hour = new Date ( ) . getHours ( ) ;
1976+ if ( hour < 12 ) return 'Good morning' ;
1977+ if ( hour < 18 ) return 'Good afternoon' ;
1978+ return 'Good evening' ;
1979+ }
1980+
1981+ /**
1982+ * Get personalized encouragement
1983+ */
1984+ private getPersonalizedEncouragement ( blockingCount : number , resolvedCount : number ) : string {
1985+ if ( resolvedCount > 10 ) {
1986+ return `🎉 Excellent work! You've resolved ${ resolvedCount } existing issues. ${ blockingCount === 0 ? 'And no new blocking issues!' : `Just ${ blockingCount } items to address before merge.` } ` ;
1987+ } else if ( blockingCount === 0 ) {
1988+ return `✅ Great job! No blocking issues found. ${ resolvedCount > 0 ? `Plus you resolved ${ resolvedCount } issues!` : 'Clean PR!' } ` ;
1989+ } else if ( blockingCount === 1 ) {
1990+ return `Just one small issue to fix before we can merge. You've got this! 💪` ;
1991+ } else if ( blockingCount <= 3 ) {
1992+ return `Found a few items that need attention before merge. Nothing major! 👍` ;
1993+ } else {
1994+ return `There are ${ blockingCount } issues that need to be addressed. I've provided detailed fix suggestions for each. Let me know if you need any help! 🚀` ;
1995+ }
1996+ }
1997+
17321998 /**
17331999 * Generate footer
17342000 */
0 commit comments