Replace Pico CSS CDN with Tailwind v4 standalone CLI (no Node.js). Brand theme with navy/electric/accent palette, component classes, self-hosted Commit Mono font. Docker multi-stage CSS build. Logo links to dashboard when logged in. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
[Unreleased]
Changed
- Pico CSS → Tailwind CSS v4 — full design system migration across all templates (except planner, which keeps its own CSS)
- Standalone Tailwind CLI binary (no Node.js) with
make css-build/make css-watch - Court Tech brand theme: navy/charcoal/electric/accent color palette
- Component classes (
.btn,.card,.form-input,.table,.badge,.flash, etc.) ininput.cssfor consistent styling - Self-hosted Commit Mono font (replaces JetBrains Mono) for monospace data display
- Docker multi-stage build: CSS compiled in dedicated stage before Python build
- Standalone Tailwind CLI binary (no Node.js) with
- Landing page teaser calculator restyled with Tailwind utilities and brand colors
Removed
- Pico CSS CDN dependency
custom.css(replaced by Tailwindinput.csswith@layer components)- JetBrains Mono font (replaced by self-hosted Commit Mono)
Fixed
- Empty env vars (e.g.
SECRET_KEY=) now fall back to defaults instead of silently using""— fixes 500 on every request when.envhas blank values
Added
- Comprehensive migration test suite (
tests/test_migrations.py— 20 tests) covering fresh DB, existing DB, up-to-date DB, idempotent migration, version discovery,_is_fresh_db, migration 0001 correctness, and ordering - Expanded
migrate.pymodule docstring documenting the 8-step algorithm, protocol for adding migrations, and design decisions - Sequential migration system (
migrations/migrate.py) — tracks applied versions in_migrationstable, auto-detects fresh vs existing DBs, runs pending migrations in order migrations/versions/0001_rename_ls_to_paddle.py— first versioned migration (absorbed fromscripts/migrate_to_paddle.py)- Server-side financial calculator (
planner/calculator.py) — ported JScalc(),pmt(),calcIRR()to Python so the full financial model is no longer exposed in client-side JavaScript POST /planner/calculateendpoint for server-side computation- Pre-computed initial data (
window.__PADELNOMICS_INITIAL_D__) injected on page load for instant first render - Debounced API fetch pattern in
planner.jswithAbortControllerfor in-flight request cancellation - Computing indicator CSS (
.planner-app--computing) with subtle "computing..." text - Comprehensive test suite for calculator (
tests/test_calculator.py— 227 tests) covering all 4 venue/ownership combos, edge cases, and Hypothesis property-based fuzzing - Comprehensive billing test suite (371 tests total):
tests/conftest.py— shared fixtures (DB, app, clients, subscriptions, webhook helpers)tests/test_billing_helpers.py— unit tests for SQL helpers, feature/limit access, plan determination (60+ tests + parameterized + Hypothesis)tests/test_billing_webhooks.py— integration tests for LemonSqueezy webhooks (signature verification, all lifecycle events, Hypothesis fuzzing)tests/test_billing_routes.py— route tests (pricing, checkout, manage, cancel, resume, subscription_required decorator)- Added
hypothesis>=6.100.0andrespx>=0.22.0to dev dependencies for property-based testing and httpx mocking - Factored into Copier template — all billing tests now generate as
.jinjatemplates with provider-specific conditionals for Stripe, Paddle, and LemonSqueezy
- GitLab CI/CD pipeline (
.gitlab-ci.yml) — runs pytest + ruff on master/MRs, auto-deploys on master - Blue-green deployment with Docker Compose profiles (
docker-compose.prod.yml,deploy.sh)- nginx router on port 5000 proxies to active blue/green slot
- Zero-downtime: new slot health-checked before traffic switch
- Automatic rollback on failed health check
Removed
scripts/migrate_to_paddle.py— superseded byversions/0001_rename_ls_to_paddle.py
Changed
planner.jsno longer containscalc(),pmt(), orcalcIRR()functions — computation moved server-siderender()split intorender()(tab switching + schedule calc) andrenderWith(d)(DOM updates from data)- Tab switching now renders from
_lastDcache (instant, no API call) - Slider input triggers 200ms debounced server call instead of synchronous client-side calc