verstak/docs/PLAN.md

14 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 выполнено (v2, full Svelte UI)
12 Files/Folders full workflow выполнено (copy/link/import/tree)
13 Drag-and-drop выполнено (internal + external drops)
14 MVP stabilization 🔄 в процессе — smoke-тесты, docs, go test
15 Sync Server + Client 🔒 PAUSED — HTTP API key, push/pull, blob sync
16 Activity Suggestions 🔒 PAUSED — worklog suggestions from activity_events
17 File Scanner/Watcher 🔒 PAUSED — fsnotify, snapshot scanner, missing file detection
18 TUI MVP (Bubble Tea) 🔒 PAUSED — tree/search, add worklog, run action, sync
19 Plugins: Lua runtime 🔒 PAUSED — gopher-lua, hooks, sandbox
20 Browser Extension 🔒 PAUSED — tracking, capture, evidence
21 Calendar/Kanban 🔒 PAUSED — view by date, board view
22 Integrity Check + Repair 🔒 PAUSED — checksums, crash recovery
23 New templates/integrations 🔒 PAUSED — community plugins

🔒 = PAUSED — не начинать до завершения шага 14 (MVP stabilization). Текущий статус: MVP stabilization завершена — smoke-тесты написаны, go test проходит, документация обновлена.

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)


Текущий этап: MVP Stabilization

Цель: стабилизация MVP — smoke-тесты, go test, документация.

Прогресс Wails v2 Desktop GUI:

  • Wails v2 shell (window opens, no SIGSEGV)
  • Layout fix (full viewport, dark theme, sidebar+main)
  • Notes bindings + UI (create/read/save/dirty state)
  • Tabs (Overview/Notes/Files/Actions/Worklog/Activity)
  • Node creation + template selection (FromTemplate)
  • Section filtering
  • File tree with breadcrumbs, preview, CRUD (rename/delete/duplicate/cut/copy/paste)
  • Drag-and-drop (internal + external OS file drops)
  • Actions CRUD (create/list/run/delete)
  • Worklog entry form
  • Today dashboard + Activity feed (global + per-case)
  • Search
  • Import dialog with safety checks (PreviewImport)
  • Keyboard shortcuts

Среднесрочные шаги (заморожены до стабилизации MVP):

  • Sync server/client
  • File Scanner/Watcher
  • TUI (Bubble Tea)
  • Activity suggestions
  • Lua runtime
  • Browser extension

Выполненные шаги (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 (Wails v2 — реализовано)

// Nodes
ListSections() []SectionDTO
ListNodesBySection(section string) ([]NodeDTO, error)
GetNodeDetail(nodeID string) (*NodeDTO, error)
ListChildren(parentID string) ([]NodeDTO, error)
CreateNode(parentID, typ, title, section string) (*NodeDTO, error)
DeleteNode(id string) error
MoveNode(nodeID, newParentID string) error
RenameNode(nodeID, newTitle string) error

// Templates
ListTemplates() []TemplateDTO
FromTemplate(parentID, typ, title, section, template string) (*NodeDTO, error)

// Notes
ListNotes(nodeID string) ([]NodeDTO, error)
CreateNote(parentID, title string) (*NodeDTO, error)
ReadNote(noteID string) (string, error)
SaveNote(noteID, content string) error

// Files
ListFiles(nodeID string) ([]FileDTO, error)
ListItems(nodeID string) ([]FileTreeItemDTO, error)
AddPathCopy(nodeID, sourcePath string) ([]NodeDTO, error)
AddPathLink(nodeID, sourcePath string) ([]NodeDTO, error)
DeleteFileOrFolder(nodeID string) error
CreateEmptyFile(parentID, filename string) (*NodeDTO, error)
DuplicateNode(nodeID string) (*NodeDTO, error)
OpenFile(fileID string) error
OpenFolder(nodeID string) error
ReadFileText(fileID string) (string, error)
GetFileBase64(fileID string) (string, error)
PreviewImport(sourcePath string) (*ImportSummary, error)
ValidateName(name string) error
PickFile() (string, error)
PickFiles() ([]string, error)
PickDirectory() (string, error)

// Actions
ListActions(nodeID string) ([]ActionDTO, error)
CreateAction(nodeID, kind, title, data string) (*ActionDTO, error)
DeleteAction(id string) error
RunAction(id string) error

// Worklog
ListWorklog(nodeID string) ([]WorklogDTO, error)
CreateWorklog(nodeID, summary string, minutes int) (*WorklogDTO, error)

// Search
Search(query string) ([]SearchResultDTO, error)

// Activity
ListTodayView() (*TodayDashboardDTO, error)
ListActivityFeed(limit, offset int) ([]EventDTO, error)
ListActivityByNode(nodeID string, limit, offset int) ([]EventDTO, error)
CountActivityByNode(nodeID string) (int, 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 v2 GUI main

  frontend/           # Wails v2 Svelte frontend
    package.json
    vite.config.js
    src/
      App.svelte
      FileTreeRow.svelte
      lib/
        FileBreadcrumbs.svelte
        FilePreviewModal.svelte
        ConfirmModal.svelte
        FileIcon.svelte
        FileActions.svelte
        fileUtils.js
      api/verstak.js

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

  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
    007_search.sql
    008_sync.sql
    009_section.sql

RAID

  • Критично: Wails требует Node.js для frontend-сборки
  • Критично: go-sqlite3 + cgo; gcc уже установлен
  • Зависимость: Steps 15+ ждут завершения step 14 (MVP stabilization)