fix(discussion): Make NormalizedDiscussion polymorphic for MR support
This is a P0 fix from the CP1-CP2 alignment audit. The original NormalizedDiscussion struct had issue_id as a non-optional i64 and hardcoded noteable_type to "Issue", making it incompatible with merge request discussions even though the database schema already supports both via nullable columns and a CHECK constraint. Changes: - Add NoteableRef enum with Issue(i64) and MergeRequest(i64) variants to provide compile-time safety against mixing up issue vs MR IDs - Change NormalizedDiscussion.issue_id from i64 to Option<i64> - Add NormalizedDiscussion.merge_request_id: Option<i64> - Update transform_discussion() signature to take NoteableRef instead of local_issue_id, deriving issue_id/merge_request_id/noteable_type from the enum variant - Update upsert_discussion() SQL to include merge_request_id column (now 12 parameters instead of 11) - Export NoteableRef from transformers module - Add test for MergeRequest discussion transformation - Update all existing tests to use NoteableRef::Issue(id) The database schema (migration 002) was forward-thinking and already supports both issue_id and merge_request_id as nullable columns with a CHECK constraint. This change prepares the application layer for CP2 merge request support without requiring any migrations. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ use crate::Config;
|
||||
use crate::core::error::Result;
|
||||
use crate::core::payloads::{StorePayloadOptions, store_payload};
|
||||
use crate::gitlab::GitLabClient;
|
||||
use crate::gitlab::transformers::{transform_discussion, transform_notes};
|
||||
use crate::gitlab::transformers::{NoteableRef, transform_discussion, transform_notes};
|
||||
|
||||
use super::issues::IssueForDiscussionSync;
|
||||
|
||||
@@ -129,8 +129,11 @@ async fn ingest_discussions_for_issue(
|
||||
)?;
|
||||
|
||||
// Transform and store discussion
|
||||
let normalized =
|
||||
transform_discussion(&gitlab_discussion, local_project_id, issue.local_issue_id);
|
||||
let normalized = transform_discussion(
|
||||
&gitlab_discussion,
|
||||
local_project_id,
|
||||
NoteableRef::Issue(issue.local_issue_id),
|
||||
);
|
||||
|
||||
// Wrap all discussion+notes operations in a transaction for atomicity
|
||||
let tx = conn.unchecked_transaction()?;
|
||||
@@ -217,10 +220,10 @@ fn upsert_discussion(
|
||||
) -> Result<()> {
|
||||
conn.execute(
|
||||
"INSERT INTO discussions (
|
||||
gitlab_discussion_id, project_id, issue_id, noteable_type,
|
||||
gitlab_discussion_id, project_id, issue_id, merge_request_id, noteable_type,
|
||||
individual_note, first_note_at, last_note_at, last_seen_at,
|
||||
resolvable, resolved, raw_payload_id
|
||||
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
|
||||
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
|
||||
ON CONFLICT(project_id, gitlab_discussion_id) DO UPDATE SET
|
||||
first_note_at = excluded.first_note_at,
|
||||
last_note_at = excluded.last_note_at,
|
||||
@@ -232,6 +235,7 @@ fn upsert_discussion(
|
||||
&discussion.gitlab_discussion_id,
|
||||
discussion.project_id,
|
||||
discussion.issue_id,
|
||||
discussion.merge_request_id,
|
||||
&discussion.noteable_type,
|
||||
discussion.individual_note,
|
||||
discussion.first_note_at,
|
||||
|
||||
Reference in New Issue
Block a user