feat: node section assignment for sidebar filtering + search fix

Backend:
- Migration 004: add 'section' column to nodes table
  (NULL=inbox, values: clients/projects/recipes/documents/archive)
- Create(parentID, type, title, section) — section stored on root nodes
- ListRoots(includeDeleted, section) — filters by section
  (section='inbox' returns nodes with NULL section)
- GET /api/nodes?section=X filters root nodes by section
- POST /api/nodes accepts 'section' field in body

Frontend:
- Sidebar separates 'НАВИГАЦИЯ' (virtual sections) from 'ДЕЛА' (real nodes)
- Each section loads only its own nodes: GET /api/nodes?section=clients etc.
- Creating from a section sets the section automatically
- Inbox shows only nodes with no section
- selectBySearch(id) closes result dropdown after selection
- All types shown in Russian (Дело, Заметка, Папка, etc.)

Acceptance: go build pass, go test pass (all packages),
  manual: Pro projects section shows only project-nodes,
  clients only client-nodes, inbox only unsectioned nodes.
This commit is contained in:
2026-05-31 01:26:46 +08:00
parent 14ff1a25b9
commit 9ee6df0d3f
11 changed files with 141 additions and 72 deletions
@@ -0,0 +1,9 @@
package storage
// migration004 — add section column to nodes for sidebar grouping.
// Valid sections: clients, projects, recipes, documents, archive, inbox.
// NULL = unassigned (inbox).
const migration004 = `
ALTER TABLE nodes ADD COLUMN section TEXT NULL;
CREATE INDEX IF NOT EXISTS idx_nodes_section ON nodes(section);
`
+2 -1
View File
@@ -60,7 +60,8 @@ var migrationFiles = map[int]string{
1: migration001,
2: migration002,
3: migration003,
// 4: migration004, etc.
4: migration004,
// 5: migration005, etc.
}
func (db *DB) runInitialSchema() error {