clickclack/docs/features/threads.md
2026-05-08 13:23:35 +01:00

68 lines
2.0 KiB
Markdown

---
read_when:
- changing thread reply behavior or thread state
- adding nested replies (don't, V1 forbids it)
---
# Threads
Threads are Slack-style: every root message can have one flat list of replies.
Nested replies are explicitly rejected. For lighter-weight inline replies that
keep the new message in the parent stream and just quote what they're
answering, see [replies.md](replies.md).
## Endpoints
```http
GET /api/messages/{message_id}/thread # root + replies + state
POST /api/messages/{message_id}/thread/replies # body
```
`GET` returns:
```jsonc
{
"root": Message,
"replies": Message[], // ordered by thread_seq asc, capped 1..200 (default 100)
"thread_state": ThreadState // counters/last reply summary
}
```
`POST` accepts `{body}`. Empty replies are rejected; replying to a non-root
message returns an error (`nested thread replies are not supported`).
## Schema invariants
For any message:
- Root: `parent_message_id IS NULL`, `thread_root_id = id`, `channel_seq IS NOT NULL`,
`thread_seq IS NULL`.
- Reply: `parent_message_id = root.id`, `thread_root_id = root.id`,
`channel_seq IS NULL`, `thread_seq` assigned per-root.
## Thread state
`thread_state` is one row per root message, kept in sync inside the same
transaction as the reply insert. It carries:
- `reply_count`
- `last_reply_at`
- `last_reply_author_ids_json` — small ring of recent author IDs for "X, Y and 3
others replied" UI.
A reply emits two durable events: `thread.reply_created` and
`thread.state_updated`. Both go into the workspace event stream and reach
subscribers via the realtime hub.
## Ordering and pagination
Replies are ordered by `thread_seq` ascending. `limit` is clamped to `1..200`
(default 100). There's no `after_seq` parameter on the thread endpoint yet —
clients fetch the head of the thread and use realtime events for new replies.
## What is intentionally missing
- Multi-level threads.
- Promoting a reply to a channel post.
- Following/unfollowing threads.