Skip to content

Chat — Views

Overview

The view layer in the chat app exposes the HTTP API for chat workflows.

It is responsible for:

  • listing conversations
  • creating conversations
  • listing message history
  • uploading attachments
  • marking conversations as read
  • listing and managing participants
  • editing and deleting messages

The view layer should remain thin.

Its job is to:

  • authenticate the request
  • resolve org context where needed
  • validate request payloads
  • call service functions
  • translate service errors into HTTP responses
  • return serialized data

Business workflow logic belongs in services, not in views.


View structure

The chat views are split into focused modules:

  • views/conversations.py
  • views/messages.py
  • views/attachments.py
  • views/participants.py
  • views/read_state.py

This structure mirrors the service and serializer layers and makes the API easier to understand.


views/conversations.py

This module exposes conversation list and creation endpoints.

Main endpoints

  • internal org conversation list
  • customer org conversation list
  • create conversation

Responsibilities

  • enforce authentication
  • enforce org or customer-org scoping
  • validate conversation creation payloads
  • call conversation services
  • serialize conversation responses

Main view classes

  • ConversationsInOrgView
  • ConversationsInCustomerOrgView
  • CreateConversationView

Internal conversation list

This endpoint lists conversations for the current internal org.

Responsibilities

  • require HasCurrentOrg
  • list conversations for request.org
  • return frontend-friendly conversation summaries

Response shape

Typically includes:

  • conversation metadata
  • unread count
  • participant count
  • last message preview

Customer conversation list

This endpoint lists conversations for the current customer org.

Responsibilities

  • require HasCurrentCustomerOrg
  • list conversations for request.customer_org
  • return frontend-friendly conversation summaries

Create conversation

This endpoint creates a conversation from the internal side.

Responsibilities

  • require internal org scope
  • validate customer_org_id
  • call conversation creation service
  • return created conversation

Business rule

The view does not decide whether the customer org is linked.
That is handled in the service layer.


views/messages.py

This module exposes message history and message mutation endpoints.

Main endpoints

  • list messages
  • edit message
  • delete message

Main view classes

  • MessagesView
  • EditMessageView
  • DeleteMessageView

List messages

Returns paginated message history for a conversation.

Responsibilities

  • ensure user is a valid participant
  • read pagination inputs such as:
  • limit
  • before
  • call message listing service
  • return:
  • items
  • next_before

Pagination model

The endpoint uses cursor-like pagination by timestamp.

The backend returns messages in oldest-to-newest order within the returned page.

Why this matters

This is especially useful for chat UIs because the frontend can:

  • load recent messages
  • request older history when scrolling upward

Edit message

Allows the sender to edit a message.

Responsibilities

  • validate payload
  • call message edit service
  • translate validation and permission errors
  • return updated message

Business rules

The sender-only rule is enforced in services, not in the view.


Delete message

Soft-deletes a message.

Responsibilities

  • call message delete service
  • translate validation and permission errors
  • return updated message payload

Business rules

Only the sender may delete their own message.

The delete is soft-delete, not hard-delete.


views/attachments.py

This module exposes attachment upload.

Main endpoint

  • upload attachment to a conversation

Main view class

  • UploadAttachmentView

Responsibilities

  • require authentication
  • parse multipart/form-data
  • call attachment upload service
  • map service errors to HTTP responses
  • return serialized attachment metadata

Why this matters

This endpoint supports the upload-first workflow:

  1. upload file
  2. receive attachment ID
  3. send message later using that attachment ID

This is especially helpful for web and mobile clients.


views/participants.py

This module exposes participant membership endpoints.

Main endpoints

  • list participants
  • add participant
  • remove participant

Main view classes

  • ListParticipantsView
  • AddParticipantView
  • RemoveParticipantView

List participants

Returns active participants in a conversation.

Responsibilities

  • require authentication
  • ensure requester is an active participant
  • return participant metadata

Typical response data

  • user id
  • username
  • display name
  • role
  • last read timestamp
  • join timestamp

Add participant

Adds or reactivates a participant in a conversation.

Responsibilities

  • validate request payload
  • call participant add service
  • map permission and validation errors
  • return created or reactivated participant

Business rules

The service layer decides:

  • whether the actor may add participants
  • whether the target user belongs to an allowed org side

Remove participant

Removes a participant by setting is_active=False.

Responsibilities

  • require authentication
  • call participant removal service
  • return success response

Notes

This is a deactivation operation, not a hard delete.


views/read_state.py

This module exposes read-state operations.

Main endpoint

  • mark a conversation as read

Main view class

  • MarkReadView

Responsibilities

  • require authentication
  • call read-state service
  • update participant read cursor
  • return updated timestamp

Why this matters

This endpoint powers unread counts and allows the frontend to sync the user’s read position.


Permissions and scoping

The chat app uses a mix of:

  • authentication
  • org scoping
  • participant-based service checks

Common permission patterns

Internal conversation endpoints

Use:

  • IsAuthenticated
  • HasCurrentOrg

Customer conversation endpoints

Use:

  • IsAuthenticated
  • HasCurrentCustomerOrg

Participant-scoped endpoints

Most message, attachment, participant, and read-state endpoints use:

  • IsAuthenticated

Then participant access is enforced by services.


Error handling

Views translate service-layer exceptions into HTTP responses.

Typical mappings include:

  • 400 Bad Request
  • invalid payload
  • invalid upload
  • invalid business input

  • 403 Forbidden

  • user not allowed
  • user not participant
  • sender-only action violation

  • 404 Not Found

  • message not found
  • conversation not found

  • 201 Created

  • conversation created
  • attachment uploaded

  • 200 OK

  • list success
  • edit/delete success
  • mark read success
  • participant add/remove success

