11package org .rostilos .codecrow .analysisengine .dto .request .ai ;
22
3+ import org .rostilos .codecrow .core .model .branch .BranchIssue ;
34import org .rostilos .codecrow .core .model .codeanalysis .CodeAnalysisIssue ;
45import org .rostilos .codecrow .core .model .codeanalysis .IssueCategory ;
56
67public record AiRequestPreviousIssueDTO (
78 String id ,
89 String type , // security|quality|performance|style
910 String severity , // critical|high|medium|low|info
11+ String title ,
1012 String reason ,
1113 String suggestedFixDescription ,
1214 String suggestedFixDiff ,
@@ -20,7 +22,9 @@ public record AiRequestPreviousIssueDTO(
2022 Integer prVersion , // Which PR iteration this issue was found in
2123 String resolvedDescription , // Description of how the issue was resolved
2224 String resolvedByCommit , // Commit hash that resolved the issue
23- Long resolvedInAnalysisId // Analysis ID where this was resolved (null if still open)
25+ Long resolvedInAnalysisId , // Analysis ID where this was resolved (null if still open)
26+ // Content-based anchoring
27+ String codeSnippet // Verbatim source line for line anchoring — Python passes back, Java re-resolves
2428) {
2529 public static AiRequestPreviousIssueDTO fromEntity (CodeAnalysisIssue issue ) {
2630 String categoryStr = issue .getIssueCategory () != null
@@ -36,6 +40,7 @@ public static AiRequestPreviousIssueDTO fromEntity(CodeAnalysisIssue issue) {
3640 String .valueOf (issue .getId ()),
3741 categoryStr ,
3842 issue .getSeverity () != null ? issue .getSeverity ().name () : null ,
43+ issue .getTitle (),
3944 issue .getReason (),
4045 issue .getSuggestedFixDescription (),
4146 issue .getSuggestedFixDiff (),
@@ -48,7 +53,58 @@ public static AiRequestPreviousIssueDTO fromEntity(CodeAnalysisIssue issue) {
4853 prVersion ,
4954 issue .getResolvedDescription (),
5055 issue .getResolvedCommitHash (),
51- issue .getResolvedAnalysisId ()
56+ issue .getResolvedAnalysisId (),
57+ issue .getCodeSnippet ()
58+ );
59+ }
60+
61+ /**
62+ * Factory method that reads all data from a BranchIssue's own fields.
63+ * Used for AI reconciliation of branch-level issues.
64+ * The BranchIssue is a fully independent entity — no CodeAnalysisIssue dereference needed.
65+ *
66+ * <p><b>ID handling:</b> The {@code id} field is set to the origin
67+ * {@link CodeAnalysisIssue} ID when available, because
68+ * {@code processReconciledIssue()} looks up the BranchIssue via
69+ * {@code findByBranchIdAndOriginIssueId(branchId, id)}. If there is no
70+ * origin issue (e.g. the BranchIssue was created directly), we fall back to
71+ * the BranchIssue's own PK.
72+ */
73+ public static AiRequestPreviousIssueDTO fromBranchIssue (BranchIssue bi ) {
74+ String categoryStr = bi .getIssueCategory () != null
75+ ? bi .getIssueCategory ().name ()
76+ : IssueCategory .CODE_QUALITY .name ();
77+
78+ // Use the reconciled line number if available
79+ Integer lineNumber = bi .getCurrentLineNumber () != null
80+ ? bi .getCurrentLineNumber () : bi .getLineNumber ();
81+
82+ // Use origin issue ID so processReconciledIssue() can look up by
83+ // findByBranchIdAndOriginIssueId. Hibernate allows getId() on a
84+ // lazy proxy without triggering full initialization.
85+ String issueId = bi .getOriginIssue () != null
86+ ? String .valueOf (bi .getOriginIssue ().getId ())
87+ : String .valueOf (bi .getId ());
88+
89+ return new AiRequestPreviousIssueDTO (
90+ issueId ,
91+ categoryStr ,
92+ bi .getSeverity () != null ? bi .getSeverity ().name () : null ,
93+ bi .getTitle (),
94+ bi .getReason (),
95+ bi .getSuggestedFixDescription (),
96+ bi .getSuggestedFixDiff (),
97+ bi .getFilePath (),
98+ lineNumber ,
99+ bi .getOriginBranchName (),
100+ bi .getOriginPrNumber () != null ? String .valueOf (bi .getOriginPrNumber ()) : null ,
101+ bi .isResolved () ? "resolved" : "open" ,
102+ categoryStr ,
103+ null , // prVersion — not applicable for branch issues
104+ bi .getResolvedDescription (),
105+ bi .getResolvedInCommitHash (),
106+ bi .getOriginAnalysisId (), // resolvedInAnalysisId → use origin for provenance
107+ bi .getCodeSnippet ()
52108 );
53109 }
54110}
0 commit comments