База даних — SQLite Schema

Загальна інформація

ER Diagram (Phase 52.1)

erDiagram
    users ||--o{ projects : owns
    users ||--|| account_settings : has
    users ||--o{ recovery_keys : holds
    users ||--o{ subscriptions : pays
    users ||--o{ invites : creates
    users ||--o{ chat_messages : sends
    users ||--o{ trial_credits : claims
    users ||--o{ activity_log : generates

    projects ||--o{ project_phases : tracks
    projects ||--o{ pinned_notes : pins
    projects ||--o{ chat_messages : contains
    projects ||--o{ timeline_events : records
    projects ||--o{ github_links : links
    projects ||--o{ skill_benchmarks : runs
    projects ||--o{ marketplace_cache : caches

    github_links ||--o{ github_events : receives

    invites }o--|| users : "consumed by"
    subscriptions ||--o{ stripe_events : "logs idempotency"

    users {
        TEXT id PK
        TEXT email UK
        TEXT password_hash
        TEXT role "admin · user"
        TEXT google_id UK
        TEXT github_id UK
        INTEGER email_verified
        INTEGER two_factor_enabled
        TEXT last_login
    }

    projects {
        INTEGER id PK
        TEXT technical_name
        TEXT owner_id FK
        TEXT display_name
        TEXT notebook_id "NotebookLM"
        INTEGER is_archived
    }

    chat_messages {
        INTEGER id PK
        TEXT project_name
        TEXT worker_id
        TEXT role "user · assistant · system"
        TEXT content "AES-256-GCM if encrypted=1"
        INTEGER encrypted
        TEXT timestamp
    }

    subscriptions {
        TEXT user_id PK
        TEXT plan "free · min · max · beta"
        TEXT stripe_customer_id
        TEXT status
    }

    invites {
        TEXT code PK "arc-XXXX-XXXX"
        TEXT created_by FK
        TEXT used_by FK
        TEXT parent_invite_code
        TEXT status "active · used · revoked"
    }

    recovery_keys {
        INTEGER id PK
        TEXT user_id FK
        TEXT encrypted_key
        TEXT key_hint "first 4 chars"
    }

    trial_credits {
        TEXT email PK
        INTEGER credits_used
        TEXT first_used_at
    }

32 таблиці у 32 міграціях. Auth + проєкти + workspace-дані + intelligence + білінг + beta gating + cloud + token tracking. Усі FK-обмеження активні.

Таблиці

users — Користувачі

Колонка Тип Опис
id TEXT PK UUID
email TEXT UNIQUE Email (обов'язковий)
password_hash TEXT Хеш пароля (bcrypt)
role TEXT 'admin' або 'user'
name TEXT Ім'я
avatar_url TEXT URL аватара
google_id TEXT UNIQUE Google OAuth ID
github_id TEXT UNIQUE GitHub OAuth ID
email_verified INTEGER 0/1
two_factor_enabled INTEGER 0/1
totp_secret TEXT TOTP-секрет (2FA)
last_login TEXT ISO 8601
created_at TEXT ISO 8601

projects — Проєкти

Колонка Тип Опис
id INTEGER PK Auto
technical_name TEXT Технічне ім'я (унікальне per owner)
owner_id TEXT FK→users Власник
display_name TEXT Відображуване ім'я
description TEXT Опис
color TEXT Колір (hex)
icon TEXT Іконка
is_archived INTEGER 0/1
sort_order INTEGER Порядок (default 999)
notebook_id TEXT NotebookLM ID
project_protocol TEXT Протокол проєкту
created_at, updated_at TEXT Timestamps

UNIQUE(technical_name, owner_id)

account_settings — Налаштування акаунту

Колонка Тип Опис
user_id TEXT PK FK→users
anthropic_key TEXT Anthropic API ключ
openai_key TEXT OpenAI API ключ
name TEXT Ім'я
role TEXT Роль
auto_harvest INTEGER Автозбір навичок 0/1

chat_messages — Історія чатів

Колонка Тип Опис
id INTEGER PK Auto
project_name TEXT Проєкт
worker_id TEXT Воркер
role TEXT 'user', 'assistant', 'system'
content TEXT Текст повідомлення (зашифровано AES-256-GCM, якщо encrypted=1)
encrypted INTEGER 0=plaintext, 1=vault-encrypted (Phase 45.3)
attachments TEXT JSON-масив
timestamp TEXT ISO 8601
metadata TEXT JSON-об'єкт

INDEX(project_name, worker_id, timestamp DESC)

recovery_keys — Ключі відновлення (Phase 45.4)

Колонка Тип Опис
id INTEGER PK Auto
user_id TEXT FK→users Власник
encrypted_key TEXT Зашифрований master key
key_hint TEXT Підказка (перші 4 символи)
created_at TEXT ISO 8601
used_at TEXT Коли використано
revoked INTEGER 0=активний, 1=відкликаний

INDEX(user_id)

github_links — Прив'язки GitHub repo (Phase 49.3)

Колонка Тип Опис
id INTEGER PK Auto
project_name TEXT Arc OS project
owner TEXT GitHub repo owner
repo TEXT GitHub repo name
webhook_secret TEXT UNIQUE 32-byte hex для HMAC-SHA256 валідації
created_at TEXT ISO 8601
created_by TEXT FK→users Хто створив link

UNIQUE(project_name, owner, repo) — multi-repo на проєкт дозволено. INDEX(project_name), INDEX(webhook_secret)

github_events — Лог GitHub-подій (Phase 49.3.1)

Колонка Тип Опис
id INTEGER PK Auto
link_id INTEGER FK→github_links CASCADE при видаленні link
project_name TEXT Arc OS project (денормалізовано для швидкості запитів)
event_type TEXT push, pull_request, workflow_run, issues
action TEXT під-дія (opened/closed/success/failure)
summary TEXT Готовий рядок для відображення
url TEXT GitHub deep link
actor TEXT GitHub username
created_at TEXT ISO 8601

INDEX(project_name, created_at DESC), INDEX(link_id)

skills_global — Глобальні навички

Колонка Тип Опис
id INTEGER PK Auto
name TEXT UNIQUE Назва
description TEXT Опис
category TEXT Категорія (default 'general')
content TEXT Вміст навички (markdown)
triggers TEXT JSON-масив тригерів
keywords TEXT JSON-масив ключових слів
eval_rules TEXT JSON-масив правил
tool_code_ts TEXT TypeScript-реалізація
version INTEGER Версія (auto-increment)
status TEXT 'active', 'draft', 'deprecated', 'archived'

skills_project_forks — Форки навичок

Колонка Тип Опис
id INTEGER PK Auto
project_name TEXT Проєкт
skill_id INTEGER FK→skills_global Батьківська навичка (CASCADE)
content TEXT Кастомізований вміст
triggers, keywords, eval_rules, tool_code_ts TEXT Перевизначення
version INTEGER Версія форку

UNIQUE(project_name, skill_id)

skill_evolution_logs — Історія змін навичок

Колонка Тип Опис
id INTEGER PK
skill_id INTEGER FK CASCADE
project_name TEXT Проєкт (nullable)
action TEXT 'created', 'modified', 'applied', 'reverted'
diff_summary TEXT Опис змін
author TEXT Автор (default 'system')
metadata TEXT JSON

skill_update_requests — PR навичок (Sage)

Колонка Тип Опис
id INTEGER PK
skill_id INTEGER FK CASCADE
proposed_by TEXT 'sage' (default)
status TEXT 'pending', 'approved', 'rejected', 'applied'
current_content TEXT Поточна версія
proposed_content TEXT Запропонована версія
reason TEXT Причина зміни

skill_benchmarks — A/B-тести навичок

Колонка Тип Опис
id INTEGER PK
request_id INTEGER FK→skill_update_requests CASCADE
test_scenario TEXT Сценарій тесту
old_output, new_output TEXT Результати
score_old, score_new REAL Оцінки
judgment_reason TEXT Обґрунтування

pinned_notes — Закріплені нотатки

Колонка Тип Опис
id INTEGER PK
project_name TEXT Проєкт
worker_id TEXT Воркер
title TEXT Заголовок
body TEXT Текст
source_message_id INTEGER Посилання на chat_messages

project_phases — Фази Roadmap

Колонка Тип Опис
id INTEGER PK
project_name TEXT Проєкт
phase_id INTEGER Номер фази
phase_title TEXT Назва
status TEXT 'PLANNED', 'ACTIVE', 'COMPLETED', 'CANCELLED'
progress REAL 0.0–1.0
deadline TEXT ISO 8601

UNIQUE(project_name, phase_id)

activity_log — Журнал активності

Колонка Тип Опис
id INTEGER PK
project_name TEXT Проєкт
actor TEXT Воркер або користувач
event_type TEXT Тип події
title TEXT Опис
metadata TEXT JSON
created_at TEXT ISO 8601

INDEX(created_at DESC), INDEX(project_name, created_at DESC), INDEX(event_type, created_at DESC), INDEX(actor, created_at DESC)

system_configs — Системні налаштування

Колонка Тип Опис
key TEXT PK Ключ
value TEXT Значення
description TEXT Опис

marketplace_analysis_cache — Кеш маркетплейсу

Кеш аналізу сумісності навичок з маркетплейсу.

ephemeral_tokens — Короткоживучі токени (issue #27)

Persistent-сховище для одноразових токенів OAuth state, password reset та email verification. До міграції 022 ці токени жили в in-memory Map і губилися при кожному рестарті master, ламаючи Google/GitHub login (invalid_state).

Колонка Тип Опис
token TEXT PK 32-байтний hex (randomBytes(32))
type TEXT NOT NULL oauth_state | password_reset | email_verification
payload TEXT NOT NULL JSON: {provider} для oauth_state, {email} для решти
expires_at INTEGER NOT NULL ms epoch — TTL: 10 хв (oauth) / 30 хв (reset) / 24 год (verify)

INDEX(type), INDEX(expires_at). Одноразове використання: consume() в одній транзакції читає payload і видаляє рядок.

Міграції

# Назва Фаза Що додає
001 initial_schema Phase 40 users, projects, account_settings
002 project_protocol Phase 40.7 projects.project_protocol
003 chat_messages Phase 40.10 chat_messages
004 skill_system Phase 41 skills_global, skills_project_forks, skill_evolution_logs, skill_update_requests
005 skill_benchmarks Phase 40.11d skill_benchmarks
006 system_configs system_configs + FIGMA_CACHE_ROOT
007 marketplace_cache Phase 40.12.1 marketplace_analysis_cache
008 harvester Phase 40.13 +is_suggestion, +source_query, +auto_harvest
009 pinned_notes Phase 41.8 pinned_notes
010 project_phases Phase 44 project_phases
011 activity_log Phase 44.1 activity_log
012 performance_indexes Perf Audit +idx_activity_log_actor, +idx_chat_msg_role_ts
013 timeline_timestamps Phase 47 +timestamp на повідомленнях воркерів
014 timeline_events Phase 47 таблиця timeline_events
015 e2ee_chat Phase 45.3 +колонка encrypted у chat_messages
016 recovery_keys Phase 45.4 таблиця recovery_keys
017 github_links Phase 49.3 таблиця github_links (webhook bindings)
018 github_events Phase 49.3.1 таблиця github_events (event log для UI feed)
019 trial_credits Phase 50.1 +users.trial_granted_at, +projects.trial_mode, +projects.trial_tokens_remaining
020 subscriptions Phase 51 таблиця subscriptions (plan, stripe_customer_id, status, feature_flags) + лог ідемпотентності stripe_events
021 invites Phase 52.1 таблиця invites (closed beta enrollment) — code, created_by, used_by, parent_invite_code, status, note
022 ephemeral_tokens issue #27 таблиця ephemeral_tokens — persistent OAuth state / password reset / email verification замість in-memory Map (фікс invalid_state на рестарті master)
023 project_issues Phase 53.14 / issue #53 таблиця project_issues (composite PK project_name+id, JSON labels/activity) — переносить issues storage з issues/issues.json у SQLite SSOT, JSON стає derived mirror; ліквідовує text-merge drift на deploy
024 context_exports Phase 56.4 + 56.5 / issues #100 + #101 export_audit_log (id PK, project_name, owner_id, exported_at, sections JSON, findings_critical/high/medium/low INT, bytes) + export_preferences (project_name PK, always_include_emails BOOL, auto_redact_critical BOOL DEFAULT 1, notify_on_export BOOL DEFAULT 0, updated_at) — за-проєктна audit history для Project Context Export + per-project policy toggles; alert при ≥3 exports/24h коли notify_on_export = true
025 onboarding_progress Phase 54.1 / issue #56 onboarding_progress (chat_id PK, JSON state per 5 steps, completed_count derived, started_at/completed_at/dismissed_at, source web|cli) — derived cache над activity_log event stream; SSOT = події event_type LIKE 'onboarding_%'; recordEvent ідемпотентний, dismiss/replay non-destructive
026 platform_audit_log Phase 57 / Sentinel #103 platform_audit_log (id PK AUTOINCREMENT, ts, user_chat_id, user_email, action, key_name, ip, result, user_agent) — append-only audit trail для super-admin Platform Settings UI мутацій vault secrets. 3 indexes: idx_platform_audit_ts/user/key. No UPDATE/DELETE — read-only через platformAuditQueries.recent + lastRotated
027 auth_events Issue #130 auth_events (id PK AUTOINCREMENT, ts, event, provider, user_id, email, ip, user_agent, result, meta JSON) — append-only лог IP + auth подій. Events: signup/login/oauth_login/magic_link/device_code_approve. Results: success/failed/rate_limited/invalid_invite/already_registered/2fa_required/invalid_token. 4 indexes: ts/user_id/ip/event+result
028 managed_containers Phase 60 #135/#136 managed_containers (id TEXT PK (docker container name), user_id, status (provisioning|ready|paused|suspended|deleted), server_ip, internal_port INT, claude_authed INT, github_authed INT, created_at, last_active) — реєстр Docker-контейнерів 1-на-користувача для Standard Cloud. managedContainerQueries.findByUser/insert/updateStatus/setAuthFlag/touch/listActive у shared/db.ts. Endpoints: POST /api/crm/cloud/provision, GET /status, POST /deprovision у shared/routes/cloud.ts
029 cloud_waitlist Phase 60 #134 cloud_waitlist (id INT PK AUTOINCREMENT, user_id TEXT UNIQUE, email, position INT, status (waiting|invited|activated|declined), notes, joined_at, invited_at, activated_at) — список очікування Early Access для Standard Cloud. cloudWaitlistQueries.join/findByUser/list/invite/activate/decline/stats у shared/db.ts. Endpoints: POST /api/crm/cloud/waitlist (вступити), GET /waitlist/status (власний статус), GET /waitlist (список для admin), POST /waitlist/invite (admin активує + upgrade план до cloud)
030 translation_feedback Phase 59.4 #122 translation_feedback (id INT PK AUTOINCREMENT, locale TEXT, message_id TEXT, original TEXT, current_translation TEXT, suggestion TEXT, user_id TEXT, status (pending|accepted|rejected), created_at, reviewed_at) — Per-locale feedback якості перекладів. Admin review dashboard на /api/crm/translations/feedback (list/stats/accept/reject).
031 token_usage_log Phase 63 #148 token_usage_log (id INT PK AUTOINCREMENT, project_name TEXT NOT NULL, owner_id TEXT NOT NULL, worker_id TEXT, input_tokens INT DEFAULT 0, output_tokens INT DEFAULT 0, cache_tokens INT DEFAULT 0, total_tokens INT DEFAULT 0, created_at INT DEFAULT (unixepoch())) — Per-request лог використання токенів Claude. 3 indexes: owner_id, project_name, created_at. Заповнюється з child-bot/claude-runner.ts через POST /api/internal/usage/log (fire-and-forget). Запитується через GET /api/crm/account/usage → повертає { rows: [...останні 200], totals: { total, input, output } } для BillingPage + UserDropdown UsageCard.
032 arc_help_usage Phase 61 #147 arc_help_usage (id INT PK AUTOINCREMENT, user_id TEXT NOT NULL, date TEXT NOT NULL (YYYY-MM-DD), count INT NOT NULL DEFAULT 0, PRIMARY KEY (user_id, date)) — Щоденний лічильник rate-limit для вбудованого чату AI-допомоги (30 повідомлень/день). Запитується через GET /api/crm/help/usage; оновлюється при POST /api/crm/help/chat.

Зв'язки (Foreign Keys)

Усі CASCADE — видалення навички видаляє всі форки, історію, PR та бенчмарки.

ER-діаграма (текстова)

users ─1:N──> projects
            ├── chat_messages
            ├── pinned_notes
            ├── project_phases
            └── skills_project_forks ──> skills_global
                                          ├── skill_evolution_logs
                                          ├── skill_update_requests
                                          │    └── skill_benchmarks
                                          └── (standalone tables)
                                               ├── activity_log
                                               ├── system_configs
                                               └── marketplace_analysis_cache