This keeps services transport-agnostic and views responsible for HTTP semantics.


Core HTTP flows

Conversation list flow

Main steps

  1. authenticate request
  2. resolve org context
  3. call conversation list service
  4. serialize list items
  5. return response

Mermaid flow

flowchart TD
    A[GET conversations] --> B[Auth + org scope]
    B --> C[Conversation service]
    C --> D[ConversationListSerializer]
    D --> E[HTTP 200 response]

Create conversation flow

Main steps

  1. authenticate request
  2. resolve internal org context
  3. validate request payload
  4. call create conversation service
  5. serialize conversation
  6. return response

Mermaid flow

flowchart TD
    A[POST create conversation] --> B[Auth + HasCurrentOrg]
    B --> C[ConversationCreateSerializer]
    C --> D[create_conversation service]
    D --> E[ConversationSerializer]
    E --> F[HTTP 201 response]

Message history flow

Main steps

  1. authenticate request
  2. read limit and before
  3. call list messages service
  4. serialize message list
  5. return items and next_before

Mermaid flow

flowchart TD
    A[GET messages] --> B[Auth]
    B --> C[Read query params]
    C --> D[list_messages service]
    D --> E[MessageSerializer]
    E --> F[Return items + next_before]

Attachment upload flow

Main steps

  1. authenticate request
  2. parse multipart payload
  3. call upload attachment service
  4. serialize attachment
  5. return 201 response

Mermaid flow

flowchart TD
    A[POST upload attachment] --> B[Auth]
    B --> C[Parse multipart file]
    C --> D[upload_attachment service]
    D --> E[MessageAttachmentSerializer]
    E --> F[HTTP 201 response]

Edit message flow

Main steps

  1. authenticate request
  2. validate edit payload
  3. call edit message service
  4. serialize updated message
  5. return response

Mermaid flow

flowchart TD
    A[POST edit message] --> B[Auth]
    B --> C[MessageEditSerializer]
    C --> D[edit_message service]
    D --> E[MessageSerializer]
    E --> F[HTTP 200 response]

Delete message flow

Main steps

  1. authenticate request
  2. call delete message service
  3. serialize updated message
  4. return response

Mermaid flow

flowchart TD
    A[POST delete message] --> B[Auth]
    B --> C[delete_message service]
    C --> D[MessageSerializer]
    D --> E[HTTP 200 response]

Participant management flow

Add participant

  1. authenticate request
  2. validate add payload
  3. call participant add service
  4. serialize participant
  5. return response

Remove participant

  1. authenticate request
  2. call remove participant service
  3. return success response

Mermaid flow

flowchart TD
    A[POST add participant] --> B[Auth]
    B --> C[AddParticipantSerializer]
    C --> D[add_participant service]
    D --> E[ParticipantSerializer]
    E --> F[HTTP 200 response]

Read-state flow

Main steps

  1. authenticate request
  2. call mark read service
  3. return updated read timestamp

Mermaid flow

flowchart TD
    A[POST mark read] --> B[Auth]
    B --> C[mark_conversation_read service]
    C --> D[Return last_read_at]
    D --> E[HTTP 200 response]

Responsibilities by layer

View layer owns

  • request parsing
  • serializer invocation
  • permission wiring
  • HTTP status mapping
  • response construction

Service layer owns

  • conversation rules
  • participant checks
  • message workflows
  • attachment lifecycle
  • unread/read logic
  • notification hooks

Serializer layer owns

  • payload validation
  • response shaping

Consumer layer owns

  • realtime websocket delivery
  • websocket event parsing
  • channel-layer broadcasting

What views do not do

Views do not:

  • compute unread counts directly
  • determine participant eligibility directly
  • attach uploaded files directly
  • persist messages directly
  • enforce sender-only edit/delete directly
  • send notifications directly
  • broadcast websocket events

Those responsibilities belong to:

  • services
  • consumers

Frontend readiness

The view split is an important step toward frontend readiness.

It gives you:

  • clear endpoint ownership
  • cleaner API contracts
  • more stable response shapes
  • easier mapping between REST and websocket responsibilities
  • simpler documentation for web and mobile teams

REST responsibilities for frontend

REST should handle:

  • conversation list
  • initial conversation history
  • pagination
  • upload attachment
  • mark read
  • participant management
  • edit/delete actions

Websocket responsibilities for frontend

Websocket should handle:

  • realtime incoming messages
  • typing indicators
  • future live edits/deletes/read updates if added

Design principles

Thin controllers

Views should orchestrate, not own workflow logic.

Explicit endpoint boundaries

Each endpoint group should map clearly to one domain area:

  • conversations
  • messages
  • attachments
  • participants
  • read state

Stable response contracts

Views should return predictable shapes for frontend integration.

Service-driven behavior

All business decisions should come from services.


Best practices

  • keep views small and explicit
  • use dedicated serializers for write actions
  • map service exceptions cleanly to HTTP responses
  • keep participant validation out of inline view code
  • keep org-scoped endpoints explicit
  • avoid duplicating workflow logic across views and consumers

Future extensions

Possible future view improvements include:

  • message create via REST in addition to websocket
  • conversation detail endpoint
  • conversation close/reopen endpoints
  • archive or mute conversation endpoints
  • message search endpoint
  • attachment list endpoint
  • presence/read receipt endpoints

Summary

The chat view layer exposes the HTTP API for:

  • conversations
  • messages
  • attachments
  • participants
  • read state

It ensures the app is:

  • cleanly structured
  • easy to test
  • easier to document
  • much more ready for frontend integration