feat: Phase 3 — web dashboard, testing, and CI/CD
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
This commit is contained in:
2026-07-10 22:28:18 +02:00
parent 0c20799f9a
commit 8151c530da
26 changed files with 1506 additions and 388 deletions
+43
View File
@@ -0,0 +1,43 @@
{% extends "base.html" %}
{% block title %}Dashboard — Willhaben Tracker{% endblock %}
{% block content %}
<div class="page-header">
<h2>Dashboard</h2>
</div>
{% if data %}
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px;">
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Total Keywords</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_keywords }}</div>
<div style="font-size: 12px; color: #0f9b58; margin-top: 4px;">{{ data.active_keywords }} active</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Total Ads</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_ads }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Active Users</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.total_users }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Notifications Sent</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.notifications_sent }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Queue Pending</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px;">{{ data.queue_pending }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Queue Dead</div>
<div style="font-size: 32px; font-weight: 700; margin-top: 8px; color: #e94560;">{{ data.queue_dead }}</div>
</div>
<div class="card">
<div style="font-size: 12px; color: #a0a0b0; text-transform: uppercase;">Last Scheduler Run</div>
<div style="font-size: 16px; font-weight: 700; margin-top: 8px;">
{{ data.last_scheduler.strftime('%Y-%m-%d %H:%M:%S') if data.last_scheduler else 'Never' }}
</div>
</div>
</div>
{% endif %}
{% endblock %}