feat(who): expand expert + overlap queries with mr_file_changes and mr_reviewers

Chain: bd-jec (config flag) -> bd-2yo (fetch MR diffs) -> bd-3qn6 (rewrite who queries)

- Add fetch_mr_file_changes config option and --no-file-changes CLI flag
- Add GitLab MR diffs API fetch pipeline with watermark-based sync
- Create migration 020 for diffs_synced_for_updated_at watermark column
- Rewrite query_expert() and query_overlap() to use 4-signal UNION ALL:
  DiffNote reviewers, DiffNote MR authors, file-change authors, file-change reviewers
- Deduplicate across signal types via COUNT(DISTINCT CASE WHEN ... THEN mr_id END)
- Add insert_file_change test helper, 8 new who tests, all 397 tests pass
- Also includes: list performance migration 019, autocorrect module, README updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-08 13:35:14 -05:00
parent 435a208c93
commit 95b7183add
19 changed files with 2139 additions and 291 deletions

View File

@@ -12,7 +12,7 @@ use tracing::{debug, warn};
use super::types::{
GitLabDiscussion, GitLabIssue, GitLabIssueRef, GitLabLabelEvent, GitLabMergeRequest,
GitLabMilestoneEvent, GitLabProject, GitLabStateEvent, GitLabUser, GitLabVersion,
GitLabMilestoneEvent, GitLabMrDiff, GitLabProject, GitLabStateEvent, GitLabUser, GitLabVersion,
};
use crate::core::error::{LoreError, Result};
@@ -609,6 +609,15 @@ impl GitLabClient {
self.fetch_all_pages(&path).await
}
pub async fn fetch_mr_diffs(
&self,
gitlab_project_id: i64,
iid: i64,
) -> Result<Vec<GitLabMrDiff>> {
let path = format!("/api/v4/projects/{gitlab_project_id}/merge_requests/{iid}/diffs");
coalesce_not_found(self.fetch_all_pages(&path).await)
}
pub async fn fetch_issue_state_events(
&self,
gitlab_project_id: i64,

View File

@@ -9,6 +9,6 @@ pub use transformers::{
};
pub use types::{
GitLabAuthor, GitLabDiscussion, GitLabIssue, GitLabIssueRef, GitLabLabelEvent, GitLabLabelRef,
GitLabMergeRequestRef, GitLabMilestoneEvent, GitLabMilestoneRef, GitLabNote,
GitLabMergeRequestRef, GitLabMilestoneEvent, GitLabMilestoneRef, GitLabMrDiff, GitLabNote,
GitLabNotePosition, GitLabProject, GitLabStateEvent, GitLabUser, GitLabVersion,
};

View File

@@ -214,6 +214,18 @@ pub struct GitLabReviewer {
pub name: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabMrDiff {
pub old_path: String,
pub new_path: String,
#[serde(default)]
pub new_file: bool,
#[serde(default)]
pub renamed_file: bool,
#[serde(default)]
pub deleted_file: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GitLabMergeRequest {
pub id: i64,