| 2026-06-27 20:45 | perf: use composite primary keys for vote and story_category | Silas Brack | 3 | +88 | -0 |
| 2026-06-14 13:41 | fix: write seed SQL to temp file to avoid arg length limit | Silas Brack | 1 | +16 | -12 |
| 2026-06-14 13:19 | fix: handle multiple nix output paths in bench.sh | Silas Brack | 1 | +1 | -1 |
| 2026-06-14 13:18 | add bench.sh for repeatable read/write benchmarks | Silas Brack | 1 | +85 | -0 |
| 2026-06-14 13:03 | perf: use RETURNING * for create_story, create_comment, create_user | Silas Brack | 1 | +22 | -24 |
| 2026-06-14 12:50 | fix: update score display when voting | Silas Brack | 2 | +33 | -5 |
| 2026-06-14 12:35 | perf: read vote score on writer connection, remove separate read round-trip | Silas Brack | 2 | +20 | -28 |
| 2026-06-14 11:54 | refactor: dedicated async DB thread pool, remove spawn_blocking | Silas Brack | 13 | +618 | -605 |
| 2026-06-14 10:18 | perf: add semaphore on password hashing to prevent DB read starvation | Silas Brack | 2 | +58 | -25 |
| 2026-06-14 07:08 | fix: replace unsafe UnsafeCell with safe RefCell for thread-local connections | Silas Brack | 1 | +340 | -326 |
| 2026-06-13 22:05 | feat: reject non-selective search queries via FTS match count | Silas Brack | 4 | +39 | -2 |
| 2026-06-13 13:59 | fix: set created_at in all INSERT statements | Silas Brack | 1 | +9 | -9 |
| 2026-06-13 13:44 | refactor: remove inline JS for tag checkboxes | Silas Brack | 3 | +11 | -40 |
| 2026-06-13 13:31 | feat: epoch integer timestamps, drop chrono | Silas Brack | 9 | +238 | -257 |
| 2026-06-13 13:15 | chore: reduce static asset cache TTL to 1 day | Silas Brack | 1 | +1 | -1 |
| 2026-06-13 13:11 | fix: HTML validation, meta description, clean up flake | Silas Brack | 2 | +4 | -11 |
| 2026-06-13 13:08 | docs: remove directory listing from README | Silas Brack | 1 | +0 | -8 |
| 2026-06-13 12:56 | docs: add migration guidelines to README | Silas Brack | 1 | +70 | -3 |
| 2026-06-13 12:53 | feat: replace JWTs with opaque session tokens | Silas Brack | 16 | +99 | -259 |
| 2026-06-13 11:43 | refactor: use ADDR and SMTP_ADDR env vars directly | Silas Brack | 2 | +9 | -22 |
| 2026-06-13 11:35 | refactor: use addr/smtp_addr instead of separate host+port fields | Silas Brack | 3 | +10 | -8 |
| 2026-06-13 11:34 | refactor: separate Config from AppState | Silas Brack | 10 | +28 | -37 |
| 2026-06-13 11:30 | refactor: flatten db module into database.rs | Silas Brack | 8 | +97 | -96 |
| 2026-06-13 11:27 | refactor: move version bumps into migration SQL files | Silas Brack | 4 | +27 | -55 |
| 2026-06-13 11:19 | test: verify foreign_keys is ON after migrations | Silas Brack | 1 | +14 | -0 |
| 2026-06-13 11:18 | fix: simplify migrations, remove tracing dep, fix dead code | Silas Brack | 6 | +23 | -62 |
| 2026-06-13 11:14 | chore: remove dead PRAGMA foreign_keys=ON from migration runner | Silas Brack | 1 | +0 | -4 |
| 2026-06-13 11:12 | test: add migration version bump tests | Silas Brack | 1 | +63 | -0 |
| 2026-06-13 11:11 | fix: bump migration version inside the transaction | Silas Brack | 2 | +37 | -21 |
| 2026-06-13 11:07 | refactor: let migrations manage their own transactions | Silas Brack | 2 | +23 | -24 |
| 2026-06-13 11:04 | feat: migrate all tables to STRICT mode | Silas Brack | 4 | +179 | -70 |
| 2026-06-13 10:43 | refactor: generate JWT secret randomly on startup | Silas Brack | 2 | +5 | -2 |
| 2026-06-13 10:41 | refactor: require all env vars, update .env.example and README | Silas Brack | 3 | +80 | -70 |
| 2026-06-13 10:05 | perf: use prepare_cached for all queries, HashMap for enrichment | Silas Brack | 2 | +27 | -21 |
| 2026-06-13 10:00 | perf: thread-local reader connections, cap blocking threads to core count | Silas Brack | 2 | +29 | -46 |
| 2026-06-12 21:28 | perf: separate reader pool and writer connection | Silas Brack | 1 | +74 | -68 |
| 2026-06-12 21:20 | perf: add SQLite performance PRAGMAs, merge feed db_query calls | Silas Brack | 2 | +16 | -12 |
| 2026-06-12 21:01 | perf: replace lettre with hand-rolled SMTP client | Silas Brack | 4 | +58 | -768 |
| 2026-06-12 20:24 | perf: replace r2d2 with hand-rolled connection pool | Silas Brack | 3 | +80 | -172 |
| 2026-06-12 20:18 | chore: remove thiserror, hand-impl Display + Error | Silas Brack | 3 | +20 | -11 |
| 2026-06-12 20:17 | chore: remove unused deps (serde_json, uuid) | Silas Brack | 3 | +11 | -7 |
| 2026-06-12 20:00 | chore: remove manual gzip, let nginx handle compression | Silas Brack | 2 | +5 | -31 |
| 2026-06-12 19:51 | perf: use system SQLite instead of bundled | Silas Brack | 3 | +3 | -2 |
| 2026-06-12 19:26 | refactor: move migrations to SQL files, update README | Silas Brack | 4 | +180 | -172 |
| 2026-06-12 19:22 | chore: remove old seeds, scripts, guests, and schemas | Silas Brack | 13 | +0 | -1696 |
| 2026-06-12 19:21 | chore: remove leftover TrailBase files | Silas Brack | 10 | +0 | -390 |
| 2026-06-12 18:51 | feat: add migration system, email verification, and data migration script | Silas Brack | 11 | +971 | -201 |
| 2026-06-12 18:22 | feat: replace TrailBase with direct SQLite access | Silas Brack | 23 | +1913 | -3170 |
| 2026-06-12 17:49 | perf: share reqwest connection pool across all TrailBase clients | Silas Brack | 10 | +96 | -239 |
| 2026-06-11 17:43 | perf: add timing instrumentation to story and feed handlers | Silas Brack | 2 | +40 | -1 |
| 2026-06-11 13:24 | fix: use data-init instead of data-on:load for SSE connection | Silas Brack | 2 | +2 | -2 |
| 2026-06-11 12:55 | fix: add X-Accel-Buffering header to SSE responses for nginx | Silas Brack | 2 | +10 | -4 |
| 2026-06-11 12:43 | feat: re-implement comment SSE bridge with initial event diagnostic | Silas Brack | 5 | +149 | -43 |
| 2026-06-11 11:43 | fix: replace broken SSE bridge with EventSource + Datastar @get | Silas Brack | 5 | +43 | -124 |
| 2026-06-11 10:38 | feat: add Datastar loading indicators to interactive elements | Silas Brack | 6 | +22 | -6 |
| 2026-06-11 10:36 | feat: replace vanilla JS comment updates with Datastar SSE stream | Silas Brack | 5 | +123 | -39 |
| 2026-06-11 10:33 | fix: use proper SSE format for settings tabs, remove manual history.pushState | Silas Brack | 3 | +10 | -17 |
| 2026-06-11 10:32 | fix: use proper SSE format and outer morph for search responses | Silas Brack | 2 | +4 | -9 |
| 2026-06-11 10:31 | fix: use proper SSE format and outer morph for vote responses | Silas Brack | 2 | +8 | -14 |
| 2026-06-11 10:30 | feat: add SSE helper module for Datastar-compliant responses | Silas Brack | 2 | +36 | -0 |
| 2026-06-10 20:52 | feat: add validation-enhancer web component for inline form validation | Silas Brack | 9 | +472 | -37 |
| 2026-06-10 20:49 | refactor: use enum for story fragment query parameter | Silas Brack | 1 | +8 | -2 |
| 2026-06-10 20:40 | refactor: consolidate comments fragment into story handler | Silas Brack | 3 | +19 | -25 |
| 2026-06-09 18:07 | feat: add /api/* reverse proxy for local development | Silas Brack | 3 | +56 | -2 |
| 2026-06-09 18:07 | fix: prevent vote race condition with try-then-catch pattern | Silas Brack | 1 | +48 | -65 |
| 2026-06-09 18:07 | feat: replace full page reload with targeted comment refresh on SSE | Silas Brack | 2 | +12 | -1 |
| 2026-06-09 18:07 | fix: batch-fetch comment authors and tag queries to eliminate N+1 | Silas Brack | 6 | +214 | -66 |
| 2026-06-09 18:07 | chore: remove dead HTMX code | Silas Brack | 2 | +1 | -52 |
| 2026-06-08 20:36 | revert: go back to page reload for SSE comments | Silas Brack | 4 | +4 | -60 |
| 2026-06-08 20:33 | feat: swap comments via fetch instead of full page reload | Silas Brack | 4 | +60 | -4 |
| 2026-06-08 20:27 | feat: replace HTMX with Datastar | Silas Brack | 14 | +89 | -84 |
| 2026-06-08 16:41 | fix: enable subscriptions on comment record API | Silas Brack | 1 | +1 | -0 |
| 2026-06-08 16:38 | fix: filter SSE subscription by story_id | Silas Brack | 1 | +2 | -9 |
| 2026-06-08 15:50 | feat: add realtime comments via SSE subscription | Silas Brack | 1 | +17 | -1 |
| 2026-06-07 21:09 | perf: batch story enrichment via WASM guest /enrich endpoint | Silas Brack | 4 | +146 | -30 |
| 2026-06-07 21:07 | fix: use IF NOT EXISTS in index migration | Silas Brack | 1 | +2 | -2 |
| 2026-06-07 21:06 | perf: add indices on story.published and story.score | Silas Brack | 1 | +2 | -0 |
| 2026-06-07 21:03 | perf: drop ORDER BY rank from FTS5 search | Silas Brack | 2 | +0 | -1 |
| 2026-06-07 20:48 | docs: trim README to stable content only | Silas Brack | 1 | +13 | -78 |
| 2026-06-07 20:47 | docs: update README with current stack, principles, and structure | Silas Brack | 1 | +71 | -61 |
| 2026-06-07 20:03 | chore: remove dead code and stale files | Silas Brack | 7 | +6 | -141 |
| 2026-06-07 19:55 | fix: revert realtime polling, add error logging for API failures | Silas Brack | 6 | +16 | -10 |
| 2026-06-07 19:50 | fix: replace unwrap() panic in reply form with proper error | Silas Brack | 1 | +2 | -1 |
| 2026-06-07 19:48 | feat: add realtime comment polling via HTMX | Silas Brack | 5 | +91 | -34 |
| 2026-06-07 19:43 | git: update gitignore | Silas Brack | 1 | +1 | -2 |
| 2026-06-07 19:42 | fix: remove accidentally committed guest build artifacts | Silas Brack | 930 | +1 | -2982 |
| 2026-06-07 19:42 | feat: replace rusqlite with WASM guest for FTS5 search | Silas Brack | 939 | +4075 | -111 |
| 2026-06-07 19:29 | chore: regenerate types from trailbase schema via quicktype | Silas Brack | 7 | +220 | -24 |
| 2026-06-07 19:03 | feat: add porter stemming to FTS5 search | Silas Brack | 1 | +34 | -0 |
| 2026-06-07 18:48 | chore: update generate-types.sh for current schema | Silas Brack | 1 | +12 | -7 |
| 2026-06-07 18:35 | chore: fix source URL, add seed script | Silas Brack | 2 | +97 | -1 |
| 2026-06-07 18:29 | feat: clean up design and remove duplicate sort links | Silas Brack | 4 | +316 | -496 |
| 2026-06-07 18:21 | feat: serve htmx and preload.js locally instead of CDN | Silas Brack | 4 | +29 | -2 |
| 2026-06-07 18:14 | fix: add missing slash in resend verification URL | Silas Brack | 1 | +2 | -1 |
| 2026-06-07 18:11 | feat: add resend verification email page | Silas Brack | 5 | +82 | -1 |
| 2026-06-07 17:30 | chore: upgrade trailbase from v0.23.0 to v0.28.3 | Silas Brack | 1 | +2 | -2 |
| 2026-06-07 17:09 | feat: use SQLite FTS5 for search instead of LIKE | Silas Brack | 5 | +113 | -9 |
| 2026-06-07 16:23 | feat: restore tag selection using hidden field with JS | Silas Brack | 3 | +53 | -6 |
| 2026-06-07 16:17 | fix: add URL validation error message and log profile creation failures | Silas Brack | 2 | +18 | -3 |
| 2026-06-07 16:15 | fix: change URL field from type=url to type=text | Silas Brack | 2 | +2 | -2 |
| 2026-06-07 16:09 | fix: remove tags from form structs to fix submission | Silas Brack | 1 | +2 | -17 |
| 2026-06-07 16:03 | fix: include user_id in profile creation and auto-create on login | Silas Brack | 2 | +16 | -1 |
| 2026-06-07 15:58 | fix: use OR for target_id filters in vote lookup | Silas Brack | 1 | +16 | -15 |
| 2026-06-07 15:55 | fix: convert URL-safe base64 user_id to standard base64 | Silas Brack | 1 | +4 | -1 |
| 2026-06-07 15:50 | feat: add story editing and tag selection | Silas Brack | 9 | +308 | -13 |
| 2026-06-07 15:44 | fix: filter votes by user_id to show correct voted state | Silas Brack | 1 | +6 | -0 |
| 2026-06-07 13:31 | refactor: reuse shared reqwest client for registration | Silas Brack | 3 | +4 | -3 |
| 2026-06-07 12:32 | fix: show success page instead of error for email verification | Silas Brack | 2 | +26 | -21 |
| 2026-06-07 12:28 | fix: handle 303 redirect from trailbase registration | Silas Brack | 1 | +9 | -4 |
| 2026-06-07 12:25 | feat: implement user registration via trailbase API | Silas Brack | 6 | +231 | -5 |
| 2026-04-25 20:08 | chore: remove debug logging and add htmx preloading | Silas Brack | 3 | +13 | -44 |
| 2026-04-25 16:58 | fix: resolve FTS5 content table and vote auth issues | Silas Brack | 2 | +60 | -8 |
| 2026-04-25 16:33 | test: remove user_id from vote to check auto-fill | Silas Brack | 1 | +0 | -6 |
| 2026-04-25 15:55 | debug: log vote JSON payload | Silas Brack | 1 | +3 | -3 |
| 2026-04-25 15:53 | debug: use eprintln for logging | Silas Brack | 1 | +9 | -9 |
| 2026-04-25 15:49 | debug: add logging for user_id extraction and create operations | Silas Brack | 1 | +36 | -4 |
| 2026-04-25 13:45 | fix: manual JWT parsing for user_id extraction | Silas Brack | 2 | +78 | -10 |
| 2026-04-25 13:10 | fix: include user_id/created_by in create requests | Silas Brack | 1 | +42 | -2 |
| 2026-04-25 13:03 | fix: use client.user().sub for vote user_id | Silas Brack | 4 | +4 | -22 |
| 2026-04-25 12:35 | fix: use autofill_missing_user_id_column for vote user_id | Silas Brack | 1 | +1 | -1 |
| 2026-04-25 12:33 | fix: use TrailBase autofill for vote user_id | Silas Brack | 3 | +4 | -14 |
| 2026-04-25 11:17 | fix: search wildcards and vote authentication | Silas Brack | 4 | +41 | -5 |
| 2026-04-25 11:03 | feat: refactor to HN/Lobsters-style link aggregator | Silas Brack | 41 | +3041 | -612 |
| 2026-04-25 10:19 | refactor: remove tower-http compression layer | Silas Brack | 3 | +2 | -80 |
| 2026-04-25 10:01 | feat: implement proper auth with trailbase-client | Silas Brack | 8 | +2733 | -663 |
| 2026-04-25 09:25 | fix: embed static files for Nix deployment | Silas Brack | 3 | +44 | -19 |
| 2026-04-25 09:20 | fix: correct TrailBase API filter syntax and response handling | Silas Brack | 1 | +9 | -5 |
| 2026-04-25 09:17 | fix: use cursor instead of total_count for TrailBase pagination | Silas Brack | 1 | +1 | -1 |
| 2026-04-25 09:08 | refactor: remove bloated dependencies | Silas Brack | 12 | +552 | -2331 |
| 2026-04-22 11:20 | feat: generate Rust types from Trailbase schema | Silas Brack | 8 | +145 | -17 |
| 2026-04-22 06:19 | fix: correct Trailbase API response format and migration naming | Silas Brack | 4 | +15 | -18 |
| 2026-04-21 20:28 | feat: add Trailbase backend for authentication | Silas Brack | 24 | +1355 | -870 |
| 2026-04-21 20:01 | fix: embed static files with rust-embed | Silas Brack | 3 | +104 | -16 |
| 2026-04-21 19:55 | fix: serve pre-compressed static files | Silas Brack | 2 | +1 | -1 |
| 2026-04-21 19:31 | refactor: apply mkv development philosophy | Silas Brack | 13 | +303 | -162 |
| 2026-04-20 19:46 | refactor: migrate from Python/Starlette to Rust/Axum | Silas Brack | 56 | +4098 | -3688 |
| 2025-10-15 15:12 | test: random fixes | Silas Brack | 4 | +173 | -92 |
| 2025-10-04 21:45 | style: format HTML with prettier | Silas Brack | 10 | +847 | -382 |
| 2025-10-04 17:03 | fix: loading more data | Silas Brack | 2 | +7 | -1 |
| 2025-10-04 14:58 | chore: whitespace | Silas Brack | 1 | +0 | -1 |
| 2025-10-04 14:57 | refactor: use url_for | Silas Brack | 6 | +23 | -23 |
| 2025-10-04 11:12 | test: improve tests | Silas Brack | 1 | +5 | -2 |
| 2025-10-04 11:08 | test: improve tests | Silas Brack | 1 | +7 | -0 |
| 2025-10-04 10:45 | test: improve tests | Silas Brack | 1 | +30 | -4 |
| 2025-10-04 10:45 | fix: settings tab loading | Silas Brack | 4 | +18 | -14 |
| 2025-10-04 10:08 | feat: disable load more button when we run out of content to show | Silas Brack | 3 | +8 | -4 |
| 2025-10-04 09:31 | refactor: improve settings template usage | Silas Brack | 1 | +6 | -8 |
| 2025-10-04 09:30 | test: add locustfile | Silas Brack | 1 | +7 | -0 |
| 2025-10-04 09:30 | docs: add comments for dependencies | Silas Brack | 1 | +2 | -0 |
| 2025-10-04 07:51 | refactor: refactor main page | Silas Brack | 1 | +16 | -10 |
| 2025-10-03 21:12 | test: fix testing and add tests | Silas Brack | 7 | +963 | -108 |
| 2025-10-03 10:51 | fix: load more after filtering | Silas Brack | 1 | +1 | -1 |
| 2025-10-02 17:23 | feat: improve news card | Silas Brack | 1 | +21 | -22 |
| 2025-10-02 17:15 | chore: oops | Silas Brack | 1 | +1 | -1 |
| 2025-10-02 17:15 | chore: improve local logging | Silas Brack | 3 | +55 | -5 |
| 2025-10-02 15:57 | feat: preload settings | Silas Brack | 1 | +6 | -6 |
| 2025-10-02 15:53 | feat: enable hx-preload | Silas Brack | 6 | +16 | -6 |
| 2025-10-02 15:23 | fix: github link | Silas Brack | 1 | +1 | -1 |
| 2025-10-02 15:21 | fix: load more when filtering category, change formatting | Silas Brack | 3 | +5 | -3 |
| 2025-10-02 15:01 | feat: enable filtering for category | Silas Brack | 5 | +158 | -15 |
| 2025-10-02 10:40 | fix: make category loading much faster | Silas Brack | 1 | +3 | -6 |
| 2025-10-02 07:32 | fix: use of tables from migration | Silas Brack | 2 | +12 | -8 |
| 2025-10-01 20:37 | feat: add news | Silas Brack | 17 | +327 | -178 |
| 2025-10-01 10:51 | feat: improve mobile tabs | Silas Brack | 4 | +44 | -25 |
| 2025-10-01 09:08 | feat: start implementing kagi news clone | Silas Brack | 7 | +229 | -54 |
| 2025-09-30 10:26 | chore: remove basedpyright | Silas Brack | 1 | +0 | -2 |
| 2025-09-30 10:26 | fix: entrypoint in nixos | Silas Brack | 1 | +2 | -1 |
| 2025-09-29 21:27 | docs: clean up, fix documentation | Silas Brack | 2 | +27 | -38 |
| 2025-09-29 21:03 | refactor: fix entrypoing file | Silas Brack | 3 | +11 | -7 |
| 2025-09-29 20:57 | feat!: major refactoring, improve flake support (#1) | Silas Brack | 19 | +603 | -205 |
| 2025-09-28 13:10 | build: set up for Mac OS | Silas Brack | 2 | +149 | -145 |
| 2025-09-27 16:18 | refactor: move static files into package | Silas Brack | 9 | +35 | -16 |
| 2025-09-27 13:51 | feat!: initial commit | Silas Brack | 20 | +1476 | -0 |