fix: batch tag queries, inline edit, delete response, SPA catch-all, link glyph

- Fix N+1 tag query in List() with batched IN clause
- Add inline body editing in web detail pane (dblclick or e key)
- Delete API returns {result: "soft"|"hard"} with 200 instead of 204
- SPA handler serves index.html for all extensionless paths
- Link glyph changed from emoji 🔗 to unicode ↗ for terminal alignment
- Capture bar contrast and hover glow increased
- Comment on load-bearing "--" in root.go
This commit is contained in:
2026-05-14 12:37:13 -04:00
parent 5b0d0a8f33
commit 03094706c3
9 changed files with 152 additions and 23 deletions
+40 -6
View File
@@ -269,12 +269,8 @@ func (s *Store) List(params ListParams) ([]*Entity, error) {
entities = append(entities, e)
}
for _, e := range entities {
tags, err := s.loadTags(e.ID)
if err != nil {
return nil, err
}
e.Tags = tags
if err := s.batchLoadTags(entities); err != nil {
return nil, err
}
return entities, nil
@@ -452,6 +448,44 @@ func (s *Store) Resolve(prefix string) (string, error) {
// helpers
func (s *Store) batchLoadTags(entities []*Entity) error {
if len(entities) == 0 {
return nil
}
idMap := make(map[string]*Entity, len(entities))
placeholders := make([]string, len(entities))
args := make([]any, len(entities))
for i, e := range entities {
e.Tags = []string{}
idMap[e.ID] = e
placeholders[i] = "?"
args[i] = e.ID
}
query := fmt.Sprintf(
"SELECT entity_id, tag FROM entity_tags WHERE entity_id IN (%s) ORDER BY entity_id, tag",
strings.Join(placeholders, ","),
)
rows, err := s.db.Query(query, args...)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var entityID, tag string
if err := rows.Scan(&entityID, &tag); err != nil {
return err
}
if e, ok := idMap[entityID]; ok {
e.Tags = append(e.Tags, tag)
}
}
return rows.Err()
}
func (s *Store) loadTags(entityID string) ([]string, error) {
rows, err := s.db.Query("SELECT tag FROM entity_tags WHERE entity_id = ? ORDER BY tag", entityID)
if err != nil {