@@ -610,123 +610,81 @@ function categorizePRByDocumentation(analysis) {
610610
611611function generateMarkdownReport ( releaseInfo , analyses ) {
612612 const timestamp = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
613-
614- let markdown = `# Documentation Analysis for Strapi ${ releaseInfo . tag } \n\n` ;
615- markdown += `**Generated on:** ${ timestamp } \n\n` ;
616- markdown += `**Release:** [${ releaseInfo . name || releaseInfo . tag } ](https://github.com/${ STRAPI_REPO_OWNER } /${ STRAPI_REPO_NAME } /releases/tag/${ releaseInfo . tag } )\n\n` ;
617- markdown += `**Total PRs analyzed:** ${ analyses . length } \n\n` ;
618- markdown += `---\n\n` ;
619-
620- markdown += `# 📊 Summary\n\n` ;
621-
622- const categoryCounts = { } ;
623- const priorityCounts = { high : 0 , medium : 0 , low : 0 } ;
624- const docSectionCounts = { cms : { } , cloud : { } } ;
625-
626- analyses . forEach ( a => {
627- categoryCounts [ a . category ] = ( categoryCounts [ a . category ] || 0 ) + 1 ;
628- if ( a . claudeSuggestions ) {
629- const { mainCategory, section } = categorizePRByDocumentation ( a ) ;
630- if ( ! docSectionCounts [ mainCategory ] [ section ] ) {
631- docSectionCounts [ mainCategory ] [ section ] = 0 ;
613+
614+ const verdictOf = ( a ) => ( a . claudeSuggestions && a . claudeSuggestions . needsDocs ) || ( a . impact && a . impact . verdict ) || 'maybe' ;
615+ const yesList = analyses . filter ( a => verdictOf ( a ) === 'yes' ) ;
616+ const noList = analyses . filter ( a => verdictOf ( a ) === 'no' ) ;
617+ const maybeList = analyses . filter ( a => verdictOf ( a ) === 'maybe' ) ;
618+
619+ let markdown = `# Documentation Impact Report — ${ releaseInfo . tag } \n\n` ;
620+ markdown += `Generated on: ${ timestamp } \n\n` ;
621+ markdown += `Release: [${ releaseInfo . name || releaseInfo . tag } ](https://github.com/${ STRAPI_REPO_OWNER } /${ STRAPI_REPO_NAME } /releases/tag/${ releaseInfo . tag } )\n\n` ;
622+
623+ markdown += `Total PRs: ${ analyses . length } | Yes: ${ yesList . length } | No: ${ noList . length } ` ;
624+ if ( maybeList . length > 0 ) markdown += ` | Maybe: ${ maybeList . length } ` ;
625+ markdown += `\n\n---\n\n` ;
626+
627+ // Yes section
628+ if ( yesList . length > 0 ) {
629+ markdown += `## Requires Docs Updates (Yes)\n\n` ;
630+ yesList . forEach ( a => {
631+ const s = a . claudeSuggestions || { } ;
632+ const summary = ( s . summary || a . summary || '' ) . trim ( ) ;
633+ markdown += `- PR #${ a . number } — [${ a . title } ](${ a . url } )\n` ;
634+ if ( summary ) markdown += ` \n Summary: ${ summary } \n` ;
635+ markdown += ` \n Verdict: YES\n` ;
636+ if ( s . rationale ) markdown += ` \n Rationale: ${ s . rationale } \n` ;
637+ const targets = Array . isArray ( s . targets ) ? s . targets : [ ] ;
638+ if ( targets . length > 0 ) {
639+ markdown += ` \n Targets:\n` ;
640+ targets . forEach ( t => {
641+ const anchor = t . anchor ? `#${ t . anchor } ` : '' ;
642+ markdown += ` - ${ t . path } ${ anchor } \n` ;
643+ } ) ;
632644 }
633- docSectionCounts [ mainCategory ] [ section ] ++ ;
634- }
635- } ) ;
636-
637- markdown += `### By PR Type\n\n` ;
638- Object . entries ( categoryCounts ) . forEach ( ( [ cat , count ] ) => {
639- markdown += `- **${ PR_CATEGORIES [ cat ] || cat } **: ${ count } \n` ;
640- } ) ;
641-
642- markdown += `\n### By Documentation Priority\n\n` ;
643- markdown += `- 🔴 **High priority**: ${ priorityCounts . high } \n` ;
644- markdown += `- 🟡 **Medium priority**: ${ priorityCounts . medium } \n` ;
645- markdown += `- 🟢 **Low priority**: ${ priorityCounts . low } \n\n` ;
646-
647- markdown += `### By Documentation Section\n\n` ;
648- markdown += `**CMS Documentation:**\n` ;
649- Object . entries ( docSectionCounts . cms ) . forEach ( ( [ section , count ] ) => {
650- markdown += `- ${ section } : ${ count } \n` ;
651- } ) ;
652- if ( Object . keys ( docSectionCounts . cloud ) . length > 0 ) {
653- markdown += `\n**Cloud Documentation:**\n` ;
654- Object . entries ( docSectionCounts . cloud ) . forEach ( ( [ section , count ] ) => {
655- markdown += `- ${ section } : ${ count } \n` ;
645+ markdown += `\n` ;
656646 } ) ;
657- }
658-
659- markdown += `\n---\n\n` ;
660-
661- [ 'cms' , 'cloud' ] . forEach ( mainCat => {
662- const categorizedPRs = analyses
663- . filter ( a => a . claudeSuggestions )
664- . map ( a => ( { ...a , ...categorizePRByDocumentation ( a ) } ) )
665- . filter ( a => a . mainCategory === mainCat ) ;
666-
667- if ( categorizedPRs . length === 0 ) return ;
668-
669- markdown += `# ${ DOCUMENTATION_SECTIONS [ mainCat ] . label } \n\n` ;
670-
671- const sections = { } ;
672- categorizedPRs . forEach ( pr => {
673- if ( ! sections [ pr . section ] ) {
674- sections [ pr . section ] = [ ] ;
675- }
676- sections [ pr . section ] . push ( pr ) ;
647+ markdown += `\n` ;
648+ }
649+
650+ // No section
651+ if ( noList . length > 0 ) {
652+ markdown += `## No Docs Updates (No)\n\n` ;
653+ noList . forEach ( a => {
654+ const s = a . claudeSuggestions || { } ;
655+ const summary = ( s . summary || a . summary || '' ) . trim ( ) ;
656+ markdown += `- PR #${ a . number } — [${ a . title } ](${ a . url } )\n` ;
657+ if ( summary ) markdown += ` \n Summary: ${ summary } \n` ;
658+ markdown += ` \n Verdict: NO\n` ;
659+ if ( s . rationale ) markdown += ` \n Rationale: ${ s . rationale } \n` ;
660+ markdown += `\n` ;
677661 } ) ;
678-
679- Object . entries ( sections ) . forEach ( ( [ sectionName , prs ] ) => {
680- markdown += `## ${ sectionName } \n\n` ;
681-
682- prs . forEach ( analysis => {
683- const { number, title, url, claudeSuggestions, body, category } = analysis ;
684-
685- const verdictEmoji = claudeSuggestions . needsDocs === 'yes' ? '✅' : claudeSuggestions . needsDocs === 'no' ? '🟦' : '⚠️' ;
686- markdown += `### ${ verdictEmoji } PR #${ number } : ${ title } \n\n` ;
687- markdown += `**Type:** ${ PR_CATEGORIES [ category ] || category } | **Docs required:** ${ claudeSuggestions . needsDocs . toUpperCase ( ) } | **Link:** ${ url } \n\n` ;
688-
689- if ( claudeSuggestions . affectedAreas && claudeSuggestions . affectedAreas . length > 0 ) {
690- markdown += `**Affected Areas:**\n` ;
691- claudeSuggestions . affectedAreas . forEach ( area => {
692- markdown += `- ${ area } \n` ;
693- } ) ;
694- markdown += `\n` ;
695- }
696-
697- if ( body && body . trim ( ) ) {
698- const summary = body . split ( '\n' ) . slice ( 0 , 2 ) . join ( '\n' ) . trim ( ) ;
699- if ( summary && summary . length > 10 ) {
700- markdown += `**Description:**\n${ summary . substring ( 0 , 200 ) } ${ summary . length > 200 ? '...' : '' } \n\n` ;
701- }
702- }
703-
704- if ( claudeSuggestions . rationale ) {
705- markdown += `**Rationale:** ${ claudeSuggestions . rationale } \n\n` ;
706- }
707-
708- const targets = Array . isArray ( claudeSuggestions . targets ) ? claudeSuggestions . targets : [ ] ;
709- if ( targets . length > 0 ) {
710- markdown += `**Targets:**\n` ;
711- targets . forEach ( ( t ) => {
712- const anchor = t . anchor ? `#${ t . anchor } ` : '' ;
713- markdown += `- ${ t . path } ${ anchor ? ` (${ anchor } )` : '' } \n` ;
714- } ) ;
715- markdown += `\n` ;
716- }
717- if ( claudeSuggestions . needsDocs === 'no' ) {
718- markdown += `**Documentation Impact:** No changes required.\n\n` ;
719- }
720-
721- markdown += `\n\n---\n\n` ;
722- } ) ;
662+ markdown += `\n` ;
663+ }
664+
665+ // Maybe section (only if remains after LLM)
666+ if ( maybeList . length > 0 ) {
667+ markdown += `## Uncertain (Maybe)\n\n` ;
668+ maybeList . forEach ( a => {
669+ const s = a . claudeSuggestions || { } ;
670+ const summary = ( s . summary || a . summary || '' ) . trim ( ) ;
671+ markdown += `- PR #${ a . number } — [${ a . title } ](${ a . url } )\n` ;
672+ if ( summary ) markdown += ` \n Summary: ${ summary } \n` ;
673+ markdown += ` \n Verdict: MAYBE\n` ;
674+ if ( s . rationale ) markdown += ` \n Rationale: ${ s . rationale } \n` ;
675+ const targets = Array . isArray ( s . targets ) ? s . targets : [ ] ;
676+ if ( targets . length > 0 ) {
677+ markdown += ` \n Targets:\n` ;
678+ targets . forEach ( t => {
679+ const anchor = t . anchor ? `#${ t . anchor } ` : '' ;
680+ markdown += ` - ${ t . path } ${ anchor } \n` ;
681+ } ) ;
682+ }
683+ markdown += `\n` ;
723684 } ) ;
724- } ) ;
725-
726- markdown += `## 📝 Notes\n\n` ;
727- markdown += `- This analysis is AI-generated using Claude (${ CLAUDE_MODEL } )\n` ;
728- markdown += `- PRs categorized as chores, tests, or CI/CD changes are automatically excluded\n` ;
729-
685+ markdown += `\n` ;
686+ }
687+
730688 return markdown ;
731689}
732690
0 commit comments