- 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
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# 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_PASSWORD` env vars
|
||||
- Routes that query the DB via `get_pool()` from `db.py`
|
||||
- Each route returns HTML via Jinja2 templates
|
||||
|
||||
### 3. Create `worker/src/templates/`
|
||||
|
||||
- `base.html` — Base layout with sidebar navigation, dark theme
|
||||
- `dashboard.html` — Keywords overview + stats summary cards
|
||||
- `keywords.html` — Table of keywords with status, filters, subscribers
|
||||
- `keyword_detail.html` — Keyword detail with recent ads, price history, scrape logs
|
||||
- `users.html` — Users list with mute/digest settings
|
||||
- `ads.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>:8766` with 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)
|
||||
Reference in New Issue
Block a user