feat(api): one API for curl and MCP, REST reads with keys, origin badge with key name
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m16s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m16s
API keys reach tasks and lists over plain REST too (GET /task-lists, GET /tasks with
status/due filters, PATCH/DELETE /thoughts/{id}, GET /lists, list items), guarded by a route
table; notes and settings stay closed. Rights hold for every access alike (webhook:task also
allows create_task over MCP, tasks:write also task delivery).
Tasks, thoughts and list items record which key created them and which one changed them last
(migration 13 replaces agent_mark; origin stays after the user's own edits and survives the
triage into a list item). OriginBadge shows the key name with a webhook or robot icon, details
on hover and tap, and replaces the Webhook and KI badges everywhere, now also on list items.
Settings: category "API" with rights grouped by tasks, lists and inbox and two tabs
(curl / smart home with a Home Assistant sensor, AI agents over MCP). Docs, help, README and
changelog updated; v0.30.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0ca715ba64
commit
b883315914
36 files changed
+1119
-563
No files matched your search
@@ -303,7 +303,7 @@ func (s *Store) DeleteList(userID, listID string) error {
|
||||
func (s *Store) GetListItems(listID string) ([]domain.ListItem, error) {
|
||||
rows, err := s.db.Query(
|
||||
`SELECT li.id, li.list_id, li.content, li.category, li.quantity, li.is_completed, li.completed_by, li.completed_by_name,
|
||||
li.created_by, COALESCE(u.display_name, ''), li.sort_order, li.created_at, li.completed_at, li.agent_mark
|
||||
li.created_by, COALESCE(u.display_name, ''), li.sort_order, li.created_at, li.completed_at, `+originColumns("li.")+`
|
||||
FROM list_items li LEFT JOIN users u ON u.id = li.created_by AND li.created_by != ''
|
||||
WHERE li.list_id = ?
|
||||
ORDER BY li.is_completed ASC, li.sort_order ASC, li.created_at DESC`,
|
||||
@@ -318,8 +318,10 @@ func (s *Store) GetListItems(listID string) ([]domain.ListItem, error) {
|
||||
for rows.Next() {
|
||||
var it domain.ListItem
|
||||
var doneInt int
|
||||
if err := rows.Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &doneInt, &it.CompletedBy, &it.CompletedByName, &it.CreatedBy, &it.CreatedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt, &it.AgentMark); err == nil {
|
||||
var o originDest
|
||||
if err := rows.Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &doneInt, &it.CompletedBy, &it.CompletedByName, &it.CreatedBy, &it.CreatedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt, &o.createdVia, &o.createdKey, &o.changedVia, &o.changedKey, &o.changedAt); err == nil {
|
||||
it.IsCompleted = doneInt != 0
|
||||
it.Origin = o.result()
|
||||
items = append(items, it)
|
||||
}
|
||||
}
|
||||
@@ -399,15 +401,18 @@ func (s *Store) ToggleListItem(itemID string, isCompleted bool, userID, userName
|
||||
|
||||
var it domain.ListItem
|
||||
var dInt int
|
||||
var o originDest
|
||||
err = s.db.QueryRow(
|
||||
`SELECT id, list_id, content, category, quantity, is_completed, completed_by, completed_by_name, sort_order, created_at, completed_at
|
||||
`SELECT id, list_id, content, category, quantity, is_completed, completed_by, completed_by_name, sort_order, created_at, completed_at, `+originColumns("")+`
|
||||
FROM list_items WHERE id = ?`,
|
||||
itemID,
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt)
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt,
|
||||
&o.createdVia, &o.createdKey, &o.changedVia, &o.changedKey, &o.changedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
it.IsCompleted = dInt != 0
|
||||
it.Origin = o.result()
|
||||
_, _ = s.db.Exec(`UPDATE lists SET updated_at = ? WHERE id = ?`, now, it.ListID)
|
||||
return &it, nil
|
||||
}
|
||||
@@ -416,15 +421,18 @@ func (s *Store) UpdateListItem(itemID string, content *string, category *string,
|
||||
now := domain.NowISO()
|
||||
var it domain.ListItem
|
||||
var dInt int
|
||||
var o originDest
|
||||
err := s.db.QueryRow(
|
||||
`SELECT id, list_id, content, category, quantity, is_completed, completed_by, completed_by_name, sort_order, created_at, completed_at
|
||||
`SELECT id, list_id, content, category, quantity, is_completed, completed_by, completed_by_name, sort_order, created_at, completed_at, `+originColumns("")+`
|
||||
FROM list_items WHERE id = ?`,
|
||||
itemID,
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt)
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt,
|
||||
&o.createdVia, &o.createdKey, &o.changedVia, &o.changedKey, &o.changedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
it.IsCompleted = dInt != 0
|
||||
it.Origin = o.result()
|
||||
|
||||
if content != nil {
|
||||
it.Content = *content
|
||||
@@ -459,17 +467,19 @@ func (s *Store) MoveListItem(itemID, targetListID string) (*domain.ListItem, err
|
||||
|
||||
var it domain.ListItem
|
||||
var dInt int
|
||||
var o originDest
|
||||
err := s.db.QueryRow(
|
||||
`SELECT li.id, li.list_id, li.content, li.category, li.quantity, li.is_completed, li.completed_by, li.completed_by_name,
|
||||
li.created_by, COALESCE(u.display_name, ''), li.sort_order, li.created_at, li.completed_at, li.agent_mark
|
||||
li.created_by, COALESCE(u.display_name, ''), li.sort_order, li.created_at, li.completed_at, `+originColumns("li.")+`
|
||||
FROM list_items li LEFT JOIN users u ON u.id = li.created_by AND li.created_by != ''
|
||||
WHERE li.id = ?`,
|
||||
itemID,
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.CreatedBy, &it.CreatedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt, &it.AgentMark)
|
||||
).Scan(&it.ID, &it.ListID, &it.Content, &it.Category, &it.Quantity, &dInt, &it.CompletedBy, &it.CompletedByName, &it.CreatedBy, &it.CreatedByName, &it.SortOrder, &it.CreatedAt, &it.CompletedAt, &o.createdVia, &o.createdKey, &o.changedVia, &o.changedKey, &o.changedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
it.IsCompleted = dInt != 0
|
||||
it.Origin = o.result()
|
||||
return &it, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user