Lettre — AGENTS.md

Project Overview

Lettre is a newspaper/blog hybrid web app built with Rust + Actix-web. Two main areas:

  • Public: Landing page (latest article link, audiences link), audience pages listing all audiences
  • Authenticated (author area): Multi-tab dashboard — articles (create, edit content/settings, publish). Articles belong to exactly one audience. Same-topic articles across audiences are "siblings."

Architecture & Conventions

  • Backend: Rust, edition 2024, Actix-web with maud (HTML macro templating), actix-multipart for uploads
  • Database: Postgres via Neon (serverless) — always prefer Neon for the database layer; use tokio-postgres (rust-postgres) for DB integration
  • Migrations: migs crate — check src/ for migration files as the project grows
  • Password hashing: argon2
  • Deployment: [spruce] section in Cargo.toml defines deploy target (host, namespace, mode)
  • Never write raw JavaScript — use fixi/paxi/ssexi/moxi (vendored in assets/) for all client-side behavior
  • Templating: Always use maud macros for HTML — never template strings or string concatenation
  • Styling: Tachyons CSS (vendored in assets/tachyons.css). Prefer tachyons utility classes over custom CSS
  • Design: Japanese-inspired color scheme — muted, high-contrast, deliberate typography. Favor serif typefaces (serif, georgia) for body text and generous measure/lh-copy line lengths

Frontend Libraries (vendored, no build step)

LibraryFilePurpose
fixiassets/fixi.jsHypermedia controls (AJAX via fx-action, fx-method, fx-target, fx-swap, fx-trigger attributes)
paxiassets/paxi.jsDOM morphing swap strategy (fx-swap="morph")
ssexiassets/ssexi.jsServer-Sent Events streaming for fixi
moxiassets/moxi.jsLocal interactivity (on-* event handlers, live reactivity, q() query helper)
  • Skill docs for each are in .opencode/{fixi,paxi,ssexi,moxi}/SKILL.md
  • Tachyons reference: .opencode/tachyons/SKILL.md
  • Static assets are served via src/assets.rs using include_str! (compile-time baked in, long cache headers)

Verification Commands

just verify    # or: just v — runs fmt check, cargo check, clippy, test
just test      # cargo test only
just fmt       # auto-fix formatting and clippy
just run       # build + run (kills existing process on port 8080 first)

Always run just verify after making changes. The order matters: fmt → check → clippy → test.

Key Domain Rules

  • Articles have versioned content with git-like commits and diffs — the editor auto-commits; authors can also manually commit
  • Authors can publish at any commit/version, but only one commit can be the published version
  • Author accounts can only be created via an invite ticket — tickets are generated in the UI using a MAIN_KEY env var
  • One article belongs to exactly one audience; sibling articles share a topic but target different audiences

Early-Project Caveats

  • src/main.rs is currently a stub (println!("Hello, world!"))
  • src/assets.rs references files not yet in assets/ (t.css, h.js, hx-response-targets.js, fig.svg) — these need to be added or the module updated
  • The assets/ dir has the vendored JS libs (fixi.js, paxi.js, ssexi.js, moxi.js) and tachyons.css, but assets.rs doesn't serve them yet — update the match arms when wiring up