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
77 lines
3.3 KiB
Markdown
77 lines
3.3 KiB
Markdown
# 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) |