verstak/docs/PLAN.md

12 KiB
Raw Blame History

Верстак — Пошаговый план разработки

Принципы работы

  1. После каждого шага — СТОП. Влад проверяет, даёт обратную связь.
  2. Следующий шаг начинается ТОЛЬКО после одобрения.
  3. Каждый шаг — отдельный git commit.
  4. Периодически сверяться с этим планом и документацией в docs/.

Статус шагов

# Шаг Статус
1 Git init + Skeleton выполнен
2 Init + SQLite + First Migration выполнен
3 Nodes Repository + CRUD + CLI Node выполнен
4 Vault Files: Trash + File Service + CLI File выполнен
5 Markdown Notes: Create/Read/Save + CLI Note выполнен
6 GUI (browser prototype): Sidebar + Main Panel выполнен
7 Actions + Worklog выполнен
8 FTS5 Search выполнен
9 Section assignment + Sidebar filtering выполнен
10 Plugin Manager (discovery + templates) выполнен
11 Wails Desktop GUI 🔄 в процессе — Wails v2 stable
12 Files/Folders full workflow не начат
13 Drag-and-drop не начат
14 MVP stabilization не начат
15 Sync Server Skeleton 🔒 PAUSED
16 Sync Client MVP 🔒 PAUSED
17 Activity + File Scanner/Watcher 🔒 PAUSED
18 TUI MVP (Bubble Tea) 🔒 PAUSED
19 Integrity Check + Repair 🔒 PAUSED
20 Plugins: Lua runtime 🔒 PAUSED
21 DokuWiki Importer (plugin) 🔒 PAUSED
22 Calendar/Kanban 🔒 PAUSED
23 New templates/integrations 🔒 PAUSED

🔒 = PAUSED — не начинать до завершения шага 14 (MVP stabilization).

Wails v3 → v2 migration: Wails v3 alpha.96 показал SIGSEGV на Linux desktop (GTK/X11). Wails v2 stable выбран как GUI base для MVP. Миграция в процессе (ветка gui/migrate-wails-v2).

GUI Build (Wails v2):

cd frontend && npm run build && cd ..
rm -rf cmd/verstak-gui/frontend-dist && cp -r frontend/dist cmd/verstak-gui/frontend-dist
go build -tags "gui production webkit2_41" -o verstak-gui ./cmd/verstak-gui
./verstak-gui

Или для dev режима: wails dev (требует Wails v2 CLI)


Выполненные шаги (1-10)

ШАГ 1 — Git Init + Skeleton

  • go module verstak, структура cmd/internal/migrations
  • CLI verstak --version
  • README.md

ШАГ 2 — Init + SQLite

  • storage.go: DB wrapper, migration runner
  • vault.go: Init() создаёт .verstak/ + index.db
  • config.go: YAML config

ШАГ 3 — Nodes Repository

  • Node struct + CRUD (Create, Get, ListChildren, ListRoots, UpdateTitle, Move, SoftDelete)
  • Meta KV + tests

ШАГ 4 — Files

  • FileService: AddExternal, CopyIntoVault, Get, ListByNode, MarkMissing, DeleteToTrash, Open
  • file_test.go: 5 tests

ШАГ 5 — Notes

  • NoteService: Create, Read, Save (с backup), Delete
  • note_test.go: 3 tests

ШАГ 6 — GUI (browser prototype)

  • Go HTTP SPA на случайном порту
  • Sidebar tree + разделы (Сегодня, Неразобранное, Клиенты, Проекты...)
  • Dashboard дела + вкладки (Обзор, Заметки, Файлы, Действия, Журнал, Активность)
  • Модальное окно "+ Добавить" с выбором типа
  • Поиск по корневым нодам
  • Это legacy prototype — не развивать как основной GUI

ШАГ 7 — Actions + Worklog

  • ActionService: Create, Get, ListByNode, Delete, Run (open_url/file/folder, run_command)
  • WorklogService: Add, Update, ListByNode, Delete, SumMinutes, Report
  • CLI: action add/list/run/delete, log add/list/report
  • GUI вкладки с кнопками действий и журналом работ
  • SearchService: Index, Remove, Rebuild, Search (FTS5 MATCH)
  • FTS5 virtual table создаётся лениво (работает с/без FTS5)
  • Fallback на LIKE по заголовкам нод
  • CLI: verstak index rebuild
  • GUI search bar

ШАГ 9 — Section assignment

  • Колонка section в nodes (clients/projects/recipes/documents/archive/inbox)
  • Фильтрация разделов по ?section= в API
  • Root-ноды без section → inbox

ШАГ 10 — Plugin Manager

  • Discovery: .verstak/plugins/<name>/plugin.json
  • Enable/disable, templates → pre-filled node trees
  • Built-in шаблон "Клиент" (Overview + Документы/Переписка/Скриншоты)
  • Template selector в модалке создания дела
  • POST /api/nodes/from-template
  • CLI: plugin list/enable/disable/templates
  • Lua runtime — stub (placeholder)

Текущий этап: ШАГ 11 — Wails Desktop GUI

Целевой commit: gui/wails-file-workflow

Архитектура:

┌─────────────────────────────────────────────────┐
│  Frontend (Wails)                                │
│  frontend/src/                                   │
│    App.svelte                                    │
│    components/Sidebar, TopBar, CaseView, ...     │
│    stores/selection, nodes, files, ui           │
│    styles/theme.css                              │
└──────────────────┬──────────────────────────────┘
                   │ Wails bindings
