toa://toacomments
Headless comments for static sites.
OVERVIEW
comments rounds out the toa:// indie-backend suite alongside blog and contact — the piece static sites can’t build themselves. Drop a Web Component on any page and get moderated, privacy-first discussion over a clean REST API: AI handles spam and toxicity, you moderate from a per-site dashboard. Built multi-tenant with Postgres row-level security like the rest of the suite, and open-source from day one.
FEATURES
Drop-in Web Component
Add `<toa-comments>` plus one script tag to any static site (Astro, Hugo, Nuxt). Shadow-DOM isolated, themeable via CSS custom properties.
AI moderation
Every comment is scored by DeepSeek for spam and toxicity — clean ones publish instantly, borderline ones wait in a queue, with a rule-based fallback if the model is unavailable.
Privacy-first
Cookieless, no third-party tracking. Emails are hashed (never shown), IPs hashed and auto-purged, avatars generated — GDPR-clean by design.
Spam-proof
Cloudflare Turnstile, per-site rate limits, honeypot and blocklist — defense in depth, so a public widget never holds a secret key.
Multi-tenant
One service, many sites. Postgres row-level security isolates each site; the moderation dashboard is per-site.
Headless + admin
Public REST API for native rendering, a Nuxt moderation dashboard (single sign-on via toa://auth), and a ready-made embed snippet.
WHAT'S NEW
- added Multi-tenant headless comments backend: per-site RLS (PostgreSQL), SHA-256 API keys,
toacomments_approle. - added Public read API (
GET /api/public/v1/sites/{slug}/threads/{page_key}/comments): approved, depth-1 threaded, paginated, newest/oldest sort. - added Comment submission (
POST /api/public/v1/sites/{slug}/comments): Cloudflare Turnstile verification, per-IP rate limiting, honeypot, link/length caps, per-site blocklist. - added DeepSeek AI moderation gate on submit: spam/toxicity/quality scores decide
published/pending/rejected. Rule-based fallback when AI is unavailable. - added Token-based edit/delete window (15 min) — no account required.
- added Generated identicon avatars (SVG data-URI); no Gravatar, no third-party calls.
- added Hashed email storage (
author_email_hash, SHA-256); emails are never stored or returned in cleartext. - added IP hashing for rate-limit and abuse tracking only.
- added Admin API (
/api/admin/v1): moderation queue (approve/reject/delete, bulk), per-site settings, API key CRUD, thread browser — Authentik JWT-gated. - added
<toa-comments>Web Component (Shadow DOM, ~7.6 kB gzipped): embeddable on any static site (Astro, Hugo, Nuxt, plain HTML). Themeable via--toac-*CSS custom properties. - added Nuxt 4 admin panel: moderation queue, site settings, API keys, embed-snippet generator — toa:// console design, Authentik OIDC.
- added Owner review-notify: opt-in email alert when a comment lands as
pending(notify_on_pending+notify_emailper site). Fire-and-forget via aiosmtplib + FastAPI BackgroundTasks; never blocks submission. - added Docker Compose stack: PostgreSQL 17-alpine, FastAPI backend, Nuxt frontend, Traefik labels for
comments.toaweb.com. - added MIT license, self-host quickstart README,
cliff.tomlfor git-cliff changelog generation.
API