verstak/docs/PLAN.md

324 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Верстак — Пошаговый план разработки
## Принципы работы
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** | 🔄 в процессе |
| 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`).
---
## Выполненные шаги (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/<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 (минимум)
```go
// 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`:
```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 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