feat: Phase 2 — web server, REST API, WebSocket/SSE, UI [v0.2.0]

AsyncEventBridge bridges sync EventEmitter to asyncio consumers.
FastAPI app with session management, discussion control, roles/providers.
WebSocket for real-time events + inject, SSE for read-only streaming.
Minimal dark-theme HTML/JS UI. `meeting-room serve` CLI subcommand.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 08:50:04 +03:00
parent 069462953b
commit 1dffaae822
13 changed files with 1393 additions and 6 deletions

View File

@@ -1,6 +1,41 @@
# Task Board
_Updated: 2026-05-04_
## 🟢 v2-p2-async-bridge — AsyncEventBridge: sync EventEmitter → asyncio.Queue
**Status:** done
**Where I stopped:** Complete
**Next action:** N/A
---
## 🟢 v2-p2-fastapi-app — FastAPI app + REST API (sessions, start, inject, roles, providers)
**Status:** done
**Where I stopped:** Complete
**Next action:** N/A
---
## 🟢 v2-p2-websocket-sse — WebSocket + SSE streaming endpoints
**Status:** done
**Where I stopped:** Complete
**Next action:** N/A
---
## 🟢 v2-p2-web-ui — Minimal HTML/CSS/JS frontend
**Status:** done
**Where I stopped:** Complete
**Next action:** N/A
---
## 🟢 v2-p2-serve-command — `meeting-room serve` CLI subcommand
**Status:** done
**Where I stopped:** Complete
**Next action:** N/A
---
## 🟢 v2-p1-deps — Обновить зависимости (pydantic, pytest, [web])
**Status:** done
**Branch:** feat/v2-phase1-core-refactor
@@ -44,8 +79,8 @@ _Updated: 2026-05-04_
---
<!--
Фаза 1 завершена! Фаза 2 (Web-сервер) задачи будут добавлены.
Фаза 2 завершена! Все таски выполнены.
Статусы:
🔴 Active — только одна одновременно
🟡 Paused — в процессе, возобновима

View File

@@ -0,0 +1,26 @@
# v2-p2-async-bridge
## Goal
Bridge synchronous EventEmitter to asyncio so DiscussionEngine can run in a thread while WebSocket/SSE consumers receive events asynchronously.
## Key files
- `meeting_room/events.py` — add AsyncEventBridge class
- `meeting_room/engine.py` — no changes (runs in thread as-is)
## Decisions log
- 2026-05-04: AsyncEventBridge + asyncio.to_thread() chosen over async engine rewrite. Minimizes changes, engine stays sync.
## Open questions
- [ ] None
## Completed steps
- [x] AsyncEventBridge class in events.py
- [x] Thread-safe bridge with call_soon_threadsafe
- [x] subscribe/unsubscribe consumer queues
- [x] Drop policy on full queues
- [x] Tests (10/10 passing)
## Notes
- events.py already has comment: "In Phase 2, an AsyncEventBridge will forward events to WebSocket clients"
- Bridge subscribes to sync EventEmitter, puts events into asyncio.Queue
- Consumers (WebSocket handlers, SSE handlers) read from the queue

View File

@@ -0,0 +1,22 @@
# v2-p2-fastapi-app
## Goal
Create FastAPI application with REST API endpoints for session management and discussion control.
## Key files
- `meeting_room/server.py` — FastAPI app, routes, session store
## Decisions log
- 2026-05-04: In-memory session store (dict). Persistent storage deferred.
- 2026-05-04: REST routes under /api prefix, WebSocket/SSE on root
## Open questions
- [ ] None
## Completed steps
- [x] FastAPI app with lifespan handler
- [x] Session + SessionStore models
- [x] REST endpoints: POST /api/sessions, GET /api/sessions, GET /api/sessions/{id}, POST /api/sessions/{id}/start, POST /api/sessions/{id}/inject, GET /api/sessions/{id}/messages
- [x] GET /api/roles, GET /api/providers
- [x] Session start runs engine in asyncio.to_thread
- [x] Tests (12 passing)

View File

@@ -0,0 +1,17 @@
# v2-p2-serve-command
## Goal
Add `meeting-room serve` CLI subcommand that starts the FastAPI web server.
## Key files
- `meeting_room/cli.py` — serve subcommand added
## Decisions log
- 2026-05-04: Default port 8000, configurable via --port. --host and --reload flags.
## Open questions
- [ ] None
## Completed steps
- [x] `meeting-room serve` subcommand with --host, --port, --reload
- [x] Starts uvicorn with the FastAPI app

18
.tasks/v2-p2-web-ui.md Normal file
View File

@@ -0,0 +1,18 @@
# v2-p2-web-ui
## Goal
Minimal HTML/CSS/JS frontend for viewing and interacting with discussions.
## Key files
- `meeting_room/static/index.html` — single-page UI
## Decisions log
- 2026-05-04: Vanilla JS + WebSocket API. No framework.
## Open questions
- [ ] None
## Completed steps
- [x] Dark theme UI with WebSocket event handling
- [x] Start discussion, view messages, inject messages
- [x] Served from /static/index.html, / redirects

View File

@@ -0,0 +1,17 @@
# v2-p2-websocket-sse
## Goal
Stream discussion events to browser clients via WebSocket and SSE endpoints.
## Key files
- `meeting_room/server.py` — WebSocket and SSE route handlers
## Decisions log
- 2026-05-04: WebSocket for bidirectional (events + inject), SSE for read-only
## Open questions
- [ ] None
## Completed steps
- [x] WebSocket endpoint: /ws/{session_id} — bidirectional events + inject
- [x] SSE endpoint: /events/{session_id} — read-only event stream