modified
templates/pages/changelog.html
@@ -1,5 +1,9 @@{% extends "base.html" %}{% block extra_css %}<link rel="stylesheet" href="{{ vite_asset('static_src/pages/index.js', 'css') }}">{% endblock %}{% block breadcrumbs %}<nav aria-label="breadcrumb"> <ol class="breadcrumb mb-0">
@@ -10,24 +14,167 @@{% endblock %}{% block main %}<div class="container my-4"> <div class="row mb-4"> <div class="col-12"> <div class="section-label mb-1">project</div> <h1 class="fw-bolder text-white" style="letter-spacing: -0.01em;">Changelog</h1> <p class="text-muted mb-0 small">An ongoing record of what's shipped.</p><div class="container my-5"> <div class="row"> <div class="col-lg-8 offset-lg-2"> <div class="section-label mb-2">release log</div> <h1 class="fw-bolder text-white" style="letter-spacing: -0.01em;">{{ title }}</h1> <p class="text-muted">Shipped changes, incidents, and the occasional tease for something coming.</p> </div> </div> <div class="bg-surface border-subtle rounded border p-4"> <h2 class="h5 text-white fw-bolder">v1.0 · Rust rewrite</h2> <ul class="text-muted small"> <li>Single-binary axum service replaces the Django + scheduler pair.</li> <li>Single-password operator auth replaces the multi-user accounts model.</li> <li>SEO crawler ported to reqwest + scraper. Lighthouse still shells out to the npm CLI.</li> <li>Email alerts use direct-MX delivery via lettre + hickory-resolver. Discord webhooks use plain HTTP POST.</li> <li>Migration subcommand: <code>./status migrate <django.sqlite3></code> preserves Property UUIDs.</li> </ul> <div class="row mt-4"> <div class="col-lg-8 offset-lg-2"> <div class="changelog-entry"> <div class="changelog-date">2026-05-09</div> <ul> <li>Rewrite the entire backend from Django to a single statically-linked axum binary in Rust. sqlx + SQLite directly, minijinja for templates, no more Gunicorn or separate scheduler process. Property UUIDs are preserved so existing public status URLs keep working</li> <li>Drop the multi-user accounts model. Auth is now a single operator password from <code>.env</code> with signed-cookie sessions and <code>SameSite=Strict</code> instead of CSRF tokens</li> <li>Port the SEO crawler from <code>requests</code> + <code>BeautifulSoup</code> to <code>reqwest</code> + <code>scraper</code>. The 38 ranked checks (SEO, links, sitemap, accessibility, content, performance, security) match the original Python output</li> <li>Switch alert email to <code>lettre</code> + <code>hickory-resolver</code>, still opportunistic STARTTLS direct-to-MX on port 25; Discord webhooks are plain HTTP POST</li> <li>Add a <code>./status migrate <django.sqlite3></code> subcommand that imports an existing Django SQLite into the new schema while preserving Property UUIDs</li> <li>Run the lighthouse CLI through <code>bun run --bun</code> so the runtime image drops nodejs and npm; chromium stays for lighthouse only</li> <li>Probe Content-Encoding with a non-decompressing client so <code>response_ms</code> reflects the wire payload, not the decoded body</li> <li>Fix the mobile nav menu being clipped by the fixed navbar height</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-26</div> <ul> <li>Drop SQLite <code>mmap_size</code> to avoid a multi-process corruption hazard</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-18</div> <ul> <li>Centralize SQLite settings and expand PRAGMA tuning (WAL, synchronous, cache, mmap, temp_store)</li> <li>Commit alert state before firing notifications so a crash mid-alert can't cause duplicate sends</li> <li>Harden the chromium wrapper with timeouts, <code>/tmp</code> temp files, and <code>--headless=new</code></li> <li>Redesign alert emails to match the warm-earth site palette</li> <li>Stop wedge-reset from failing a healthy queued backlog of checks</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-17</div> <ul> <li>Redesign the whole dashboard with a warm-earth palette: mossy forest green and amber on deep charcoal, Monaspace Argon throughout</li> <li>Rework the property page with live-signals tiles, Lighthouse score cards, styled Chart.js panels, and compact insight tables</li> <li>Add recent-uptime bar strips and rolling uptime percentage to every property row on the dashboard</li> <li>Surface the full Lighthouse performance breakdown: weighted metric tiles and top savings opportunities, ranked by impact</li> <li>Swap the rocket emoji favicon for a themed SVG tile matching the in-app logo</li> <li>Update the chromium wrapper to also pick up <code>google-chrome</code> so the webdev container runs locally without extra setup</li> <li>Fix logout 405 by switching to a POST form + CSRF (Django 5 <code>LogoutView</code> is POST-only)</li> <li>Refactor the scheduler with thread pools and graceful shutdown</li> <li>Collapse the web and scheduler services into a single container via a Python supervisor in <code>entrypoint.py</code></li> <li>Replace the Exim relay with a Python direct-to-MX email backend</li> <li>Set <code>PYTHONUNBUFFERED</code> so scheduler output reaches <code>docker logs</code></li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-16</div> <ul> <li>Add live crawl/lighthouse status panel with real-time recrawl and rerun buttons</li> <li>Rewrite the SEO crawler in-process using <code>requests</code> + <code>BeautifulSoup</code>, no more Scrapy subprocess</li> <li>Harden the scheduler, alert state machine, and crawl pipeline against races and partial failures</li> <li>Harden the Lighthouse runner and surface failure reasons in the UI</li> <li>Migrate the frontend build from Webpack/Yarn to Vite/Bun</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-09</div> <ul> <li>Migrate Python package management from Pipenv/pyenv to <code>uv</code></li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2026-04-03</div> <ul> <li>Bind the Docker port to localhost only, host should proxy in</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2025-06-01</div> <ul> <li>Refactor property email templates to share a base</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2025-05-31</div> <ul> <li>Improve alert system with state tracking and recovery notifications, no more alert spam on flapping sites</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-07-25</div> <ul> <li>Add recrawl button</li> <li>Run crawler weekly on a schedule</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-07-23</div> <ul> <li>Add crawler insights: title, description, canonical, OG tags, H1 extraction per page</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-07-16</div> <ul> <li>Add docker init to handle Lighthouse Chrome zombies</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-07-15</div> <ul> <li>Add check queue to be more resource friendly</li> <li>Add Lighthouse scores</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-07-04</div> <ul> <li>Add properties listing pagination</li> <li>Add properties listing search</li> <li>Improve properties listing UI</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-06-26</div> <ul> <li>Add HSTS monitoring</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-06-25</div> <ul> <li>Add uptime chart</li> </ul> </div> <div class="changelog-entry"> <div class="changelog-date">2022-06-19</div> <ul> <li>Create status project</li> </ul> </div> </div> </div></div>{% endblock %}
modified
templates/pages/home.html
@@ -71,7 +71,6 @@<section class="container my-5 py-4"> <div class="row mb-4"> <div class="col-12"> <div class="section-label mb-2">capabilities</div> <h2 class="h3 text-white fw-bolder" style="letter-spacing: -0.01em;"> Everything your infrastructure team needs in one dashboard. </h2>
@@ -82,42 +81,42 @@ <div class="feature"> <div class="feature-label">uptime</div> <div class="feature-title">Live HTTP probes</div> <p class="feature-desc">Three-minute intervals, two-strike alert debouncing, SSL and timeout mapping. Discord + SMTP notifications only fire on real state transitions.</p> <p class="feature-desc">Three-minute checks with two-strike debouncing. Email and Discord fire only on real state transitions, never on flaps.</p> </div> </div> <div class="col-12 col-md-6 col-lg-4"> <div class="feature"> <div class="feature-label">performance</div> <div class="feature-title">Lighthouse audits</div> <p class="feature-desc">Daily headless runs surface performance, accessibility, best practices, and SEO scores with weighted metric breakdowns.</p> <p class="feature-desc">Daily headless runs scoring performance, accessibility, best practices, and SEO. Top weighted metrics and savings opportunities ranked by impact.</p> </div> </div> <div class="col-12 col-md-6 col-lg-4"> <div class="feature"> <div class="feature-label">security</div> <div class="feature-title">Header analysis</div> <p class="feature-desc">HTTPS, HSTS, HSTS preload, XSS and content-sniffing protection, clickjack defence, and server-version leak checks.</p> <p class="feature-desc">HTTPS, HSTS, HSTS preload, XSS and content-sniffing protection, clickjack defence, and server-version leak checks on every probe.</p> </div> </div> <div class="col-12 col-md-6 col-lg-4"> <div class="feature"> <div class="feature-label">crawler</div> <div class="feature-title">Weekly SEO spider</div> <p class="feature-desc">Extracts title, description, canonical, OG tags, and H1 per page — every mismatch becomes a severity-ranked insight.</p> <p class="feature-desc">In-process spider runs weekly. 38 ranked checks across SEO, links, sitemap, accessibility, content, performance, and security.</p> </div> </div> <div class="col-12 col-md-6 col-lg-4"> <div class="feature"> <div class="feature-label">sharing</div> <div class="feature-title">Public status pages</div> <p class="feature-desc">Toggle a property public and share the URL — no account required, customers see live status, response graphs, and uptime at a glance.</p> <p class="feature-desc">Flip a property public and share the URL. Customers see live status, response graphs, and uptime at a glance, no account required.</p> </div> </div> <div class="col-12 col-md-6 col-lg-4"> <div class="feature"> <div class="feature-label">ownership</div> <div class="feature-title">Single binary, single container</div> <p class="feature-desc">Rust + axum + SQLite. Ships as a Docker Compose stack. Your data, your ingress, your retention policy. No SaaS vendor lock-in.</p> <p class="feature-desc">Rust + axum + SQLite, shipped as one Docker Compose stack. Your data, your ingress, your retention policy. No SaaS lock-in.</p> </div> </div> </div>