Moved all six apps in the fleet (PopRoom, BotWhy, x, Apercu, sacenpapier, homelab-sacenpapier) from manual `kubectl rollout restart` deploys to ArgoCD-managed GitOps. Every app's `k3s/` manifests are now the single source of truth — the cluster continuously reconciles against git and self-heals if anything drifts.
Four features landed in a single push: Lists (create/delete, member viewing, with its own backend models and router), an Explore page backed by a new trending-tweets endpoint, Bookmarks (per-tweet toggle plus a dedicated page), and Notifications (triggered by likes, retweets, comments, and follows) — replacing what had been placeholder "coming soon" pages.
Procedural park generation for PopRoom's canvas — decor rendering, boulders, and wildlife (rabbits and birds) scattered across the play space, plus improved WebSocket error handling and a proper launch configuration for running frontend and backend together.
A security pass across the homelab boxes' SSH configuration, plus a tuning fix on a false-alarm memory alert triggered by Watchtower's nightly auto-updates squeezing `glances`' memory limit.
Trending post reporting with author-only deletion, all trending posts surfaced in the admin moderation view, and a manual OpenRouter spend reconciliation tool in the admin panel.
Voice input and voice replies for BotWhy's chat: a `useSpeechRecognition` hook for talking to the bot, a `useSpeechSynthesis` hook for hearing its replies read aloud, a tri-state `VoiceModeButton`, and a per-message read-aloud button (replacing an earlier auto-speak-everything approach).
A full admin panel: user list and detail views, role management with a self-demotion guard, soft-delete and reactivate for accounts, a credit adjustment endpoint with an audit trail, and a transaction ledger view — plus the admin frontend routes and pages to use all of it.
A per-IP rate limit (20 requests/minute via `slowapi`) and a 500-character message length cap on BotWhy's `/openai/answer` endpoint — the one route that actually calls out to a paid AI provider on every request.
Eventually landed: a stable mobile layout where the chat input stays anchored at the bottom and the header stays sticky even when the on-screen keyboard opens.
A full pay-as-you-go credit system for BotWhy: Stripe checkout and webhooks, a credit ledger with transaction history, free credits on signup, a free-tier message allowance with a countdown, model restrictions for free-tier users, and a dedicated Credits page with pack selection and balance display.