278 lines
9.3 KiB
Markdown
278 lines
9.3 KiB
Markdown
# 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.
|
||
|
||
Плагины должны явно указывать, какие данные можно синхронизировать, а какие локальны только на устройстве.
|
||
|