feat: ШАГ 1 — Bridge HTTP-сервер для браузерного расширения

- internal/core/bridge/ — лёгкий HTTP-сервер на 127.0.0.1
  - POST /api/events — приём батча событий от расширения
  - GET /api/ping — healthcheck для расширения
  - X-Verstak-Secret — аутентификация по shared-secret
  - AutoGenPort — случайный порт если 9786 занят
- config.BridgeConfig — порт, секрет, auto_gen_port
- App: интеграция startBridge/stopBridge при open/close vault
- bindings_bridge.go — BridgeInfo(), startBridge(), saveBridgeConfig()
- Тесты: ping, auth, success, empty batch, secret gen, auto-port
This commit is contained in:
2026-06-06 18:23:47 +08:00
parent f88376264d
commit 358c649b42
20 changed files with 1676 additions and 21 deletions
+55 -5
View File
@@ -193,12 +193,62 @@ Core service extensions:
---
## Ожидающие шаги (17-23)
## Завершённый этап: ШАГ 17 — File Scanner/Watcher
### ШАГ 17 — File Scanner/Watcher
- fsnotify watcher на vault
- snapshot scanner для обнаружения изменений при закрытом приложении
- обнаружение missing файлов
**Статус:** ✅ выполнено
Что реализовано:
- `internal/core/watcher/scanner.go` — Snapshot scanner:
- Итерирует все ноды с FsPath, сканирует их директории на диске
- Детектит missing файлы (запись в БД есть — файла нет) → MarkMissing + activity event
- Детектит restored файлы (был missing — снова на диске) → MarkMissing(false) + activity event
- Детектит modified файлы (SHA256 не совпал) → обновление размера/SHA в БД + activity event
- Считает new файлы на диске без записи в БД (не авто-добавляет, только счётчик)
- Пропускает `.verstak/` и скрытые директории
- `internal/core/watcher/watcher.go` — fsnotify Watcher:
- Реальное время: CREATE/REMOVE/RENAME/WRITE события
- Debounce 2 секунды для группировки burst-событий
- CREATE → авто-добавление file record + `file_added` event
- REMOVE → MarkMissing(true) + `file_deleted` event
- WRITE → обновление SHA256 + `file_modified` event
- Рекурсивное добавление watcher-ов на поддиректории
- Пропускает скрытые файлы и `.verstak/`
- `internal/core/watcher/service.go` — Объединённый сервис:
- Start(enableWatcher) → snapshot scan + опционально запуск real-time watcher
- Stop() → остановка watcher
- RunScanner() → одноразовое сканирование
- `internal/core/activity/activity.go` — Новые типы событий: `file_modified`, `file_restored`
- `internal/core/storage/migrations_017.sql.go` — Таблица `watcher_state` для трекинга состояния файлов
- `internal/core/config/appconfig.go` — Настройка `Vault.FileWatcher` (по умолчанию true)
- `cmd/verstak-gui/app.go` — Интеграция в App: initVault запускает сканер + watcher, closeVault останавливает
- `cmd/verstak-gui/bindings_watcher.go` — Bindings: WatcherStatus(), RunSnapshotScan(), ToggleFileWatcher()
- `internal/core/watcher/watcher_test.go` — 5 тестов: no changes, missing, restored, modified, hidden filter
- `internal/core/files/file.go` — Новые методы: ListAllVault(), ListAllVaultWithTrashed()
- `internal/core/nodes/repository.go` — Новый метод: ListAllWithFsPath()
### Как включить/отключить
| Способ | Команда | Действие |
|--------|---------|----------|
| **GUI** | Settings → "File Watcher" toggle | Вкл/выкл real-time, snapshot всегда |
| **Config** | `~/.config/verstak/config.json``vault.file_watcher: false` | Навсегда |
| **Env** | `VERSTAK_NO_WATCHER=1 ./verstak-gui` | На сессию (переопределяет config) |
| **CLI** | `./verstak-gui --no-watcher` | Один запуск (переопределяет всё) |
Важно: **snapshot scan** (сверка диска с БД) выполняется ВСЕГДА при открытии vault.
Real-time fsnotify watcher управляется отдельно.
### Как проверить что работает
После запуска в логе:
```
[watcher] snapshot: 0 missing, 0 restored, 0 modified, 0 new
```
Через GUI: `WatcherStatus()` — true если watcher активен.
Через консоль (отладка): создать/удалить файл в vault → в activity появятся события `file_added`/`file_missing`/`file_modified`.
## Ожидающие шаги (18-23)
### ШАГ 18 — TUI MVP (Bubble Tea)
- Терминальный интерфейс: дерево дел, поиск, добавление worklog, запуск действий, sync