# Верстак — Пошаговый план разработки ## Принципы работы 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):** ```bash 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 вкладки с кнопками действий и журналом работ ### ШАГ 8 — FTS5 Search - 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//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 — реализовано) ```go // 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`: ```go 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) --- ## Phase 4: Template-Driven Architecture Implemented in this commit: - **Template system** — built-in system templates for folder, project, client, document, and recipe types. Each template defines default modules, default files (`Overview.md`), and default subfolders. - **Vault layout** — human-readable folder structure on disk. Every node gets a folder named after its title (sanitized). Nesting reflects parent-child relationships. UUIDs are never exposed in user paths. - **`.verstak/` directory** — app-internal data (db, backups, thumbnails, cache, sync, trash, history). - **i18n keys** — new locale keys for `nav.*`, `template.*`, `common.archive`, and `migrate.*` namespaces added to both `ru.json` and `en.json`. - **Documentation** — `docs/VAULT_LAYOUT.md` (vault folder structure, rules, migration) and `docs/TEMPLATES.md` (system templates, template structure JSON, UI integration).