Phase 4: Remove deprecated edge fields from Issue struct (Decision 004)

This is the final phase of the Edge Schema Consolidation. It removes
the deprecated edge fields (RepliesTo, RelatesTo, DuplicateOf, SupersededBy)
from the Issue struct and all related code.

Changes:
- Remove edge fields from types.Issue struct
- Remove edge field scanning from queries.go and transaction.go
- Update graph_links_test.go to use dependency API exclusively
- Update relate.go to use AddDependency/RemoveDependency
- Update show.go with helper functions for thread traversal via deps
- Update mail_test.go to verify thread links via dependencies
- Add migration 022 to drop columns from issues table
- Fix cycle detection to allow bidirectional relates-to links
- Fix migration 022 to disable foreign keys before table recreation

All edge relationships now use the dependencies table exclusively.
The old Issue fields are fully removed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-18 02:48:13 -08:00
parent 3ec517cc1b
commit 7c8b69f5b3
18 changed files with 768 additions and 607 deletions

View File

@@ -183,7 +183,7 @@ func TestMailReply(t *testing.T) {
t.Fatalf("Failed to create original message: %v", err)
}
// Create reply
// Create reply (thread link now done via dependencies per Decision 004)
reply := &types.Issue{
Title: "Re: Original Subject",
Description: "Reply body",
@@ -193,7 +193,6 @@ func TestMailReply(t *testing.T) {
Assignee: "manager", // Reply goes to original sender
Sender: "worker",
Ephemeral: true,
RepliesTo: original.ID, // Thread link
CreatedAt: now.Add(time.Minute),
UpdatedAt: now.Add(time.Minute),
}
@@ -202,14 +201,31 @@ func TestMailReply(t *testing.T) {
t.Fatalf("Failed to create reply: %v", err)
}
// Verify reply has correct thread link
savedReply, err := testStore.GetIssue(ctx, reply.ID)
if err != nil {
t.Fatalf("GetIssue failed: %v", err)
// Add replies-to dependency (thread link per Decision 004)
dep := &types.Dependency{
IssueID: reply.ID,
DependsOnID: original.ID,
Type: types.DepRepliesTo,
}
if err := testStore.AddDependency(ctx, dep, "test"); err != nil {
t.Fatalf("Failed to add replies-to dependency: %v", err)
}
if savedReply.RepliesTo != original.ID {
t.Errorf("RepliesTo = %q, want %q", savedReply.RepliesTo, original.ID)
// Verify reply has correct thread link via dependencies
deps, err := testStore.GetDependenciesWithMetadata(ctx, reply.ID)
if err != nil {
t.Fatalf("GetDependenciesWithMetadata failed: %v", err)
}
var foundReplyLink bool
for _, d := range deps {
if d.DependencyType == types.DepRepliesTo && d.ID == original.ID {
foundReplyLink = true
break
}
}
if !foundReplyLink {
t.Errorf("Reply missing replies-to link to original message")
}
}