feat(storage): add pinned field to issues schema

Add pinned column to the issues table to support persistent context markers
that should not be treated as work items (bd-7h5).

Changes:
- Add pinned column to schema.go CREATE TABLE
- Add migration 023_pinned_column.go for existing databases
- Update all issue queries to include pinned column
- Update scanIssues and scanIssuesWithDependencyType to handle pinned field
- Add Pinned field to types.Issue struct with JSON serialization
- Fix migrations_test.go to include pinned in legacy schema test

🤖 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-19 00:08:12 -08:00
parent 8e6462d44c
commit b1ba1c5315
12 changed files with 149 additions and 29 deletions

View File

@@ -233,7 +233,7 @@ func (s *SQLiteStorage) GetDependenciesWithMetadata(ctx context.Context, issueID
i.status, i.priority, i.issue_type, i.assignee, i.estimated_minutes,
i.created_at, i.updated_at, i.closed_at, i.external_ref, i.source_repo,
i.deleted_at, i.deleted_by, i.delete_reason, i.original_type,
i.sender, i.ephemeral,
i.sender, i.ephemeral, i.pinned,
d.type
FROM issues i
JOIN dependencies d ON i.id = d.depends_on_id
@@ -255,7 +255,7 @@ func (s *SQLiteStorage) GetDependentsWithMetadata(ctx context.Context, issueID s
i.status, i.priority, i.issue_type, i.assignee, i.estimated_minutes,
i.created_at, i.updated_at, i.closed_at, i.external_ref, i.source_repo,
i.deleted_at, i.deleted_by, i.delete_reason, i.original_type,
i.sender, i.ephemeral,
i.sender, i.ephemeral, i.pinned,
d.type
FROM issues i
JOIN dependencies d ON i.id = d.issue_id
@@ -714,6 +714,8 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
// Messaging fields (bd-kwro)
var sender sql.NullString
var ephemeral sql.NullInt64
// Pinned field (bd-7h5)
var pinned sql.NullInt64
err := rows.Scan(
&issue.ID, &contentHash, &issue.Title, &issue.Description, &issue.Design,
@@ -721,7 +723,7 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
&issue.Priority, &issue.IssueType, &assignee, &estimatedMinutes,
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef, &sourceRepo, &closeReason,
&deletedAt, &deletedBy, &deleteReason, &originalType,
&sender, &ephemeral,
&sender, &ephemeral, &pinned,
)
if err != nil {
return nil, fmt.Errorf("failed to scan issue: %w", err)
@@ -766,6 +768,10 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
if ephemeral.Valid && ephemeral.Int64 != 0 {
issue.Ephemeral = true
}
// Pinned field (bd-7h5)
if pinned.Valid && pinned.Int64 != 0 {
issue.Pinned = true
}
issues = append(issues, &issue)
issueIDs = append(issueIDs, issue.ID)
@@ -805,6 +811,8 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
// Messaging fields (bd-kwro)
var sender sql.NullString
var ephemeral sql.NullInt64
// Pinned field (bd-7h5)
var pinned sql.NullInt64
var depType types.DependencyType
err := rows.Scan(
@@ -813,7 +821,7 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
&issue.Priority, &issue.IssueType, &assignee, &estimatedMinutes,
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef, &sourceRepo,
&deletedAt, &deletedBy, &deleteReason, &originalType,
&sender, &ephemeral,
&sender, &ephemeral, &pinned,
&depType,
)
if err != nil {
@@ -856,6 +864,10 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
if ephemeral.Valid && ephemeral.Int64 != 0 {
issue.Ephemeral = true
}
// Pinned field (bd-7h5)
if pinned.Valid && pinned.Int64 != 0 {
issue.Pinned = true
}
// Fetch labels for this issue
labels, err := s.GetLabels(ctx, issue.ID)