{% extends 'base.html' %} {% block extra_head %} {% include "includes/social.html" %} {% endblock %} {% block extra_css %} {% endblock %} {% block breadcrumbs %} {% endblock %} {% block main %}

{{ page.title }}

Shipped changes, schema tweaks, and the occasional tease for something coming.

2026-05-09
  • Replace the dashboard PDF pipeline with the embedded Typst compiler (typst + typst-pdf + typst-kit). No chromium subprocess, no temp files; fonts are searched once at startup and shared across renders
  • Restructure the axum server into per-feature route modules under src/routes/, with AppState/router assembly split into src/app.rs and the standard render context centralized in src/render.rs
  • Fix several dashboard issues exposed by the restructure (404 handling, breadcrumb edge cases)
  • Expand make clean to wipe target/, frontend deps, runtime data, and the cached topojson
  • Fix the mobile nav menu being clipped by the fixed navbar height
2026-05-07
  • 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 Uvicorn or separate scheduler process. The collector endpoint and embed snippet are unchanged, so existing tracked sites keep reporting without edits
  • Drop the multi-user accounts model. Auth is now a single operator password from .env with signed-cookie sessions and SameSite=Strict instead of CSRF tokens
  • Route bot traffic into a dedicated bot_events table at write time so human dashboard queries never have to filter it
  • Auto-download the GeoIP database and ua-parser regexes on boot when missing or stale. The server still boots and serves dashboards if either download fails
  • Add an analytics migrate subcommand that imports an existing Django SQLite into the new schema while preserving property UUIDs, so embedded snippets keep working after the cutover
  • Add an in-memory dashboard cache (5-minute TTL, keyed by property + date range + filter), bypassed for PDF and markdown exports so they always reflect the live data
  • Add a stable /static/collector.js route so embed snippets don't break when Vite re-hashes the collector bundle
2026-04-29
  • Replace the dashboard PDF report with a toner-friendly print template
2026-04-26
  • Swap the US-only datamap for a Natural Earth world map with admin-1 drill-down on click
  • Switch IP geolocation from MaxMind to DB-IP City Lite (CC-BY-4.0, no signup, monthly auto-refresh)
  • Drop SQLite mmap_size to avoid a multi-process corruption hazard
2026-04-18
  • Replace the Playwright PDF pipeline with a headless Chromium subprocess wrapper and move the Docker base image to Alpine: smaller image, faster cold starts
  • Centralize SQLite settings and expand PRAGMA tuning (WAL, synchronous, cache, mmap, temp_store)
  • Speed up the property dashboard, split the property view, and surface bot traffic separately
  • Swap the Exim relay for a Python direct-to-MX email backend
2026-04-17
  • Redesign the whole dashboard with a warm-earth palette: mossy forest green and amber on deep charcoal, Monaspace Argon throughout, aligned to the status app
  • Rework the property dashboard with metric tiles, period-over-period deltas, chart panels, and compact ranked top-lists instead of Bootstrap list groups
  • Rework the properties listing page with search, live-signal tiles, and a dense row layout
  • Swap the bar-chart emoji favicon for a themed SVG mark matching the in-app logo
  • Add a /documentation link into the main nav so the collector snippet docs are easier to find
  • Restyle the collector-tag modal and accordion docs as terminal-style code blocks
2025-10-04
  • Swap browser automation to Playwright with the bundled Chromium runtime
  • Switch Docker base image to Ubuntu 24.04 LTS
2025-10-03
  • Migrate Python package management from Pipenv/pyenv to uv
  • Switch frontend build from Yarn + Webpack to Bun + Vite
  • Fix d3/datamaps strict-mode crash under ESM so the US-state map renders again
  • Fix logout 405 by switching to a POST form + CSRF (Django 5 LogoutView is POST-only)
2022-07-26
  • Add URL property filtering: click any top-page row to scope the whole dashboard
2022-07-06
  • Change IPInfo to local MaxMind DB for IP → geo lookup (no more third-party API)
2022-06-18
  • Rename all "tracking" terminology to "collecting" (we're not spyware)
2022-06-05
  • Add PDF report generator: hit ?report on any property page to export
2022-05-28
  • Add headless Chromium screenshot utility
  • Add Open Graph / Twitter card metadata
2022-05-22
  • Add previous-period comparisons on every metric card
  • Add a shareable public-link toggle for property pages
  • Add UTM query-param collection (source, medium, campaign)
  • Add platform doughnut graph
  • Add date-range selection with presets and a custom picker
  • Add custom event cards: pin any custom event as a headline metric
{% endblock %}