refactor: implement template-driven node tree and human-readable vault layout

Unified Node model: added template_id, fs_path, archived, sort_order fields.
Template registry: system templates embedded as JSON (folder/project/client/
document/recipe), with Registry for enabled/disabled/filtered access.
SafeDisplayNameToPathSegment: human-readable path segments with Cyrillic
support, illegal char replacement, uniqueness via numeric suffixes.
Sidebar refactored: system views (Today/Inbox/Activity) separate from
workspace tree. Creation menu built dynamically from enabled templates.
Create/Rename/Move: physical folder operations with fs_path update,
recursive descendant path updates.
DB migration 012: adds template_id, fs_path, archived columns.
Vault migration command: rebuilds fs_path for existing nodes.
Tests: safename, registry, node model, repository integration.
Docs: VAULT_LAYOUT.md, TEMPLATES.md, PLAN.md updated.
i18n: nav.system, nav.workspace, template.*, common.rename/archive,
migrate.* keys added to ru.json and en.json.
This commit is contained in:
2026-06-02 12:47:06 +08:00
parent 12f2916a24
commit 0b26f7e5b3
37 changed files with 1479 additions and 338 deletions
+8 -1
View File
@@ -35,7 +35,7 @@ func NewService(db *storage.DB, vaultRoot string, nodeRepo *nodes.Repository, fi
// Create makes a new note node, an empty .md file, and links them.
func (s *Service) Create(parentID, title, section string) (*nodes.Node, *files.Record, error) {
node, err := s.nodes.Create(parentID, nodes.TypeNote, title, section)
node, err := s.nodes.Create(strPtr(parentID), nodes.TypeNote, title, 0, "", "")
if err != nil {
return nil, nil, fmt.Errorf("create node: %w", err)
}
@@ -201,3 +201,10 @@ func mustRead(path string) []byte {
func utcNow() string {
return time.Now().UTC().Format(time.RFC3339)
}
func strPtr(s string) *string {
if s == "" {
return nil
}
return &s
}