Files
2026-08-07 21:17:17 +03:30

3.4 KiB
Raw Permalink Blame History

Kavosh

Self-hosted dashboard that ingests Apache/LiteSpeed access logs and turns them into three sections — Overview, SEO & Bot Behavior, and Suspicious Requests/IP History — engineered to run inside a constrained cPanel shared-hosting account (4 CPU cores, 60 entry processes, 2GB RAM, 1,024 IOPS, 16MB/s I/O, 150 processes, 150 DB connections).

Stack: Flask (application factory + blueprints) + HTMX/Alpine.js + Tailwind + Chart.js + Grid.js, served via Passenger, SQLite in WAL mode. No cron job is required — uploads process automatically in the background, with light/dark mode and live progress bars for both the upload and analysis phases.

Project docs

  • DEPLOYMENT.md — cPanel deployment checklist + local dev setup (no cron needed)
  • docs/api-contract-final.md — consolidated route table + envelope audit
  • .env.example — every environment variable the app reads
  • migrations/versions/0001–0006 — schema history, in order

Layout

app/
  blueprints/   overview, seo, security, uploads, auth, api (routes)
  models/       SQLAlchemy models — one file per table
  services/     log parsing, bot/threat classification, aggregation,
                background.py (no-cron auto-processing)
  static/src    Tailwind/JS source (built via Vite -> static/dist)
  templates     Jinja base + HTMX partials
migrations/     Alembic schema history
tests/          pytest suite (parser + classifier + route smoke tests,
                real log-file fixtures under tests/fixtures/)

Quick start (local dev)

cp .env.example .env          # fill in real values
pip install -r requirements.txt -r requirements-dev.txt
npm install && npm run build  # or `npm run dev` while iterating on frontend
flask db upgrade
flask create-admin --email you@example.com
flask run
pytest

Visit / — it redirects to /overview if you're logged in, or /login otherwise. Upload a log file and it starts analyzing immediately; no cron job or manual CLI command required (see DEPLOYMENT.md if you want the optional cron fallback anyway). The Overview page also lists every uploaded file with select-and-delete — deleting a file removes its raw data and correctly recomputes any shared date rollups, rather than just subtracting the file's contribution naively (see app/services/ file_deletion.py).

Design system

  • Colors/fonts are defined as Tailwind tokens in tailwind.config.js (paper/surface/ink/muted/accent/danger/warn/ok, each with a -dark counterpart) — not hardcoded slate-* classes.
  • Three type roles: font-display (Space Grotesk, headings), font-sans (Public Sans, UI chrome), font-data (JetBrains Mono, every number/IP/ path/timestamp — the app's one deliberate signature touch, since the whole product is "raw log lines turned into a readout").
  • Dark mode toggles a .dark class on <html>, persisted in localStorage, set synchronously in base.html's <head> to avoid a flash of the wrong theme on load.

Notes on how this was built

Built chapter-by-chapter against a 12-chapter project spec, then extended per project-owner follow-up requests (removing the cron requirement, dark mode, upload/analysis progress bars, root-URL auth redirect). Where an implementation choice extended or deviated from the original spec, it's marked inline with a comment — search for "flagged", "ASSUMPTION", or "TRADEOFF" to find every one of them.