heartwood every commit a ring
7.9 KB raw
{% 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">
    <li class="breadcrumb-item"><a href="/">Home</a></li>
    <li class="breadcrumb-item active" aria-current="page">{{ title }}</li>
  </ol>
</nav>
{% endblock %}

{% block main %}
<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="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 &lt;django.sqlite3&gt;</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 %}