CI / lint-and-test (push) Has been cancelled
- Remove multi-marketplace from Phase 3 - Add FastAPI web UI on port 8766 with basic auth - Add 6 Jinja2 templates (dashboard, keywords, users, ads, stats) - Add pytest test suite (45 tests, 49% coverage) - Add GitHub Actions CI/CD workflow - Update docker-compose.yml to expose web UI port - Update Dockerfile to include tests
3.3 KiB
3.3 KiB
Task: Web Dashboard (FastAPI + Jinja2)
Description
Currently, the only way to monitor the system is via Telegram bot commands or SSH into the server. This task adds a read-only web dashboard for real-time visibility into keywords, ads, users, and stats.
Architecture
┌──────────────────────────────────────────────┐
│ FastAPI App (port 8766) │
│ │
│ Auth: Basic Auth (WEB_UI_USERNAME/PASSWORD) │
│ Templates: Jinja2 with inline CSS │
│ │
│ Routes: │
│ GET / → Dashboard │
│ GET /keywords → Keywords list │
│ GET /keywords/<id> → Keyword detail │
│ GET /users → Users list │
│ GET /ads → Recent ads │
│ GET /stats → JSON stats │
└──────────┬───────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ PostgreSQL (asyncpg pool) │
│ │
│ Queries: │
│ - Keywords with status, filters, subs │
│ - Recent ads with price, location │
│ - Users with mute/digest settings │
│ - Stats (counts, queue status) │
└──────────────────────────────────────────────┘
Implementation Details
1. Add dependencies
In worker/requirements.txt:
fastapi==0.115.0
uvicorn==0.30.0
jinja2==3.1.4
2. Create worker/src/web.py
- FastAPI app with Jinja2 template engine
- Basic auth middleware using
WEB_UI_USERNAME/WEB_UI_PASSWORDenv vars - Routes that query the DB via
get_pool()fromdb.py - Each route returns HTML via Jinja2 templates
3. Create worker/src/templates/
base.html— Base layout with sidebar navigation, dark themedashboard.html— Keywords overview + stats summary cardskeywords.html— Table of keywords with status, filters, subscriberskeyword_detail.html— Keyword detail with recent ads, price history, scrape logsusers.html— Users list with mute/digest settingsads.html— Recent ads with search/filter
4. Integrate into main.py
- Start uvicorn server on port 8766 alongside existing aiohttp health server on 8765
- Graceful shutdown includes web server cleanup
Acceptance Criteria
- Web UI accessible at
http://<host>:8766with basic auth - Dashboard shows keywords with status, filters, subscribers, last scrape
- Dashboard shows recent ads with price, location, keyword
- Dashboard shows users with mute/digest settings
- Dashboard shows stats (ads indexed, notifications sent, queue status)
- Health server still works on port 8765 (no regression)
- Telegram bot still works (no regression)