Skip to content

feat(ama): guest, public realtime + guild list ordering - #336

Merged
didinele merged 2 commits into
mainfrom
feat/guest-realtime
Aug 10, 2026
Merged

feat(ama): guest, public realtime + guild list ordering#336
didinele merged 2 commits into
mainfrom
feat/guest-realtime

Conversation

@didinele

@didinele didinele commented Aug 10, 2026

Copy link
Copy Markdown
Member

Closes #321
Closes #323

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chatsift-website Ready Ready Preview Aug 10, 2026 8:58pm

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 03ce236e-804e-4dc7-8594-0a978b914c26

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds public AMA WebSocket tickets, channel-level authorization, multi-channel realtime invalidation, and live updates for public answer pages. It also updates AMA publishers, guild sorting, tests, and realtime architecture documentation.

Changes

Public AMA realtime flow

Layer / File(s) Summary
Channel contracts and batched broadcasting
packages/private/core/src/lib/realtimeChannels.ts, services/api/src/core/..., packages/private/backend-core/src/lib/...
Realtime channels support public AMA answers. Routes can return multiple channels, and publishing sends one message per channel.
Ticket claims and channel authorization
packages/private/backend-core/src/lib/wsTicket.ts, services/api/src/routes/ws/getTicket.ts, services/api/src/ws/..., docs/roadmap/01-architecture.md
Tickets include channel allowlists. Authorization supports admins, guild managers, AMA guests, and exact public answer channels.
Public ticket route and response channel
services/api/src/routes/ama/questions/..., services/api/src/app.ts, services/api/src/index.ts
Public answers responses expose their realtime channel. A share-token route mints a short-lived, channel-restricted ticket.
Public answer page subscription
apps/website/src/api/ws.ts, apps/website/src/hooks/..., apps/website/src/app/ama-answers/...
The website creates a public realtime client per share token and invalidates the answers query when updates arrive.
AMA invalidation producers and ordering
services/api/src/routes/ama/questions/..., services/ama-bot/src/components/..., apps/website/src/utils/util.ts, apps/website/src/app/dashboard/...
AMA actions notify both question and public answer channels. Guild sorting now uses bot count with alphabetical name ordering as the tiebreaker.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PublicAnswers
  participant publicAMAWsTicketRoute
  participant RealtimeClient
  participant AMAQuestionRoute
  participant publishRealtimeInvalidate
  PublicAnswers->>publicAMAWsTicketRoute: request share-token WebSocket ticket
  publicAMAWsTicketRoute-->>RealtimeClient: return channel-restricted ticket
  RealtimeClient->>PublicAnswers: subscribe to response realtime channel
  AMAQuestionRoute->>publishRealtimeInvalidate: publish question and public answer channels
  publishRealtimeInvalidate-->>RealtimeClient: deliver public answer invalidation
  RealtimeClient->>PublicAnswers: invalidate answers query
Loading

Possibly related PRs

  • ChatSift/chatsift#296: Introduced the public AMA answers flow extended here with realtime updates.
  • ChatSift/chatsift#297: Added the WebSocket gateway extended here with ticket claims and channel authorization.
  • ChatSift/chatsift#298: Added realtime infrastructure extended here with public AMA subscriptions and multi-channel invalidation.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.23% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description only references issue numbers and does not explain how those issues relate to the changeset. Add a brief summary of the guest and public realtime changes and the guild list ordering update.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the pull request's main changes: guest and public realtime support plus guild list ordering.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/guest-realtime

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/website/src/api/ws.ts (1)

87-130: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent a socket from opening after the final unsubscribe.

If mintTicket() resolves after the final listener unsubscribes, disconnect() sees no socket to close. Lines 89-130 then create and retain an idle socket with no channels. Public page navigation or unmount during ticket minting triggers this path.

Check this.channels.size immediately after ticket minting. Exit before constructing WebSocket when it is zero. Add coverage for an unsubscribe before the ticket promise resolves.