┌──────────────────▼──────────────────────────────┐
│  Go Core (internal/core/)                        │
│    nodes, vault, storage, notes, files,         │
│    actions, worklog, search, plugins             │
└──────────────────┬──────────────────────────────┘
                   │
┌──────────────────▼──────────────────────────────┐
│  Vault filesystem + SQLite                       │
└─────────────────────────────────────────────────┘

Действия

  1. Создать Wails app skeleton (wails init)
  2. Структура frontend/ — Svelte/Vue/vanilla TS
  3. Backend bindings — методы Wails над core services
  4. Перенести текущий UI shell из inline HTML в frontend
  5. Оставить текущий internal/gui/ как legacy (не удалять, но не развивать)

Backend bindings (минимум)

// Nodes
ListSections() ([]SectionDTO, error)
ListNodes(section string) ([]NodeDTO, error)
GetNodeDetail(nodeID string) (NodeDetailDTO, error)
CreateNode(parentID, section, typ, title string) (NodeDTO, error)
FromTemplate(parentID, section, typ, title, template string) (NodeDTO, error)
DeleteNode(id string) error
MoveNode(id, parentID string) error

// Notes
CreateNote(parentID, title string) (NodeDTO, error)
ReadNote(noteID string) (string, error)
SaveNote(noteID, content string) error

// Files
ListFiles(nodeID string) ([]FileDTO, error)
AddPathCopy(nodeID, sourcePath string) ([]NodeDTO, error)  // файл или папка
AddPathLink(nodeID, sourcePath string) ([]NodeDTO, error)
DeleteFileOrFolder(id string) error
OpenFile(id string) error
OpenFolder(id string) error
PickFile() (string, error)
PickDirectory() (string, error)

// Actions/Worklog/Search
ListActions(nodeID string) ([]ActionDTO, error)
RunAction(id string) error
CreateWorklog(nodeID, summary string, minutes int) (WorklogDTO, error)
Search(query string) ([]SearchResultDTO, error)

ШАГ 12 — Files/Folders full workflow

Core service extensions

Расширить files.Service:

AddPathCopy(nodeID string, sourcePath string) ([]Node, error)
AddPathLink(nodeID string, sourcePath string) ([]Node, error)

Логика:

  • os.Stat(sourcePath) → если директория → рекурсивный обход
  • Каждый файл → File node + file record
  • Каждая папка → Folder node
  • Структура сохраняется через parent_id

Folder model

Папка = node type folder (не file record с mime=directory).

При импорте romashka-docs/:

Folder node: romashka-docs (type=folder)
  File node: dogovor.docx (type=file)
  Folder node: screenshots (type=folder)
    File node: error.png (type=file)

Name conflict resolution

Если в target уже есть docs:

docs
docs (2)
docs (3)

Safety checks

При добавлении папки показать summary:

  • количество файлов/папок
  • общий размер
  • предупреждение если > 1000 файлов, > 1 GB, содержит .git/node_modules/.cache

Trash

  • Soft delete node + children
  • Vault files → .verstak/trash
  • External files — только удалить связь
  • Не rm -rf

Tests

  1. Copy single file → vault, record created, source intact
  2. Link single file → no copy, external path saved
  3. Copy folder → tree created, files in vault
  4. Link folder → node created, no content copied
  5. Delete vault file → soft-deleted, file in trash
  6. Delete vault folder → children soft-deleted
  7. Name conflict → no overwrite, safe suffix
  8. Open file → mocked opener (no real app launch)

ШАГ 13 — Drag-and-drop

External D&D

Drop target: активное дело / вкладка Файлы / Неразобранное.

После drop → диалог:

Добавить в "ООО Ромашка / Сайт"
Файлов: 3, Папок: 1, 240 MB
[Скопировать] [Переместить] [Привязать] [Отмена]

ШАГ 14 — MVP stabilization

  • Smoke tests базовых сценариев
  • Проверка: дело → заметка → файл → папка → trash → перезапуск
  • go test ./... pass
  • Обновление документации
  • Остановка перед следующими фичами

Структура репозитория

verstak/
  go.mod
  README.md
  PLAN.md

  cmd/
    verstak/          # CLI
    verstak-gui/      # Wails GUI main
    verstak-tui/      # Bubble Tea TUI
    verstak-server/   # Sync server

  frontend/           # Wails frontend
    package.json
    wails.json
    src/
      App.svelte
      components/
      stores/
      styles/

  internal/
    core/
      nodes/
      vault/
      storage/
      notes/
      files/
      actions/
      worklog/
      activity/
      search/
      sync/
      security/
      config/
      plugins/        # manager, lua (stub)

  contrib/
    plugins/
      importer-dokuwiki/

  migrations/
    001_init.sql
    002_add_meta.sql
    003_add_files.sql
    004_add_notes.sql
    005_add_actions.sql
    006_add_worklog.sql

RAID

  • Критично: Wails требует Node.js для frontend-сборки
  • Критично: go-sqlite3 + cgo; gcc уже установлен
  • Зависимость: Steps 15+ ждут завершения step 14
  • Риск: Wails v3 может быть нестабилен — проверить перед шагом 11