Summary
SearchRanked in pkg/store/search.go open-codes the same 16-field rows.Scan as scanNode in pkg/store/node.go, just to capture a trailing rank column. Adding or removing a nodes column now requires editing two scan sites in lock-step.
Location
pkg/store/search.go:34-48 — the inline scan
pkg/store/node.go:76-92 — scanNode
pkg/store/queries.go — nodeColumns constant
Category
refactor
Impact
Medium. Three-way drift risk (the nodeColumns constant, scanNode, SearchRanked's inline scan) on every schema change. Easy to update two of three and ship a silent bug.
Rationale
// pkg/store/node.go:76-92
func scanNode(r RowScanner) (*Node, error) {
var n Node
var parentID sql.NullString
err := r.Scan(
&n.ID, &parentID, &n.SourceFile, &n.NodeType, &n.Depth,
&n.Label, &n.Content, &n.Format, &n.TokenCount, &n.ContentHash,
&n.Temperature, &n.AccessCount, &n.LastAccessed,
&n.CreatedAt, &n.UpdatedAt, &n.Pinned,
)
...
}
// pkg/store/search.go:36-48
var n Node
var parentID sql.NullString
var rank float64
err := rows.Scan(
&n.ID, &parentID, &n.SourceFile, &n.NodeType, &n.Depth,
&n.Label, &n.Content, &n.Format, &n.TokenCount, &n.ContentHash,
&n.Temperature, &n.AccessCount, &n.LastAccessed,
&n.CreatedAt, &n.UpdatedAt, &n.Pinned, &rank,
)
The 16 node fields are identical; only &rank is appended.
Suggested change direction
Add a small helper in pkg/store/node.go that scans the 16 node fields plus one trailing pointer arg:
func scanNodeWithExtra(r RowScanner, extra ...any) (*Node, error) {
var n Node
var parentID sql.NullString
args := append([]any{
&n.ID, &parentID, &n.SourceFile, &n.NodeType, &n.Depth,
&n.Label, &n.Content, &n.Format, &n.TokenCount, &n.ContentHash,
&n.Temperature, &n.AccessCount, &n.LastAccessed,
&n.CreatedAt, &n.UpdatedAt, &n.Pinned,
}, extra...)
if err := r.Scan(args...); err != nil {
return nil, err
}
n.ParentID = parentID.String
return &n, nil
}
SearchRanked becomes:
var rank float64
n, err := scanNodeWithExtra(rows, &rank)
Keep the existing scanNode as the zero-extra convenience wrapper. One scan list, one place to update on schema changes. No new abstraction beyond what's already implicit in RowScanner.
Filed by the nightly enhancement-scanner routine at commit f11c9f1.
Summary
SearchRankedinpkg/store/search.goopen-codes the same 16-fieldrows.ScanasscanNodeinpkg/store/node.go, just to capture a trailingrankcolumn. Adding or removing anodescolumn now requires editing two scan sites in lock-step.Location
pkg/store/search.go:34-48— the inline scanpkg/store/node.go:76-92—scanNodepkg/store/queries.go—nodeColumnsconstantCategory
refactor
Impact
Medium. Three-way drift risk (the
nodeColumnsconstant,scanNode,SearchRanked's inline scan) on every schema change. Easy to update two of three and ship a silent bug.Rationale
The 16 node fields are identical; only
&rankis appended.Suggested change direction
Add a small helper in
pkg/store/node.gothat scans the 16 node fields plus one trailing pointer arg:SearchRankedbecomes:Keep the existing
scanNodeas the zero-extra convenience wrapper. One scan list, one place to update on schema changes. No new abstraction beyond what's already implicit inRowScanner.Filed by the nightly enhancement-scanner routine at commit f11c9f1.