Proposed fix
 const ticket = await this.mintTicket();
+if (this.channels.size === 0) {
+	return;
+}
 const url = new URL(wsURL());
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/website/src/api/ws.ts` around lines 87 - 130, Update the async
connection flow around mintTicket() to check this.channels.size immediately
after the ticket resolves and return when it is zero, before constructing or
assigning a WebSocket. Preserve normal socket setup when channels remain
subscribed, and add coverage for unsubscribing before the ticket promise
resolves.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/website/src/app/ama-answers/`[shareToken]/_components/PublicAnswers.tsx:
- Around line 46-52: Add a confirmed-subscription callback or signal to the
useRealtimeInvalidate flow in PublicAnswers, and invalidate
queryKeys.ama.publicAnswers(shareToken) once the WebSocket subscription is
active, while preserving the existing realtime invalidation callback. Add an
integration test covering an answer mutation during the mint/subscription delay,
and run it against the affected service.

In `@services/api/src/core/__tests__/server.test.ts`:
- Around line 360-389: Add coverage in the server route tests for the string
form of RouteDefinition.realtimeChannel by defining a route whose
realtimeChannel returns one channel string, invoking its final handler with a
realtime client ID, and asserting publishRealtimeInvalidate is called exactly
once for that channel.

---

Outside diff comments:
In `@apps/website/src/api/ws.ts`:
- Around line 87-130: Update the async connection flow around mintTicket() to
check this.channels.size immediately after the ticket resolves and return when
it is zero, before constructing or assigning a WebSocket. Preserve normal socket
setup when channels remain subscribed, and add coverage for unsubscribing before
the ticket promise resolves.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5fe1b9ef-8df1-45ff-89b1-6a5f94c766e0

📥 Commits

Reviewing files that changed from the base of the PR and between eecc713 and a8769fb.

📒 Files selected for processing (28)
  • apps/website/src/api/ws.ts
  • apps/website/src/app/ama-answers/[shareToken]/_components/PublicAnswers.tsx
  • apps/website/src/app/dashboard/_components/GuildList.tsx
  • apps/website/src/hooks/usePublicRealtimeClient.ts
  • apps/website/src/hooks/useRealtimeInvalidate.ts
  • apps/website/src/utils/util.ts
  • docs/roadmap/01-architecture.md
  • packages/private/backend-core/src/lib/__tests__/realtimeBroadcast.test.ts
  • packages/private/backend-core/src/lib/realtimeBroadcast.ts
  • packages/private/backend-core/src/lib/wsTicket.ts
  • packages/private/core/src/lib/realtimeChannels.ts
  • services/ama-bot/src/components/markDuplicateSelect.ts
  • services/ama-bot/src/components/modApprove.ts
  • services/api/src/app.ts
  • services/api/src/core/__tests__/server.test.ts
  • services/api/src/core/route.ts
  • services/api/src/core/server.ts
  • services/api/src/index.ts
  • services/api/src/routes/ama/questions/mergeQuestion.ts
  • services/api/src/routes/ama/questions/mergeQuestionsBulk.ts
  • services/api/src/routes/ama/questions/publicAnswers.ts
  • services/api/src/routes/ama/questions/publicWsTicket.ts
  • services/api/src/routes/ama/questions/sendQuestion.ts
  • services/api/src/routes/ama/questions/updateQuestion.ts
  • services/api/src/routes/ws/getTicket.ts
  • services/api/src/ws/__tests__/authorizeChannel.test.ts
  • services/api/src/ws/authorizeChannel.ts
  • services/api/src/ws/server.ts

Comment thread services/api/src/core/__tests__/server.test.ts
@claude

claude Bot commented Aug 10, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@didinele
didinele merged commit 8cb8c6b into main Aug 10, 2026
5 of 6 checks passed
@didinele
didinele deleted the feat/guest-realtime branch August 10, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subscribing to WS channel updates for AMA guests should work /dashboard puts Guest guilds at the end

1 participant