docs: events migration plan

This commit is contained in:
Markov 2026-03-17 11:48:54 +01:00
parent 3f46c46466
commit 39d3d6d4ba

131
migration-events.md Normal file
View File

@ -0,0 +1,131 @@
# Миграция: messages → events
## Цель
Единая таблица `events` вместо `messages` + `task_actions`. Один event = одно действие в системе.
## Новая схема
### Таблица `events`
```sql
CREATE TABLE events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id),
type VARCHAR(50) NOT NULL, -- см. типы ниже
actor_id UUID REFERENCES members(id), -- кто сделал
task_id UUID REFERENCES tasks(id) ON DELETE CASCADE, -- nullable
parent_id UUID REFERENCES events(id), -- для тредов
payload JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_events_project ON events(project_id, created_at);
CREATE INDEX idx_events_task ON events(task_id, created_at);
CREATE INDEX idx_events_type ON events(type);
```
### Таблица `attachments` (без изменений, переименуем FK)
```sql
ALTER TABLE attachments RENAME COLUMN message_id TO event_id;
```
### Типы событий
| type | payload | Где видно |
|------|---------|-----------|
| `chat_message` | `{content, mentions?, thinking?, voice_url?}` | Проектный чат |
| `task_comment` | `{content, mentions?, thinking?, tool_log?}` | Комментарии задачи |
| `task_created` | `{title, status, priority, assignee?}` | Чат + задача |
| `task_status` | `{from, to}` | Чат + задача |
| `task_assigned` | `{assignee, previous?}` | Чат + задача |
| `task_unassigned` | `{previous}` | Чат + задача |
| `task_updated` | `{field, from, to}` | Задача |
| `task_label_add` | `{label}` | Задача |
| `task_label_remove` | `{label}` | Задача |
### Что удаляем
- Таблица `messages` → заменена `events`
- Таблица `task_actions` → заменена `events` (type = task_*)
- Таблица `chats`**удаляем** (project_id в events заменяет chat routing)
- Колонка `author_type` → заменена на `type` + `actor_id` (system events = actor_id NULL)
### Что НЕ меняем
- `tasks`, `projects`, `members`, `agent_configs`, `labels`, `steps`, `project_files`, `task_labels`, `task_links`
---
## План миграции (6 этапов)
### Этап 1: Backend — модели
- [ ] Создать `models/event.py` с Event model
- [ ] Удалить `models/message.py`, `models/task_action.py`
- [ ] Удалить `models/chat.py`
- [ ] Обновить `__init__.py` — импорты
### Этап 2: Backend — API
- [ ] Переписать `api/messages.py``api/events.py`
- `POST /api/v1/events` — создать event (chat_message, task_comment)
- `GET /api/v1/events?project_id=X&types=chat_message,task_status,...&limit=N` — лента проекта
- `GET /api/v1/events?task_id=X` — лента задачи
- [ ] Обновить `api/tasks.py` — создавать events вместо messages + task_actions
- Одна запись вместо двух (task comment + chat message → один event)
- [ ] Обновить `api/schemas.py` — EventOut, EventCreate
- [ ] Удалить эндпоинты `/messages` (или оставить как alias)
### Этап 3: Backend — WebSocket
- [ ] WS broadcast: `event.new` вместо `message.new`
- [ ] Streaming: `agent.stream.*` — без изменений (task_id привязка)
- [ ] Обновить `ws/manager.py` — broadcast по project_id (уже есть)
### Этап 4: Backend — Picogent tools
- [ ] `send_message` tool → отправляет `POST /api/v1/events` с type=task_comment
- [ ] `list_messages` tool → `GET /api/v1/events?task_id=X`
- [ ] Обновить TrackerClient в picogent
### Этап 5: Frontend
- [ ] `lib/api.ts` — новые типы Event, эндпоинты
- [ ] `ChatPanel.tsx` — рендерит events вместо messages
- `chat_message` → обычное сообщение
- `task_status` → системное "TE-4: backlog → done"
- `task_assigned` → системное "TE-4: назначена на @coder"
- `task_created` → системное "TE-4 создана: ..."
- [ ] `TaskModal.tsx` — комментарии из events (type=task_comment + task_status + ...)
- [ ] `MentionInput.tsx` — без изменений
- [ ] WS: слушать `event.new` вместо `message.new`
- [ ] Streaming — без изменений
### Этап 6: База данных
- [ ] DROP TABLE messages, task_actions, chats
- [ ] CREATE TABLE events (через SQLAlchemy create_all при dev start)
- [ ] Seed: создать тестовый проект заново
---
## Запросы для фронта
**Проектный чат:**
```
GET /api/v1/events?project_id=X&types=chat_message,task_created,task_status,task_assigned,task_unassigned&limit=30
```
**Комментарии задачи:**
```
GET /api/v1/events?task_id=X&limit=50
```
**Timeline проекта (всё):**
```
GET /api/v1/events?project_id=X&limit=100
```
---
## Оценка
- Backend: ~4 часа
- Frontend: ~2 часа
- Тесты: ~1 час
- **Итого: ~1 день**
## Риски
- Bridge (Telegram) — нужно обновить, он создаёт messages через API
- Picogent — нужно обновить send_message/list_messages tools
- Тесты — переписать test_chat.py, test_messages.py