rob thijssen bf04f8a1ff fix(api): log internal handler errors
Tower-http's TraceLayer logged the failure status code but not the
underlying error, leaving 500s opaque without curling the response
body. Log the error from the internal() helper so server logs carry
the actual cause (permission denied, query error, etc.).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:31:10 +03:00
2026-05-03 17:47:06 +03:00

moments

Personal activity timeline for rob.tn. Polls public sources (GitHub, Gitea, hg-edge.mozilla.org, bugzilla.mozilla.org), stores raw payloads in Postgres, and serves a reshaped timeline to a static React frontend.

Successor to the now-defunct grenade-events-react, which depended on MongoDB Stitch (retired by MongoDB in September 2022).

Layout

crates/
  moments-entities/   # types and DTOs
  moments-core/       # ingestion + reshape logic
  moments-data/       # postgres adapter + migrations
  moments-api/        # axum read-only HTTP API (binary)
  moments-worker/     # ingestion daemon (binary)
ui/                   # vite + react + swc + ts frontend
asset/                # systemd, nginx, firewalld, manifest.yml
script/deploy.sh

Architectural conventions follow grenade/architecture/generic.md.

Local development

cargo build --workspace
cargo run -p moments-api      # serves on 127.0.0.1:8080
cargo run -p moments-worker   # one-shot ingest tick (until --interval is wired up)

The API expects a Postgres reachable at DATABASE_URL. For magrathea, that's an mTLS connection using the host cert. For local dev against a throwaway database:

DATABASE_URL=postgres://localhost/moments cargo run -p moments-api

Migrations live in crates/moments-data/migrations/ and run automatically on API startup.

Deployment

See asset/manifest.yml and script/deploy.sh.

Description
Personal activity timeline for rob.tn — successor to grenade-events-react
Readme 1.4 MiB
Languages
Rust 61.4%
TypeScript 24.3%
Shell 12.1%
CSS 1.4%
HTML 0.8%