Release 0.5.0: PR-less per-RFC discussion (contribution still requires PR)
Roadmap item #3. An RFC's main view now carries a discussion surface distinct from PR comments and from branch chat. The substrate is the existing threads/thread_messages tables — rows with branch_name IS NULL scope to the RFC's main view; the schema already permitted that shape, v0.5.0 is the first build to write it. Five new endpoints under /api/rfcs/<slug>/discussion/..., a new RFCDiscussionPanel right-column component used when branchParam === main, SPEC §10.10 settling discussion-vs-contribution, and §17 listing the new routes. Notification routing reuses the existing chat_message_in_participated_thread / chat_reply_to_my_message event kinds with branch_name=null on the fan-out row; a distinct event_kind is a §19.2 candidate. Anonymous viewers can read; writes require contributor — v0.6.0's item #4 will harden adjacent gates. No schema migration; minor bump, no operator action required beyond rebuild and restart. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -197,6 +197,52 @@ export async function resolveThread(slug, branch, threadId) {
|
||||
return jsonOrThrow(res)
|
||||
}
|
||||
|
||||
// ── v0.5.0: PR-less per-RFC discussion (§5 / §10) ────────────────────────
|
||||
//
|
||||
// The substrate is `threads.branch_name IS NULL` — the same threads
|
||||
// table the branch chat uses, with a null branch the schema already
|
||||
// supported. Contribution still requires a PR (api_prs / openPR), so
|
||||
// these endpoints are read+write for discussion only.
|
||||
|
||||
export async function listDiscussionThreads(slug) {
|
||||
return jsonOrThrow(await fetch(`/api/rfcs/${slug}/discussion/threads`))
|
||||
}
|
||||
|
||||
export async function createDiscussionThread(slug, { label = null, message = null } = {}) {
|
||||
const res = await fetch(`/api/rfcs/${slug}/discussion/threads`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ label, message }),
|
||||
})
|
||||
return jsonOrThrow(res)
|
||||
}
|
||||
|
||||
export async function getDiscussionThreadMessages(slug, threadId) {
|
||||
return jsonOrThrow(await fetch(
|
||||
`/api/rfcs/${slug}/discussion/threads/${threadId}/messages`,
|
||||
))
|
||||
}
|
||||
|
||||
export async function postDiscussionMessage(slug, threadId, { text, quote = null }) {
|
||||
const res = await fetch(
|
||||
`/api/rfcs/${slug}/discussion/threads/${threadId}/messages`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text, quote }),
|
||||
},
|
||||
)
|
||||
return jsonOrThrow(res)
|
||||
}
|
||||
|
||||
export async function resolveDiscussionThread(slug, threadId) {
|
||||
const res = await fetch(
|
||||
`/api/rfcs/${slug}/discussion/threads/${threadId}/resolve`,
|
||||
{ method: 'POST' },
|
||||
)
|
||||
return jsonOrThrow(res)
|
||||
}
|
||||
|
||||
// ── Slice 4: super-draft body editing (§9.5) ─────────────────────────────
|
||||
|
||||
export async function startEditBranch(slug, body = {}) {
|
||||
|
||||
Reference in New Issue
Block a user