verstak-docs/02_Platform_Architecture.md

278 lines
9.3 KiB
Markdown
Raw Permalink 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.

# Verstak Platform Architecture
## 1. Общая схема
```text
+----------------------+
| UI Shell |
| windows, layout, |
| command palette, |
| settings, toasts |
+----------+-----------+
|
+----------v-----------+
| Core Platform |
| plugin manager, |
| capabilities, |
| permissions, events |
+----------+-----------+
|
+-------------------+-------------------+
| | |
+-------v--------+ +-------v--------+ +-------v--------+
| Local Vault | | Storage API | | Sync Boundary |
| files, notes, | | SQLite, index, | | client adapter |
| assets, trash | | migrations | | not core truth |
+-------+--------+ +-------+--------+ +-------+--------+
| | |
+-------------------+-------------------+
|
+----------v-----------+
| Dynamic Plugins |
| official and third |
| party packages |
+----------------------+
```
## 2. Core Platform
Core Platform - минимальное ядро приложения. Оно не содержит бизнес-функции пользователя. Его задача - дать среду, в которую плагины безопасно подключают рабочие инструменты.
Core отвечает за:
- запуск приложения;
- открытие и проверку vault;
- загрузку и выгрузку плагинов;
- enable/disable состояние плагинов;
- capability registry;
- contribution points;
- settings registry;
- permissions;
- event bus;
- storage API;
- vault file API;
- command registry;
- diagnostics;
- sync boundary.
Core не должен импортировать конкретные плагины как обязательные модули.
## 3. UI Shell
UI Shell - общий интерфейс платформы:
- главное окно;
- навигация;
- вкладки и панели;
- command palette;
- global search entry point;
- settings window;
- plugin manager window;
- dialogs/toasts;
- error boundary для plugin UI.
UI Shell не знает, что такое notes editor или file preview как конкретная реализация. Он знает contribution points:
- sidebar items;
- main views;
- case tabs;
- file actions;
- note actions;
- context menu entries;
- settings panels;
- command palette commands;
- status bar items;
- activity cards;
- search providers.
## 4. Vault
Vault остается пользовательским рабочим пространством. Он должен быть максимально понятным снаружи.
Пример:
```text
VerstakVault/
.verstak/
db.sqlite
config.json
plugins/
plugin-state/
cache/
trash/
Clients/
Romashka/
Notes/
Overview.md
Files/
Screenshots/
Projects/
```
Правила:
- пользовательские документы не прячутся в непрозрачные blob-таблицы без необходимости;
- SQLite хранит индексы, связи, историю, состояние UI, plugin metadata;
- файловая структура должна оставаться пригодной для ручного восстановления;
- имена заметок и файлов остаются человекочитаемыми;
- sync не является единственным способом доступа к данным.
## 5. Plugin Runtime
Плагины загружаются динамически из каталогов. Официальные плагины используют тот же механизм, что и сторонние.
Папки плагинов:
```text
VerstakVault/.verstak/plugins/
official.files/
official.notes/
official.markdown-editor/
~/.config/verstak/plugins/
user.local-plugin/
```
Порядок загрузки:
1. Найти plugin manifests.
2. Проверить schemaVersion и apiVersion.
3. Проверить enabled/disabled state.
4. Проверить обязательные capabilities.
5. Запросить permissions.
6. Запустить backend sidecar, если нужен.
7. Загрузить frontend bundle, если нужен.
8. Принять регистрации capabilities и contributions.
9. Перевести плагин в состояние loaded/degraded/failed/incompatible.
## 6. Backend Model
Не использовать Go `plugin` как основной механизм. Он плохо подходит для кроссплатформенного desktop-приложения из-за ABI, версий компилятора и сборки под разные ОС.
Предпочтительная модель:
- плагин может быть pure frontend;
- плагин может быть pure manifest/data;
- плагин может иметь backend sidecar;
- sidecar общается с core через локальный RPC;
- core выдает sidecar только разрешенные API;
- прямой произвольный доступ к vault и OS запрещен по умолчанию.
Sidecar может быть написан на Go, Rust, Python или другом языке, если он соблюдает протокол.
## 7. Frontend Model
Плагин поставляет frontend bundle:
```text
frontend/
index.js
style.css
```
Frontend bundle не должен напрямую обращаться к Wails backend methods как к глобальному хаосу. Он работает через `VerstakPluginAPI`, который предоставляет:
- registerView;
- registerSettingsPanel;
- registerCommand;
- registerFileAction;
- callBackend;
- readSettings/writeSettings;
- subscribe/publish events;
- requestCapability.
## 8. Capability Registry
Плагины связываются не по имени друг друга, а через capabilities.
Пример:
```text
editor.text
editor.text.markdown
viewer.file
viewer.image
preview.markdown
workspace.files
workspace.notes
capture.browser
activity.provider
secret-store
search.provider
```
Файловый плагин не зависит от `official.markdown-editor`. Он проверяет, есть ли capability `editor.text.markdown`. Если есть - показывает действие "Редактировать". Если нет - действие не появляется.
## 9. Plugin Manager UI
Core обязан иметь окно управления плагинами с первого платформенного этапа.
Функции:
- список установленных плагинов;
- enable/disable;
- status: loaded, disabled, failed, incompatible, degraded;
- version и apiVersion;
- source: official, local, third-party;
- capabilities provided;
- required/optional capabilities;
- permissions;
- кнопка "Settings", если плагин предоставляет settings panels;
- diagnostics/error log.
Выключение плагина не удаляет пользовательские данные.
## 10. Settings Registry
Настройки плагинов не должны быть произвольными экранами, спрятанными в разных местах.
Плагин регистрирует settings panels:
```json
{
"contributes": {
"settingsPanels": [
{
"id": "official.notes.general",
"title": "Notes",
"component": "settings.general"
}
]
}
}
```
Core показывает кнопку настроек у выбранного плагина и открывает соответствующую панель/окно.
## 11. Event Bus
Event bus связывает плагины без прямых импортов.
Примеры событий:
- `vault.opened`;
- `case.selected`;
- `file.added`;
- `file.changed`;
- `note.saved`;
- `activity.recorded`;
- `browser.capture.received`;
- `plugin.enabled`;
- `plugin.disabled`.
События должны иметь стабильные схемы. Плагин не должен полагаться на приватные поля другого плагина.
## 12. Sync Boundary
Sync server и browser extension выносятся в отдельные репозитории, но должны использовать общие protocol contracts.
Sync не должен знать о внутренних UI-плагинах. Он синхронизирует:
- vault metadata;
- files/blobs;
- plugin state where allowed;
- plugin data через зарегистрированные storage namespaces.
Плагины должны явно указывать, какие данные можно синхронизировать, а какие локальны только на устройстве.