HTML archive view at /feedback for browsers #2

Open
opened 2026-05-13 18:44:23 +02:00 by arne · 0 comments
Owner

What to build

Content-negotiated GET on `/feedback`. Posta clients (`Accept: application/posta+json`) keep getting the actor doc; browsers get a static-ish HTML archive of the room.

Shape ("Shape 1" from the design grilling):

  • Header: room name, about text, the room's display URL.
  • A short "how to post" paragraph (example CLI invocation + link to /spec).
  • Body: the most recent 50 messages, reverse-chronological. Each entry shows sender URL (linked to the sender's own actor), display name (cached from their actor doc), timestamp, message body. Plain text bodies are HTML-escaped; line breaks preserved.
  • Member count is rendered only when there are more than 5 subscribers; the member list is never publicised.
  • No pagination, no JS, no reply UI, no inner-signature badge (signatures were already verified at receive time; surfacing it adds noise without changing trust).

Implementation hangs off a `LatestN(50)` query against `messages` (excluding any `hidden=1` rows) and a count against `subscribers`. Sender display names come from a small per-request actor-doc cache.

Acceptance criteria

  • Browser GET on `/feedback` (Accept `text/html`) returns the archive page; `Accept: application/posta+json` still returns the actor doc
  • At most 50 messages render, reverse-chronological by `received_at`
  • Each entry shows sender URL (linked), display name when known, timestamp, body (escaped, line breaks preserved)
  • Hidden messages do not appear
  • Member count shows only when `COUNT(subscribers) > 5`; otherwise nothing
  • Page renders without JS; no external network requests required to display the archive

Blocked by

  • posta/web#1 (needs the receiver mounted and the store schema)
## What to build Content-negotiated GET on \`/feedback\`. Posta clients (\`Accept: application/posta+json\`) keep getting the actor doc; browsers get a static-ish HTML archive of the room. Shape (\"Shape 1\" from the design grilling): - Header: room name, about text, the room's display URL. - A short \"how to post\" paragraph (example CLI invocation + link to /spec). - Body: the most recent 50 messages, reverse-chronological. Each entry shows sender URL (linked to the sender's own actor), display name (cached from their actor doc), timestamp, message body. Plain text bodies are HTML-escaped; line breaks preserved. - Member count is rendered only when there are more than 5 subscribers; the member list is never publicised. - No pagination, no JS, no reply UI, no inner-signature badge (signatures were already verified at receive time; surfacing it adds noise without changing trust). Implementation hangs off a \`LatestN(50)\` query against \`messages\` (excluding any \`hidden=1\` rows) and a count against \`subscribers\`. Sender display names come from a small per-request actor-doc cache. ## Acceptance criteria - [ ] Browser GET on \`/feedback\` (Accept \`text/html\`) returns the archive page; \`Accept: application/posta+json\` still returns the actor doc - [ ] At most 50 messages render, reverse-chronological by \`received_at\` - [ ] Each entry shows sender URL (linked), display name when known, timestamp, body (escaped, line breaks preserved) - [ ] Hidden messages do not appear - [ ] Member count shows only when \`COUNT(subscribers) > 5\`; otherwise nothing - [ ] Page renders without JS; no external network requests required to display the archive ## Blocked by - posta/web#1 (needs the receiver mounted and the store schema)
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
posta/web#2
No description provided.