Skip to content

Internal

Internal-only tooling. Currently limited to the Internal Chat workspace — a Slack-style channels + DMs surface for staff collaboration.

Scope

This namespace is for features that are meaningful only to staff and have no external-facing variant. Today it hosts chat; future developer/admin utilities (debug consoles, data exports, tooling) would live here.

Pages

  • src/pages/internal/Chat.tsx — mounted at /internal/chat.

Route (src/App.tsx:197):

<Route path="/internal/chat"
  element={<ProtectedRoute requiredPermissions={['chat.view']}>
    <ChatPage />
  </ProtectedRoute>} />

Internal Chat

Slack-like layout (see Chat.tsx:293):

  • Left rail — search, channel list, DM list, and two CTAs: New channel and New DM.
  • Main pane — message list + composer.
  • Thread panelThreadPanel drawer for replies (opens on right).

Capabilities:

Capability Component / Service
Public / private channels ChannelList, createChannel() (services/chatService.ts)
Direct messages DMList, createDMWithUser()
Realtime delivery Supabase Realtime via subscribeToMessages()
Presence createPresenceChannel() shows "N online" pill
Reactions toggleReaction()
Threaded replies parentMessageId on sendMessage()
Soft delete / edit softDeleteMessage(), updateMessage()
Read receipts upsertReadState()
Mentions + sounds playMentionSound, playMessageSound, playDMSound (src/lib/notificationSound.ts)
Attachments ChatAttachmentInput → Supabase Storage

Migration dependency

If the chat tables are missing (supabase/migrations/20260122100000_chat.sql not applied), the page shows an inline error instead of loading:

Chat tables are missing. Apply migration supabase/migrations/20260122100000_chat.sql. See Chat.tsx:117.

Audience

All staff roles with chat.view. The matrix grants chat.view to every internal staff role (super-admins, managers, execs). Portal roles (AGENT, CUSTOMER) do not get it.

chat.view history

Referenced by /internal/chat since day one, but originally unseeded. Drift #1 in docs/PERMISSIONS.md §8 notes that it was backfilled by supabase/migrations/20260416030000_seed_chat_and_dashboard_view.sql.

Permissions

Action Permission Enforcement
View /internal/chat chat.view Route guard
Create channel chat.view No finer gate today; any staff member with chat access can create channels
Delete channel chat.view + ownership (server RLS)
Send / edit / delete own messages chat.view + author check Server RLS enforces authorId = auth.uid() for edits/deletes
Send DM chat.view DM participant check enforced server-side

API / service surface

Chat does not go through src/lib/api.ts — it talks to Supabase directly via src/services/chatService.ts. Underlying tables live in the ChatChannel, ChatChannelMember, ChatDM, ChatDMMember, ChatMessage, ChatReaction, ChatReadState models (Prisma schema).

  • Dashboard → docs/features/dashboard.md (chat notifications feed can also appear as push notifications).
  • Communications (customer-facing broadcasts) → docs/features/communications.md.