Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions internal/api/diff_review.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,19 @@ func (s *Server) DiffReview(c echo.Context) error {
func (s *Server) GetDiffReviewStatus(c echo.Context) error {
// API key authentication is handled by middleware

orgID, ok := c.Get("org_id").(int64)
if !ok || orgID == 0 {
return JSONErrorWithEnvelope(c, http.StatusUnauthorized, "missing org context")
}

reviewIDStr := c.Param("review_id")
reviewID, err := strconv.ParseInt(reviewIDStr, 10, 64)
if err != nil {
return JSONErrorWithEnvelope(c, http.StatusBadRequest, "invalid review_id")
}

rm := NewReviewManager(s.db)
reviewRecord, err := rm.GetReview(reviewID)
reviewRecord, err := rm.GetReviewForOrg(reviewID, orgID)
if err != nil {
return JSONErrorWithEnvelope(c, http.StatusNotFound, "review not found")
}
Expand Down Expand Up @@ -274,7 +279,8 @@ func (s *Server) GetDiffReviewStatus(c echo.Context) error {

preloaded, err := decodePreloadedChanges(meta)
if err != nil {
return JSONErrorWithEnvelope(c, http.StatusInternalServerError, fmt.Sprintf("failed to decode preloaded changes: %v", err))
log.Printf("[WARN] preloaded_changes unavailable for review %d, serving without code context: %v", reviewID, err)
preloaded = nil
}

result, err := decodeReviewResult(meta)
Expand Down Expand Up @@ -316,6 +322,7 @@ func (s *Server) runDiffReview(request review.ReviewRequest, rm *ReviewManager,
// Attach event sink so logs go to review_events table for UI
eventSink := NewDatabaseEventSink(s.db)
logger.SetEventSink(eventSink)
defer logger.Close()
logger.LogSection("CLI DIFF REVIEW STARTED")
logger.Log("Review ID: %d", reviewID)
logger.Log("Organization ID: %d", orgID)
Expand Down Expand Up @@ -410,6 +417,7 @@ func (s *Server) runDiffReview(request review.ReviewRequest, rm *ReviewManager,
}
if logger != nil {
logger.LogSection("REVIEW COMPLETED")
logger.Log("Review ID: %d", reviewID)
logger.Log("Successfully generated %d comments", len(result.Comments))
}
} else {
Expand All @@ -434,10 +442,6 @@ func (s *Server) runDiffReview(request review.ReviewRequest, rm *ReviewManager,
}
}

if err := rm.UpdateReviewStatus(reviewID, status); err != nil {
log.Printf("[WARN] failed to update review status for %d: %v", reviewID, err)
}

payload := DiffReviewResult{Summary: summary, Comments: comments}
meta := map[string]interface{}{"review_result": payload}
if failureReason != "" {
Expand All @@ -447,6 +451,10 @@ func (s *Server) runDiffReview(request review.ReviewRequest, rm *ReviewManager,
log.Printf("[WARN] failed to persist review_result for %d: %v", reviewID, err)
}

if err := rm.UpdateReviewStatus(reviewID, status); err != nil {
log.Printf("[WARN] failed to update review status for %d: %v", reviewID, err)
}

// Persist AI summary title for later display (extract first heading only)
if summary != "" {
title := extractFirstHeading(summary)
Expand Down
53 changes: 53 additions & 0 deletions internal/api/reviews.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,59 @@ func (rm *ReviewManager) GetReview(reviewID int64) (*Review, error) {
return &review, nil
}

// GetReviewForOrg retrieves a review by ID scoped to a specific org.
// Returns an error if the review does not exist or belongs to a different org.
func (rm *ReviewManager) GetReviewForOrg(reviewID int64, orgID int64) (*Review, error) {
query := `
SELECT id, repository, branch, commit_hash, pr_mr_url, connector_id,
status, trigger_type, user_email, provider, mr_title, friendly_name, author_name, author_username,
created_at, started_at, completed_at, metadata
FROM reviews
WHERE id = $1 AND org_id = $2
`

var review Review
var mrTitle, friendlyName, authorName, authorUsername sql.NullString
err := rm.store.QueryRow(query, reviewID, orgID).Scan(
&review.ID,
&review.Repository,
&review.Branch,
&review.CommitHash,
&review.PrMrURL,
&review.ConnectorID,
&review.Status,
&review.TriggerType,
&review.UserEmail,
&review.Provider,
&mrTitle,
&friendlyName,
&authorName,
&authorUsername,
&review.CreatedAt,
&review.StartedAt,
&review.CompletedAt,
&review.Metadata,
)
if err != nil {
return nil, fmt.Errorf("failed to get review: %w", err)
}

if mrTitle.Valid {
review.MRTitle = &mrTitle.String
}
if friendlyName.Valid {
review.FriendlyName = &friendlyName.String
}
if authorName.Valid {
review.AuthorName = &authorName.String
}
if authorUsername.Valid {
review.AuthorUsername = &authorUsername.String
}

return &review, nil
}

// ReviewMetadataUpdate describes optional fields that can be updated on a review record.
type ReviewMetadataUpdate struct {
Repository *string
Expand Down
6 changes: 3 additions & 3 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"picomatch@2": "2.3.2",
"picomatch@4": "4.0.4",
"preact": "10.27.3",
"qs": "6.14.2",
"qs": "6.15.2",
"react-router": "6.30.2",
"serialize-javascript": "7.0.5",
"svgo": "3.3.3",
Expand Down
Loading