feat(sync): fetch and store GitLab issue links (bd-343o)

Add end-to-end support for GitLab issue link fetching:
- New GitLabIssueLink type + fetch_issue_links API client method
- Migration 029: add issue_links job type and watermark column
- issue_links.rs: bidirectional entity_reference storage with
  self-link skip, cross-project fallback, idempotent upsert
- Drain pipeline in orchestrator following mr_closes_issues pattern
- Display related issues in 'lore show issues' output
- --no-issue-links CLI flag with config, autocorrect, robot-docs
- 6 unit tests for storage logic
This commit is contained in:
teernisse
2026-02-19 09:26:28 -05:00
parent 9a1dbda522
commit 1e679a6d72
18 changed files with 2051 additions and 8 deletions

View File

@@ -0,0 +1,43 @@
-- Migration 029: Expand pending_dependent_fetches CHECK to include 'issue_links' job type.
-- Also adds issue_links_synced_for_updated_at watermark to issues table.
-- SQLite cannot ALTER CHECK constraints, so we recreate the table.
-- Step 1: Recreate pending_dependent_fetches with expanded CHECK
CREATE TABLE pending_dependent_fetches_new (
id INTEGER PRIMARY KEY,
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
entity_type TEXT NOT NULL CHECK (entity_type IN ('issue', 'merge_request')),
entity_iid INTEGER NOT NULL,
entity_local_id INTEGER NOT NULL,
job_type TEXT NOT NULL CHECK (job_type IN (
'resource_events', 'mr_closes_issues', 'mr_diffs', 'issue_links'
)),
payload_json TEXT,
enqueued_at INTEGER NOT NULL,
locked_at INTEGER,
attempts INTEGER NOT NULL DEFAULT 0,
next_retry_at INTEGER,
last_error TEXT
);
INSERT INTO pending_dependent_fetches_new
SELECT * FROM pending_dependent_fetches;
DROP TABLE pending_dependent_fetches;
ALTER TABLE pending_dependent_fetches_new RENAME TO pending_dependent_fetches;
-- Recreate indexes from migration 011
CREATE UNIQUE INDEX uq_pending_fetches
ON pending_dependent_fetches(project_id, entity_type, entity_iid, job_type);
CREATE INDEX idx_pending_fetches_claimable
ON pending_dependent_fetches(job_type, locked_at) WHERE locked_at IS NULL;
CREATE INDEX idx_pending_fetches_retryable
ON pending_dependent_fetches(next_retry_at) WHERE locked_at IS NULL AND next_retry_at IS NOT NULL;
-- Step 2: Add watermark column for issue link sync tracking
ALTER TABLE issues ADD COLUMN issue_links_synced_for_updated_at INTEGER;
-- Update schema version
INSERT INTO schema_version (version, applied_at, description)
VALUES (29, strftime('%s', 'now') * 1000, 'Expand dependent fetch queue for issue links');