verstak/docs/03_Data_Model_Storage.md

291 lines
6.2 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. Vault
Пример структуры:
```text
~/VerstakVault/
.verstak/
index.db
config.yml
device.yml
sync_state.db
trash/
history/
originals/
thumbnails/
spaces/
clients/
romashka/
case.yml
overview.md
notes/
nginx.md
mysql-cleanup.md
access.secret.md.enc
documents/
dogovor-2026.docx
sluzhebka.pdf
screenshots/
error-form.png
scripts/
backup-site.sh
cleanup.sql
actions/
open-admin.yml
worklog/
2026-05.md
```
## 2. SQLite schema MVP
### nodes
```sql
CREATE TABLE nodes (
id TEXT PRIMARY KEY,
parent_id TEXT NULL REFERENCES nodes(id),
type TEXT NOT NULL,
title TEXT NOT NULL,
slug TEXT NOT NULL,
path TEXT NULL,
sort_order INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
deleted_at TEXT NULL,
revision INTEGER NOT NULL DEFAULT 1,
device_id TEXT NULL
);
```
### node_meta
```sql
CREATE TABLE node_meta (
node_id TEXT NOT NULL REFERENCES nodes(id),
key TEXT NOT NULL,
value TEXT NOT NULL,
PRIMARY KEY (node_id, key)
);
```
### files
```sql
CREATE TABLE files (
id TEXT PRIMARY KEY,
node_id TEXT NOT NULL REFERENCES nodes(id),
filename TEXT NOT NULL,
path TEXT NOT NULL,
storage_mode TEXT NOT NULL, -- vault | external
size INTEGER NOT NULL DEFAULT 0,
sha256 TEXT NULL,
mime TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
last_seen_at TEXT NULL,
missing INTEGER NOT NULL DEFAULT 0
);
```
### notes
```sql
CREATE TABLE notes (
node_id TEXT PRIMARY KEY REFERENCES nodes(id),
file_id TEXT NOT NULL REFERENCES files(id),
format TEXT NOT NULL DEFAULT 'markdown',
original_format TEXT NULL,
encrypted INTEGER NOT NULL DEFAULT 0
);
```
### actions
```sql
CREATE TABLE actions (
id TEXT PRIMARY KEY,
node_id TEXT NOT NULL REFERENCES nodes(id),
title TEXT NOT NULL,
kind TEXT NOT NULL,
command TEXT NULL,
args_json TEXT NULL,
working_dir TEXT NULL,
url TEXT NULL,
confirm_required INTEGER NOT NULL DEFAULT 0,
capture_output INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
```
### worklog_entries
```sql
CREATE TABLE worklog_entries (
id TEXT PRIMARY KEY,
node_id TEXT NOT NULL REFERENCES nodes(id),
started_at TEXT NULL,
ended_at TEXT NULL,
date TEXT NOT NULL,
minutes INTEGER NULL,
approximate INTEGER NOT NULL DEFAULT 1,
billable INTEGER NOT NULL DEFAULT 0,
summary TEXT NOT NULL,
details TEXT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
```
### activity_events
```sql
CREATE TABLE activity_events (
id TEXT PRIMARY KEY,
node_id TEXT NULL REFERENCES nodes(id),
source TEXT NOT NULL,
event_type TEXT NOT NULL,
title TEXT NULL,
path TEXT NULL,
url TEXT NULL,
app_name TEXT NULL,
process_name TEXT NULL,
started_at TEXT NOT NULL,
ended_at TEXT NULL,
duration_seconds INTEGER NULL,
metadata_json TEXT NULL,
confidence INTEGER NOT NULL DEFAULT 100,
created_at TEXT NOT NULL
);
```
### worklog_suggestions
```sql
CREATE TABLE worklog_suggestions (
id TEXT PRIMARY KEY,
node_id TEXT NOT NULL REFERENCES nodes(id),
date TEXT NOT NULL,
started_at TEXT NULL,
ended_at TEXT NULL,
suggested_minutes INTEGER NULL,
summary TEXT NOT NULL,
evidence_json TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
```
### search_index
```sql
CREATE VIRTUAL TABLE search_index USING fts5(
node_id UNINDEXED,
title,
content,
path,
tags,
type
);
```
### sync_ops
```sql
CREATE TABLE sync_ops (
id TEXT PRIMARY KEY,
op_id TEXT NOT NULL UNIQUE,
device_id TEXT NOT NULL,
entity_type TEXT NOT NULL,
entity_id TEXT NOT NULL,
op_type TEXT NOT NULL,
payload_json TEXT NOT NULL,
created_at TEXT NOT NULL,
pushed_at TEXT NULL,
applied_at TEXT NULL
);
```
## 3. Правила хранения
### Заметки
- physical `.md` file;
- metadata in SQLite;
- backup old version before overwrite.
### Документы
- physical file;
- open with system app;
- metadata in SQLite.
### Secret notes
- encrypted file, e.g. `access.secret.md.enc`;
- no FTS indexing;
- no logs with plaintext;
- master password later.
### Удаление
- soft delete node;
- file to `.verstak/trash`;
- sync tombstone;
- physical cleanup only after retention.
## 4. Sync operations
Каждое изменение должно создавать operation:
- node_create;
- node_update;
- node_move;
- node_delete;
- file_add;
- file_update;
- file_delete;
- note_update;
- action_update;
- worklog_create;
- worklog_update.
Даже если sync ещё не реализован, operation log лучше заложить рано.
## 5. Индексация
Индексировать:
- node titles;
- note content;
- filenames;
- paths;
- worklog summaries/details;
- action titles;
- links.
Не индексировать:
- secret notes;
- private keys;
- token-like values;
- binary content in MVP.
## 6. Расширяемость через плагины
Базовая схема фиксирована и поддерживает плагины:
- Новые типы нод регистрируются плагинами через Lua API
(`verstak.node.register_type()`) — схема таблицы `nodes` не меняется,
`type` принимает любое строковое значение.
- Мета-поля (`node_meta`) хранят произвольные key-value пары,
зарегистрированные плагинами.
- Плагины могут создавать собственные таблицы через SQL-миграции
в своей директории `.verstak/plugins/<name>/migrations/`.
- `device_id` на уровне nodes позволяет плагинам синхронизировать
свои данные через sync_ops.