Skip to content

Backend Kisum Chat (people messaging)

Port: 3810
Ownership: conversations, participants, messages (text, offer_card), read cursors.
Not: KisumAI sessions, Auth identity, booking logic.

  1. Browser or mobile calls a persona BFF (/api/messaging/* on Promoters; /api/v1/messaging/* on Artists and Venues).
  2. BFF forwards to Chat /internal/* with X-Internal-API-Key + X-Actor-User-Id (+ x-org when present).
  3. Chat persists to Postgres (chat_data), then publishes Centrifugo channels:
    • chat:conversation:{id} — thread events (message, read)
    • chat:user:{userId} — inbox bump
  4. Clients obtain a short-lived Centrifugo connection JWT from the BFF (/api/messaging/realtime/token); subscribe ACL is enforced via BFF subscribe proxy (/internal/centrifugo/subscribe).

When a message is sent, Chat notifies other participants via Expo Push (FCM/APNs through Expo’s push API).

  1. MobileApp-KisumAI registers an Expo push token after sign-in: PUT /api/messaging/push-tokens (Promoters BFF → Chat /internal/push-tokens). Body: { token, platform }.
  2. While the user is viewing a thread, the app sets PUT …/push-tokens/active-conversation with { token, conversationId } so pushes for that thread are suppressed on that device.
  3. On POST …/messages, Chat loads recipient tokens (excluding suppressed conversation) and sends { title: sender name, body: preview, data: { type: "people_message", conversationId, … } }.
  4. Sign-out: DELETE …/push-tokens with { token }.
VariablePurpose
EXPO_PUSH_ENABLEDDefault true; set false to disable sends
EXPO_PUSH_ACCESS_TOKENOptional Expo API bearer for production rate limits

Ops: Configure FCM (Android) and APNs (iOS) credentials in the EAS project for app app.kisum. Push does not work on simulators without a physical device and a dev/production build that includes expo-notifications.

  • GET …/conversations/:id/messages{ data: { messages: Message[], peerRead: { userId, lastReadAt?, lastReadMessageId? } } }
    peerRead is the other participant’s read cursor from conversation_reads (direct chats).
  • POST …/conversations/:id/read updates the caller’s cursor and publishes { type: "read", userId, lastReadAt, lastReadMessageId? } on the conversation channel.
  • DELETE …/conversations/:id (user /api/v1 and BFF /internal) — caller must be a participant.
  • Hard delete: removes the conversation row; messages, participants, and read cursors cascade away. The other person also loses the thread.
  • Response 204 No Content. Publishes an inbox bump (deleted: true) on each former participant’s chat:user:{userId} channel.
  • BFF paths: Promoters DELETE /api/messaging/conversations/:id; Artists/Venues DELETE /api/v1/messaging/conversations/:id.

Web (Promoters, Artists, Venues) and MobileApp-KisumAI thread UI: WhatsApp-style bubbles (peer left / Me right), date separators, checkmarks on sent messages when peerRead covers the message time.

BFF user search (Promoters, Artists, Venues)

Section titled “BFF user search (Promoters, Artists, Venues)”
  • Promoters: GET /api/messaging/users/search?q=
  • Artists / Venues: GET /api/v1/messaging/users/search?q=

Bearer + x-org. Matches company members by name, email, or user UUID. If no member match, falls back to Auth exact email or exact UUID (excluding the signed-in user). Response: { data: [{ id, email, name }] } (max 15).

Unread indicators (Promoters + Artists web)

Section titled “Unread indicators (Promoters + Artists web)”

Total unread = sum of unreadCount on GET /api/messaging/conversations. Shown on sidebar Messages, header inbox control (next to search), and floating Messages FAB. Refreshed on Centrifugo inbox events and after POST …/read.

Inbox rows include peerName / peerEmail (Chat resolves peer Auth user id) for conversation titles; previewText is the last message snippet only.

VariablePurpose
DATABASE_URLDedicated chat Postgres
AUTH_BASE_URL, AUTH_JWT_*User JWT validation (/api/v1/*)
AUTH_INTERNAL_API_KEYEmail lookup via Auth internal API
CHAT_INTERNAL_API_KEYInbound BFF machine routes
CENTRIFUGO_API_URL, CENTRIFUGO_API_KEYPublish after write
EXPO_PUSH_ENABLED, EXPO_PUSH_ACCESS_TOKENMobile people-message push via Expo
VariablePurpose
CHAT_INTERNAL_BASE_URLe.g. http://chat:3810
CHAT_INTERNAL_API_KEYMatches Chat service
CENTRIFUGO_TOKEN_SECRETHS256 connection tokens (server only)

Workspace root docker-compose.backends.yml service chat — host 3810, DNS chat:3810. Migrations: make -C modules/Backend-Kisum-Chat migrate-up or ./run-Docker_Composer.sh chat. Promoters waits for Chat healthy for people messaging BFF.

  • messaging.use
  • messaging.direct