Skip to content

Commit 90c2b6c

Browse files
committed
docs: PRD for minimal usage dashboard (search, mcp, bot, tunnel, landing)
Made-with: Cursor
1 parent 9e288bf commit 90c2b6c

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ npm-пакет `mcp-tma-client` в `packages/mcp-tma-client/`. Работает
260260
}
261261
```
262262

263+
## Спецификации (PRD)
264+
265+
- `docs/PRD-public-knowledge-search-service.md` — публичный `/knowledge` API
266+
- `docs/PRD-usage-dashboard-minimal.md` — минимальная панель использования (search, mcp, bot, tunnel, landing)
267+
263268
## Структура проекта
264269

265270
```
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# PRD: минимальная панель использования платформы (Usage Dashboard)
2+
3+
**Версия документа:** 0.1
4+
**Дата:** 2026-03-25
5+
**Статус:** черновик требований (без реализации)
6+
7+
---
8+
9+
## 1. Резюме
10+
11+
Нужна **минимальная операторская панель** (read-only), показывающая **сводное использование** платформы SpawnDock: сколько уникальных **субъектов** активны, **как израсходованы лимиты** (где применимы) и **какие из пяти контролируемых сервисов** задействованы.
12+
13+
**Контролируемые сервисы (обязательная сегментация в отчётах):**
14+
15+
| ID | Компонент | Типовой вход / заметка |
16+
|---------|------------------|-------------------------|
17+
| `search` | Knowledge search | Публичный `POST /knowledge/api/v1/search`, внутренние вызовы MCP → search |
18+
| `mcp` | MCP / control plane | `mcp-server`: HTTP/SSE, инструменты, preview и пр. |
19+
| `bot` | Telegram bot | Polling/webhook, команды, выдача токенов |
20+
| `tunnel`| Dev tunnel | Клиенты `dev-tunnel`, WebSocket к control plane |
21+
| `landing` | Лендинг / статика | Трафик на корневой лендинг за Caddy (не API) |
22+
23+
Панель **не заменяет** полноценный APM (Grafana/Prometheus); цель — **единый минимальный обзор** для оператора на одном экране или двух.
24+
25+
---
26+
27+
## 2. Цели и критерии успеха
28+
29+
| ID | Цель | Сигнал успеха |
30+
|----|------|----------------|
31+
| G1 | Видимость **активности по сервисам** | В панели отображаются счётчики/серии хотя бы за **24ч / 7д** по пяти ID выше |
32+
| G2 | Видимость **лимитов** там, где они уже есть | Для **search** — попадания в квоты (free/basic), **429**, необязательно поминутно в v0 |
33+
| G3 | Видимость **«пользователей»** в разумном определении | Оператор видит **число уникальных субъектов** и разбивку по типу (см. §4) без ручного сбора логов |
34+
| G4 | **Безопасность** | Панель недоступна публично; доступ только **операторам** (см. §8) |
35+
| G5 | **Минимализм** | MVP без биллинга, без self-service для конечных пользователей |
36+
37+
---
38+
39+
## 3. Не в scope (v0)
40+
41+
- Оплата, счета, лимиты «pro/enterprise» как продукт.
42+
- Редактирование квот или блокировка пользователей из UI (только просмотр; действия — вне v0 или отдельный PRD).
43+
- Гарантия 100% сквозной идентичности «один человек = один user_id» между Telegram, браузером и MCP (см. §4.3).
44+
- Хостинг панели на том же публичном префиксе, что и лендинг, **без** отдельной аутентификации.
45+
46+
---
47+
48+
## 4. Определения: «пользователь» и учёт
49+
50+
### 4.1 Субъект (actor)
51+
52+
Минимальная модель данных для агрегации:
53+
54+
- **`actor_type`**: `api_token` | `telegram_user` | `anonymous_ip` | `tunnel_client` | `unknown`
55+
- **`actor_key`**: стабильный строковый идентификатор **без** хранения секретов в открытом виде:
56+
- `api_token`**хэш** токена (например SHA-256 с солью из env) или внутренний `token_id`, если позже появится таблица токенов
57+
- `telegram_user``telegram_user_id` (число)
58+
- `anonymous_ip` → IP за доверенным прокси (как в search free-tier)
59+
- `tunnel_client` → стабильный client/session id из протокола tunnel (уточнить при инструментировании)
60+
61+
### 4.2 Связь actor ↔ сервис
62+
63+
Каждое значимое событие учёта помечается **`service`** ∈ { `search`, `mcp`, `bot`, `tunnel`, `landing` }.
64+
65+
Один субъект может появляться в **нескольких** сервисах; панель показывает **пересечения** (например «только search», «mcp+bot», таблица или sankey — опционально в v1).
66+
67+
### 4.3 Ограничения идентификации
68+
69+
- **Landing**: чаще всего **без** логина — учёт по **сессии** (cookie/анонимный id) или только агрегаты (просмотры/UV по IP+fingerprint — v1, мягко).
70+
- **MCP с токеном** и **бот** могут относиться к одному человеку; в v0 допустима **дубликатная** учётная запись в статистике с пометкой «разные actor_type».
71+
72+
---
73+
74+
## 5. Требования к данным по сервисам
75+
76+
### 5.1 `search`
77+
78+
**Уже есть (концептуально):** free/basic tier, лимиты per minute / per day, различие публичного трафика ( `X-Forwarded-For` ) и внутреннего MCP.
79+
80+
**Нужно для панели (instrumentation):**
81+
82+
- Счётчики: `requests_ok`, `requests_429`, по **`tier`** (`free` / `basic`).
83+
- Разрез по **`actor_key`** (для basic — hash токена; для free — IP или сегмент).
84+
- Опционально: доля **cache_hit** из `meta` (если включён кэш search).
85+
86+
**Источник:** метрики из процесса `search` (экспорт Prometheus, stdout JSON, или периодический сброс в SQLite/Redis — решение implementer pass).
87+
88+
### 5.2 `mcp`
89+
90+
**Нужно:**
91+
92+
- Счётчики запросов к **чувствительным** маршрутам: например SSE/MCP сессии, вызовы инструментов (хотя бы суммарно).
93+
- При наличии **Bearer / сессии** — привязка к `api_token` hash или внутреннему session id.
94+
95+
**Источник:** middleware в `mcp-server` (`repo/api`), единый формат лог-события `service=mcp`.
96+
97+
### 5.3 `bot`
98+
99+
**Нужно:**
100+
101+
- События: команды (`/start`, `/gettoken`, и т.д.), активные пользователи за окно.
102+
- **`actor_key`** = `telegram_user_id`.
103+
104+
**Источник:** hooks в `repo/api` bot polling; избегать логирования секретов.
105+
106+
### 5.4 `tunnel`
107+
108+
**Нужно:**
109+
110+
- Подключения / сессии / переданные байты (минимум: **число активных / новых сессий** за период).
111+
- Идентификатор клиента — из протокола `repo/dev-tunnel` и бэкенда.
112+
113+
**Источник:** control plane в `repo/api` + при необходимости агент `dev-tunnel`.
114+
115+
### 5.5 `landing`
116+
117+
**Нужно:**
118+
119+
- Базовые **визиты** (page views), опционально **уникальные** по дню.
120+
- Без PII в сыром виде в панели.
121+
122+
**Источник:** access log Caddy (разбор на edge) или лёгкий **pixel/counter** endpoint за отдельным путём с rate limit.
123+
124+
---
125+
126+
## 6. Функциональные требования (MVP панели)
127+
128+
### 6.1 Экран «Обзор»
129+
130+
- Карточки за период **24ч / 7д** (переключатель):
131+
- **Активные субъекты** (уникальные `actor_key`, с разбивкой по `actor_type`).
132+
- **События по сервисам** — столбчатая или таблица: `search` | `mcp` | `bot` | `tunnel` | `landing`.
133+
- **Search limits:** суммарно **429**, запросы **ok**, (если доступно) **остаток** до дневного/минутного лимита **в агрегате** по tier.
134+
135+
### 6.2 Экран или блок «Search detail»
136+
137+
- Таблица топ-N **субъектов** по числу запросов (обезличенно: префикс хэша, не токен).
138+
- График или счётчик **429** по времени.
139+
140+
### 6.3 Экран или блок «Сервисы × субъекты» (v0.5, желательно)
141+
142+
- Матрица: сколько субъектов касалось каждого сервиса; простая **venn-подобная** сводка или мультивыбор фильтра.
143+
144+
### 6.4 Обновление данных
145+
146+
- Задержка **≤ 1–5 мин** для агрегатов (достаточно batch/offline rollups).
147+
148+
---
149+
150+
## 7. Нефункциональные требования
151+
152+
- **Retention сырых событий:** v0 — 7–30 дней (конфигурируемо); агрегаты — дольше.
153+
- **Производительность:** панель не должна сканировать полные текстовые логи в runtime; только БД/TSDB.
154+
- **GDPR/приватность:** не хранить содержимое запросов search в таблицах панели; максимум длина/хэш для отладки — отдельный флаг.
155+
156+
---
157+
158+
## 8. Безопасность и доступ
159+
160+
- URL панели **не** индексировать; **отдельный** admin-префикс (например `/ops/usage`) за Caddy.
161+
- Аутентификация v0: **HTTP Basic** с паролем из env, **или** OIDC позже, **или** VPN-only + IP allowlist (решение ops).
162+
- Роль: только `operator`; аудит входов — желательно (лог).
163+
164+
---
165+
166+
## 9. Зависимости и фазы
167+
168+
### Фаза 0 — контракт событий
169+
170+
- Ввести единую схему **usage event**: `{ ts, service, event_type, actor_type, actor_key, tier?, status?, bytes? }`.
171+
- Писать в **одно** хранилище (SQLite на VPS / Postgres / ClickHouse lite — выбрать по нагрузке).
172+
173+
### Фаза 1 — сборщики
174+
175+
- Инструментирование **search**, **mcp**, **bot** (минимум).
176+
- **tunnel** и **landing** — следующими PR.
177+
178+
### Фаза 2 — UI
179+
180+
- Один сервис **static+api** или Next.js micro-app в монорепе; **или** Grafana dashboard + документация, если UI «панели» = дашборд (explicit decision).
181+
182+
---
183+
184+
## 10. Открытые вопросы
185+
186+
1. Единый **Postgres** для control plane + usage или отдельная БД?
187+
2. Нужен ли **экспорт CSV** для оператора в v0?
188+
3. Согласовать **имена сервисов** с метриками infra (Kubernetes labels и т.д.), если появятся.
189+
190+
---
191+
192+
## 11. Связанные документы
193+
194+
- `docs/PRD-public-knowledge-search-service.md` — модель лимитов **search** (`free` / `basic`, 429).
195+
- `OPERATOR.md` (если есть) — деплой, Caddy, секреты.
196+
197+
---
198+
199+
## 12. Утверждение
200+
201+
- Product / Ops: перечень метрик и определение «пользователь».
202+
- Security: хранение хэшей, доступ к панели, landing tracking.
203+
204+
---
205+
206+
*Конец PRD.*

0 commit comments

Comments
 (0)