@@ -205,6 +205,7 @@ Respond with a JSON object following this exact structure:
205205{
206206 "priority": "high" | "medium" | "low",
207207 "affectedAreas": ["area1", "area2"],
208+ "documentationSection": "Specific section name (e.g., 'Features - Media Library', 'APIs - REST API', 'Configurations - Database')",
208209 "suggestedChanges": [
209210 {
210211 "file": "path/to/doc/file.md",
@@ -316,33 +317,77 @@ const DOCUMENTATION_SECTIONS = {
316317 }
317318} ;
318319
320+ const SPECIFIC_AREA_PATTERNS = {
321+ // Features
322+ 'media|upload|asset' : { section : 'Features' , area : 'Media Library' } ,
323+ 'i18n|internationalization|locale|translation' : { section : 'Features' , area : 'Internationalization' } ,
324+ 'content-manager|content manager' : { section : 'Features' , area : 'Content Manager' } ,
325+ 'content-type-builder|content type builder' : { section : 'Features' , area : 'Content-Type Builder' } ,
326+ 'rbac|role|permission' : { section : 'Features' , area : 'RBAC' } ,
327+ 'review|workflow' : { section : 'Features' , area : 'Review Workflows' } ,
328+ 'draft|publish' : { section : 'Features' , area : 'Draft & Publish' } ,
329+ 'sso|single sign' : { section : 'Features' , area : 'SSO' } ,
330+ 'audit log' : { section : 'Features' , area : 'Audit Logs' } ,
331+ 'api token' : { section : 'Features' , area : 'API Tokens' } ,
332+
333+ // APIs
334+ 'rest|/api/rest' : { section : 'APIs' , area : 'REST API' } ,
335+ 'graphql' : { section : 'APIs' , area : 'GraphQL' } ,
336+ 'document service' : { section : 'APIs' , area : 'Document Service' } ,
337+
338+ // Configurations
339+ 'database|\\bdb\\b' : { section : 'Configurations' , area : 'Database' } ,
340+ 'server|middleware' : { section : 'Configurations' , area : 'Server' } ,
341+
342+ // Other sections
343+ 'typescript|\\.ts' : { section : 'TypeScript' , area : '' } ,
344+ 'cli|command' : { section : 'CLI' , area : '' } ,
345+ 'plugin' : { section : 'Plugins' , area : 'Plugin Development' } ,
346+ 'migration|upgrade' : { section : 'Upgrades' , area : 'Migration' } ,
347+ } ;
348+
319349function categorizePRByDocumentation ( analysis ) {
320- const { claudeSuggestions, files } = analysis ;
350+ const { claudeSuggestions, files, title } = analysis ;
321351
322352 if ( ! claudeSuggestions || ! claudeSuggestions . affectedAreas ) {
323- return { mainCategory : 'cms' , section : 'Other' } ;
353+ return { mainCategory : 'cms' , section : 'Other' , specificArea : '' } ;
354+ }
355+
356+ if ( claudeSuggestions . documentationSection ) {
357+ const mainCategory = claudeSuggestions . documentationSection . toLowerCase ( ) . includes ( 'cloud' ) ? 'cloud' : 'cms' ;
358+ return {
359+ mainCategory,
360+ section : claudeSuggestions . documentationSection ,
361+ specificArea : claudeSuggestions . documentationSection . split ( ' - ' ) [ 1 ] || ''
362+ } ;
324363 }
325364
326365 const affectedAreas = claudeSuggestions . affectedAreas . join ( ' ' ) . toLowerCase ( ) ;
327366 const filePaths = files . map ( f => f . filename . toLowerCase ( ) ) . join ( ' ' ) ;
328- const allText = `${ affectedAreas } ${ filePaths } ` . toLowerCase ( ) ;
367+ const titleLower = title . toLowerCase ( ) ;
368+ const allText = `${ affectedAreas } ${ filePaths } ${ titleLower } ` . toLowerCase ( ) ;
329369
330370 let mainCategory = 'cms' ;
331371 if ( allText . includes ( 'cloud' ) || allText . includes ( '/cloud/' ) ) {
332372 mainCategory = 'cloud' ;
373+
374+ if ( allText . includes ( 'deployment' ) ) {
375+ return { mainCategory, section : 'Deployments' , specificArea : '' } ;
376+ }
377+ if ( allText . includes ( 'project' ) ) {
378+ return { mainCategory, section : 'Projects Management' , specificArea : '' } ;
379+ }
333380 }
334381
335- const sections = DOCUMENTATION_SECTIONS [ mainCategory ] . sections ;
336-
337- for ( const [ sectionName , keywords ] of Object . entries ( sections ) ) {
338- for ( const keyword of keywords ) {
339- if ( allText . includes ( keyword ) ) {
340- return { mainCategory, section : sectionName } ;
341- }
382+ for ( const [ pattern , { section, area } ] of Object . entries ( SPECIFIC_AREA_PATTERNS ) ) {
383+ if ( new RegExp ( pattern , 'i' ) . test ( allText ) ) {
384+ const sectionLabel = area ? `${ section } - ${ area } ` : section ;
385+ return { mainCategory, section : sectionLabel , specificArea : area } ;
342386 }
343387 }
344388
345- return { mainCategory, section : 'Other' } ;
389+ const firstAffectedArea = claudeSuggestions . affectedAreas [ 0 ] || 'Other' ;
390+ return { mainCategory, section : firstAffectedArea , specificArea : '' } ;
346391}
347392
348393function generateMarkdownReport ( releaseInfo , analyses ) {
@@ -354,7 +399,7 @@ function generateMarkdownReport(releaseInfo, analyses) {
354399 markdown += `**Total PRs analyzed:** ${ analyses . length } \n\n` ;
355400 markdown += `---\n\n` ;
356401
357- markdown += `## 📊 Summary\n\n` ;
402+ markdown += `# 📊 Summary\n\n` ;
358403
359404 const categoryCounts = { } ;
360405 const priorityCounts = { high : 0 , medium : 0 , low : 0 } ;
@@ -405,7 +450,7 @@ function generateMarkdownReport(releaseInfo, analyses) {
405450
406451 if ( categorizedPRs . length === 0 ) return ;
407452
408- markdown += `## ${ DOCUMENTATION_SECTIONS [ mainCat ] . label } \n\n` ;
453+ markdown += `# ${ DOCUMENTATION_SECTIONS [ mainCat ] . label } \n\n` ;
409454
410455 const sections = { } ;
411456 categorizedPRs . forEach ( pr => {
@@ -416,25 +461,29 @@ function generateMarkdownReport(releaseInfo, analyses) {
416461 } ) ;
417462
418463 Object . entries ( sections ) . forEach ( ( [ sectionName , prs ] ) => {
419- markdown += `### ${ sectionName } \n\n` ;
464+ markdown += `## ${ sectionName } \n\n` ;
420465
421466 prs . forEach ( analysis => {
422467 const { number, title, url, claudeSuggestions, body, category } = analysis ;
423468
424469 const priorityEmoji = claudeSuggestions . priority === 'high' ? '🔴' :
425470 claudeSuggestions . priority === 'medium' ? '🟡' : '🟢' ;
426471
427- markdown += `#### ${ priorityEmoji } PR #${ number } : ${ title } \n\n` ;
472+ markdown += `### ${ priorityEmoji } PR #${ number } : ${ title } \n\n` ;
428473 markdown += `**Type:** ${ PR_CATEGORIES [ category ] || category } | **Priority:** ${ claudeSuggestions . priority . toUpperCase ( ) } | **Link:** ${ url } \n\n` ;
429474
430475 if ( claudeSuggestions . affectedAreas && claudeSuggestions . affectedAreas . length > 0 ) {
431- markdown += `**Affected Areas:** ${ claudeSuggestions . affectedAreas . join ( ', ' ) } \n\n` ;
476+ markdown += `**Affected Areas:**\n` ;
477+ claudeSuggestions . affectedAreas . forEach ( area => {
478+ markdown += `- ${ area } \n` ;
479+ } ) ;
480+ markdown += `\n` ;
432481 }
433482
434483 if ( body && body . trim ( ) ) {
435484 const summary = body . split ( '\n' ) . slice ( 0 , 2 ) . join ( '\n' ) . trim ( ) ;
436485 if ( summary && summary . length > 10 ) {
437- markdown += `**Description:**\n> ${ summary . substring ( 0 , 200 ) } ${ summary . length > 200 ? '...' : '' } \n\n` ;
486+ markdown += `**Description:**\n${ summary . substring ( 0 , 200 ) } ${ summary . length > 200 ? '...' : '' } \n\n` ;
438487 }
439488 }
440489
@@ -445,28 +494,28 @@ function generateMarkdownReport(releaseInfo, analyses) {
445494 if ( claudeSuggestions . suggestedChanges && claudeSuggestions . suggestedChanges . length > 0 ) {
446495 markdown += `**📝 TODO - Documentation Updates:**\n\n` ;
447496 claudeSuggestions . suggestedChanges . forEach ( ( change , idx ) => {
448- markdown += `** ${ idx + 1 } . ${ change . changeType . toUpperCase ( ) } : ${ change . section || path . basename ( change . file , '.md' ) } **\n\n` ;
449- markdown += `- [ ] Review PR and understand changes \n` ;
450- markdown += `- [ ] Update file: \`${ change . file } \`\n` ;
451- markdown += `- [ ] ${ change . description } \n` ;
497+ const changeTitle = change . section || path . basename ( change . file , '.md' ) ;
498+ markdown += `- [ ] ** ${ idx + 1 } . ${ change . changeType . toUpperCase ( ) } : ${ changeTitle } ** \n` ;
499+ markdown += ` - [ ] Update file: \`${ change . file } \`\n` ;
500+ markdown += ` - [ ] ${ change . description } \n` ;
452501 if ( change . suggestedContent ) {
453- markdown += `- [ ] Add/update content (see below)\n\n` ;
454- markdown += `<details>\n<summary>💡 Suggested content</summary>\n\n` ;
502+ markdown += ` - [ ] Add/update content (see below)\n\n` ;
503+ markdown += ` <details>\n <summary>💡 Suggested content</summary>\n\n` ;
455504
456505 const hasCodeBlock = change . suggestedContent . includes ( '```' ) ;
457506
458507 if ( hasCodeBlock ) {
459- markdown += `${ change . suggestedContent } \n\n` ;
508+ markdown += ` ${ change . suggestedContent . split ( '\n' ) . join ( '\n ' ) } \n\n` ;
460509 } else {
461510 const lines = change . suggestedContent . split ( '\n' ) ;
462- markdown += `> **Content to add/update:**\n>\n` ;
511+ markdown += ` > **Content to add/update:**\n >\n` ;
463512 lines . forEach ( line => {
464- markdown += `> ${ line } \n` ;
513+ markdown += ` > ${ line } \n` ;
465514 } ) ;
466515 markdown += `\n` ;
467516 }
468517
469- markdown += `</details>\n\n` ;
518+ markdown += ` </details>\n\n` ;
470519 } else {
471520 markdown += `\n` ;
472521 }
@@ -475,16 +524,13 @@ function generateMarkdownReport(releaseInfo, analyses) {
475524 markdown += `**Documentation Impact:** No changes required.\n\n` ;
476525 }
477526
478- markdown += `---\n\n` ;
527+ markdown += `\n\n ---\n\n` ;
479528 } ) ;
480529 } ) ;
481530 } ) ;
482531
483532 markdown += `## 📝 Notes\n\n` ;
484- markdown += `- This analysis is generated using Claude AI (${ CLAUDE_MODEL } )\n` ;
485- markdown += `- All suggestions should be reviewed and validated by the documentation team\n` ;
486- markdown += `- Check the boxes as you complete each documentation task\n` ;
487- markdown += `- Priority levels are determined by analyzing the actual code changes\n` ;
533+ markdown += `- This analysis is AI-generated using Claude (${ CLAUDE_MODEL } )\n` ;
488534 markdown += `- PRs categorized as chores, tests, or CI/CD changes are automatically excluded\n` ;
489535
490536 return markdown ;
0 commit comments