🚀 Chat Features
Chat features provide complete, pre-composed functionality for chat management operations in Nodeblocks applications. These features combine schemas, routes, and handlers to create ready-to-use API endpoints with proper validation, authentication, and error handling.
🎯 Overview
Chat features are designed to:
- Provide complete API endpoints for chat management operations
- Combine schemas with routes for validated operations
- Include authentication and authorization checks automatically
- Support functional composition patterns
- Handle logging and error management seamlessly
This documentation is organized into three main subsections:
- 📺 Channel Features: Manage chat channels (create, read, update, delete, search)
- 💬 Message Features: Handle chat messages (create, read, update, delete, search)
- 🔔 Subscription Features: Manage user subscriptions to channels (create, read, delete, search)
📋 Feature Structure
Each chat feature follows a consistent composition pattern:
- Schema: Validates input data and parameters
- Route: Provides HTTP endpoint with handlers
- Composition: Combines schema and route using
composefunction
🔧 Available Chat Features
📺 Channel Features
createChannelFeature
Creates a new chat channel with validation and routing.
Purpose: Handles channel creation with complete validation
Composition:
- Schema:
createChatChannelSchema- validates name and ownerId - Route:
createChatChannelRoute- POST/channelswith creation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.createChannelFeature, [{ dataStores: db }])));
API Endpoint: POST /api/channels
getChannelFeature
Retrieves individual channel data with access control.
Purpose: Fetches channel details with proper authorization
Composition:
- Schema:
getChatChannelSchema- validates path parameters - Route:
getChatChannelRoute- GET/channels/:channelIdwith retrieval handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.getChannelFeature, [{ dataStores: db }])));
API Endpoint: GET /api/channels/:channelId
findChannelsFeature
Searches and lists channels with filtering and pagination.
Purpose: Provides channel listing with search capabilities
Composition:
- Schema:
findChatChannelsSchema- validates query parameters for filtering - Route:
findChatChannelsRoute- GET/channelswith search and pagination
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.findChannelsFeature, [{ dataStores: db }])));
API Endpoint: GET /api/channels
updateChannelFeature
Updates channel information with validation and access control.
Purpose: Modifies channel data with proper authorization
Composition:
- Schema:
updateChatChannelSchema- validates optional name - Route:
updateChatChannelRoute- PATCH/channels/:channelIdwith update handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.updateChannelFeature, [{ dataStores: db }])));
API Endpoint: PATCH /api/channels/:channelId
deleteChannelFeature
Deletes channels with proper authorization.
Purpose: Removes channels with access control
Composition:
- Schema:
deleteChatChannelSchema- validates path parameters - Route:
deleteChatChannelRoute- DELETE/channels/:channelIdwith deletion handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.deleteChannelFeature, [{ dataStores: db }])));
API Endpoint: DELETE /api/channels/:channelId
getChannelMessagesFeature
Channel messages retrieval feature with schema validation and routing.
Purpose: Handles fetching all messages for a specific channel with complete validation
Composition:
- Schema:
getChannelMessagesSchema- validates channelId path parameter - Route:
getChannelMessagesRoute- GET/channels/:channelId/messageswith retrieval handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage:
app.use('/api', defService(getChannelMessagesFeature));
// With database (handlers need dataStores):
app.use('/api', defService(partial(getChannelMessagesFeature, [{ dataStores: db }])));
API Endpoint: GET /api/channels/:channelId/messages
Response (200 OK): Array of message objects
Features:
- Validates user authentication and channel subscription
- Retrieves all messages for the specified channel
- Supports pagination via query parameters
- Proper error handling for missing channels or unauthorized access
Error Responses:
401: User is not authenticated403: User is not subscribed to the channel404: Channel does not exist500: Database operation failed
getChannelIconUploadUrlFeature
Chat channel icon upload URL feature with schema validation and routing.
Purpose: Generates signed upload URLs for chat channel icon images with proper authentication and authorization.
Composition:
- Schema:
getSignedImageUploadUrlSchema- validates contentType and file size for image uploads - Route:
getChatChannelIconUploadUrlRoute- GET/channels/:channelId/icon-upload-urlwith upload URL generation
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage:
app.use('/api', defService(features.getChannelIconUploadUrlFeature));
// With database configuration:
app.use('/api', defService(
partial(features.getChannelIconUploadUrlFeature, [
{ dataStores: db, fileStorageDriver: storageDriver }
])
));
API Endpoint: GET /api/channels/:channelId/icon-upload-url
Response (200 OK):
{
"objectId": "string",
"url": "string"
}
Key Features:
- Secure Upload URLs: Generates pre-signed URLs for direct file uploads to cloud storage
- File Type Validation: Validates content type and file size constraints
- Unique Object IDs: Generates UUID-based object identifiers for uploaded files
- Authorization Control: Restricts access to channel owners and admins
- Error Handling: Comprehensive error handling for storage and validation failures
Authorization:
- Requires authentication
- Accessible by channel owners or administrators
- Uses
somevalidator for flexible permission checking
Validation Rules:
- Path parameter
channelIdis required - Query parameters
contentTypeandcontentLengthare validated - File size limited to 10MB maximum
- Content type must be valid image MIME type
Error Responses:
400 Bad Request: Invalid query parameters or file constraints401 Unauthorized: Authentication required403 Forbidden: Insufficient permissions (not channel owner or admin)500 Internal Server Error: File storage service failure
Handler Process:
- Validates user authentication and channel ownership permissions
- Validates file upload parameters (content type, size)
- Generates unique object ID with file extension
- Creates signed upload URL using file storage driver
- Returns object ID and signed URL for client upload
Use Cases:
- Uploading channel profile images
- Updating channel avatars
- Managing channel branding assets
- Providing secure file upload capabilities
Data Flow:
- Input: Channel ID, content type, content length
- Validation: Authentication, authorization, file constraints
- Processing: UUID generation, file extension extraction, URL signing
- Output: Object ID and signed upload URL
Performance Notes:
- URL generation is lightweight and doesn't involve file operations
- No database writes during URL generation
- Suitable for high-frequency requests
- File storage driver handles the actual upload process
💬 Message Features
createChatMessageFeature
Creates a new chat message with validation and routing.
Purpose: Handles message creation with complete validation
Composition:
- Schema:
createChatMessageSchema- validates content, senderId, and channelId - Route:
createChatMessageRoute- POST/messageswith creation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.createChatMessageFeature, [{ dataStores: db }])));
API Endpoint: POST /api/messages
getChatMessageFeature
Retrieves individual message data with access control.
Purpose: Fetches message details with proper authorization
Composition:
- Schema:
getChatMessageSchema- validates path parameters - Route:
getChatMessageRoute- GET/messages/:messageIdwith retrieval handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.getChatMessageFeature, [{ dataStores: db }])));
API Endpoint: GET /api/messages/:messageId
findChatMessagesFeature
Searches and lists messages with filtering and pagination.
Purpose: Provides message listing with search capabilities
Composition:
- Schema:
findChatMessagesSchema- validates query parameters for filtering - Route:
findChatMessagesRoute- GET/messageswith search and pagination
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.findChatMessagesFeature, [{ dataStores: db }])));
API Endpoint: GET /api/messages
updateChatMessageFeature
Updates message content with validation and access control.
Purpose: Modifies message data with proper authorization
Composition:
- Schema:
updateChatMessageSchema- validates optional content and metadata - Route:
updateChatMessageRoute- PATCH/messages/:messageIdwith update handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.updateChatMessageFeature, [{ dataStores: db }])));
API Endpoint: PATCH /api/messages/:messageId
deleteChatMessageFeature
Deletes messages with proper authorization.
Purpose: Removes messages with access control
Composition:
- Schema:
deleteChatMessageSchema- validates path parameters - Route:
deleteChatMessageRoute- DELETE/messages/:messageIdwith deletion handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.deleteChatMessageFeature, [{ dataStores: db }])));
API Endpoint: DELETE /api/messages/:messageId
getChatMessageAttachmentUrlFeature
Chat message attachment upload URL generation feature with schema validation and routing.
Purpose: Provides secure file upload URLs for chat message attachments with malicious file type filtering
Composition:
- Schema:
getSignedFileUploadUrlSchema- validates file upload URL request parameters (contentType, contentLength) - Route:
getChatMessageAttachmentUploadUrlRoute- GET/messages/:messageId/attachment-upload-urlwith URL generation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage with file storage driver:
app.use('/api', defService(partial(features.getChatMessageAttachmentUrlFeature, [{ fileStorageDriver }])));
// With database and file storage:
app.use('/api', defService(partial(features.getChatMessageAttachmentUrlFeature, [{
dataStores: db,
fileStorageDriver
}])));
API Endpoint: GET /api/messages/:messageId/attachment-upload-url
Query Parameters:
contentType: string(required) - MIME type of file (validated against safe types)contentLength: integer(required) - File size in bytes (max 10MB)
Response Body:
{
"objectId": "unique-file-id.png",
"url": "https://storage.googleapis.com/bucket/unique-file-id.png?signature=..."
}
Key Features:
- Security-first approach with dangerous MIME type filtering
- File size validation (10MB maximum)
- Message ownership verification
- Time-limited signed URLs
- Proper file extension handling based on MIME type
Error Responses:
400- Invalid content type or file size exceeds limit401- Not authenticated403- Not authorized to access this message500- File storage or server error
Notes:
- Excludes dangerous file types (executables, scripts, archives)
- Uses
mime-typeslibrary for content type validation - Requires
fileStorageDriverin service configuration - Returns signed URL that clients use for direct upload to storage
createChatMessageAttachmentFeature
Chat message attachment creation feature with schema validation and routing.
Purpose: Enables adding file attachments to existing messages with automatic base entity generation
Composition:
- Schema:
createChatMessageAttachmentSchema- validates file reference (objectId, type) - Route:
createChatMessageAttachmentRoute- POST/messages/:messageId/attachmentswith creation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage with database:
app.use('/api', defService(partial(features.createChatMessageAttachmentFeature, [{ dataStores: db }])));
// Full configuration:
app.use('/api', defService(partial(features.createChatMessageAttachmentFeature, [{
dataStores: db,
configuration
}])));
API Endpoint: POST /api/messages/:messageId/attachments
Request Body:
{
"objectId": "550e8400-e29b-41d4-a716-446655440000",
"type": "image/png"
}
Response Body (status 201):
{
"objectId": "550e8400-e29b-41d4-a716-446655440000",
"type": "image/png",
"id": "generated-uuid",
"createdAt": "2023-10-15T10:30:00.000Z",
"updatedAt": "2023-10-15T10:30:00.000Z"
}
Key Features:
- Automatic base entity field generation (
id,createdAt,updatedAt) - Message ownership validation (sender-only access)
- UUID validation for objectId
- Atomic MongoDB
$pushoperation - Returns complete attachment with generated fields
- Full error handling
Error Responses:
400- Invalid request body (missing objectId or type, invalid UUID)401- Not authenticated403- Not authorized (not message owner)404- Message not found500- Database error
Workflow:
- Get upload URL via
getChatMessageAttachmentUrlFeature - Upload file to signed URL
- Create attachment via
createChatMessageAttachmentFeaturewith returned objectId - Attachment is added to message's attachments array with auto-generated fields
Notes:
- Requires message to exist before adding attachments
- Each attachment gets unique ID and timestamps
- Works in conjunction with
getChatMessageAttachmentUrlFeaturefor complete file upload workflow - Message owner can add multiple attachments to same message
deleteChatMessageAttachmentFeature
Chat message attachment deletion feature with schema validation and routing.
Purpose: Enables removing file attachments from messages and deleting them from storage
Composition:
- Schema:
deleteChatMessageAttachmentSchema- validates messageId and attachmentId path parameters - Route:
deleteChatMessageAttachmentRoute- DELETE/messages/:messageId/attachments/:attachmentIdwith deletion handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage with database and file storage:
app.use('/api', defService(partial(features.deleteChatMessageAttachmentFeature, [{
dataStores: db,
fileStorageDriver
}])));
// Full configuration:
app.use('/api', defService(partial(features.deleteChatMessageAttachmentFeature, [{
dataStores: db,
fileStorageDriver,
configuration
}])));
API Endpoint: DELETE /api/messages/:messageId/attachments/:attachmentId
Response: No content (status 204) on success
Key Features:
- Removes attachment from message's attachments array
- Deletes physical file from storage
- Automatic message
updatedAttimestamp update - Admin or owner authorization (admin can delete any, owner can delete own)
- Atomic MongoDB
$pulloperation - Full error handling
Error Responses:
401- Not authenticated403- Not authorized (not admin or message owner)404- Message not found or attachment not found500- Database error or file storage error
Usage Example:
// Client-side deletion:
const response = await fetch(`/api/messages/${messageId}/attachments/${attachmentId}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer <token>'
}
});
if (response.status === 204) {
// Attachment deleted successfully
}
Notes:
- Requires message to exist with matching attachment
- Deletes both database reference and physical file
- Admin users can delete any attachment; regular users can only delete attachments from their own messages
- Works in conjunction with
createChatMessageAttachmentFeaturefor complete attachment lifecycle
streamChatMessagesFeature
Streams chat messages in real-time via WebSocket with schema validation.
Purpose: Enables real-time message streaming to clients with proper validation
Composition:
- Schema:
streamChatMessagesSchema- validates channelId query parameter for streaming - Route:
streamChatMessagesRoute- WebSocket/messages/listenwith real-time message streaming handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database and WebSocket server configuration
app.use('/api', defService(
partial(features.streamChatMessagesFeature, [{ dataStores: db }]),
webSocketServer
));
WebSocket Endpoint: ws://localhost:3000/api/messages/listen?channelId={channelId}
Client Example:
// Establish WebSocket connection
const ws = new WebSocket(
'ws://localhost:3000/api/messages/listen?channelId=channel123'
);
// Handle incoming messages
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('New message received:', message);
// message contains: id, channelId, senderId, content, createdAt, updatedAt
};
// Handle connection open
ws.onopen = () => {
console.log('Connected to chat stream');
};
// Handle errors
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
// Handle connection close
ws.onclose = (event) => {
console.log('Disconnected from chat stream');
};
Server Setup:
import { WebSocketServer } from 'ws';
import { chatService } from '@nodeblocks/backend-sdk';
// Create WebSocket server
const wss = new WebSocketServer({ noServer: true });
// Register chat service with WebSocket support
app.use('/api/chat', chatService(
database,
config,
{ webSocketServer: wss }
));
// Upgrade HTTP server for WebSocket
server.on('upgrade', (request, socket, head) => {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
});
Features:
- Real-time message streaming using MongoDB change streams
- Automatic message normalization (removes internal fields)
- Channel-specific filtering (only messages for specified channel)
- Schema validation for channelId parameter
- WebSocket protocol support
Error Responses:
400: Missing or invalid channelId parameter500: Failed to create change stream or unknown error
Notes:
- Only new messages (insert operations) are streamed
- Messages are automatically normalized before transmission
- Connection stays open until client disconnects
- Authentication validators pending WebSocket IP format fix
🧩 Message Template Features
createChatMessageTemplateFeature
Creates a new chat message template with validation and routing.
Purpose: Handles creation of reusable message templates
Composition:
- Schema:
createChatMessageTemplateSchema- validates content and title; optional organizationId and permissions - Route:
createChatMessageTemplateRoute- POST/message-templateswith creation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
app.use('/api', defService(partial(features.createChatMessageTemplateFeature, [{ dataStores: db }])));
API Endpoint: POST /api/message-templates
getChatMessageTemplateFeature
Retrieves a chat message template by ID with access control.
Purpose: Fetches template data securely
Composition:
- Schema:
getChatMessageTemplateSchema- validates path parameter - Route:
getChatMessageTemplateRoute- GET/message-templates/:messageTemplateId
Usage:
import { features } from '@nodeblocks/backend-sdk';
app.use('/api', defService(partial(features.getChatMessageTemplateFeature, [{ dataStores: db }])));
API Endpoint: GET /api/message-templates/:messageTemplateId
updateChatMessageTemplateFeature
Updates an existing chat message template with partial data support.
Purpose: Modifies existing message templates for content updates with proper authorization
Composition:
- Schema:
updateChatMessageTemplateSchema- validates path parameter and partial body - Route:
updateChatMessageTemplateRoute- PATCH/message-templates/:messageTemplateIdwith update handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
app.use('/api', defService(partial(features.updateChatMessageTemplateFeature, [{ dataStores: db }])));
API Endpoint: PATCH /api/message-templates/:messageTemplateId
deleteChatMessageTemplateFeature
Deletes a chat message template with proper authorization.
Purpose: Removes existing message templates from the database with access control and validation.
Composition:
- Schema:
deleteChatMessageTemplateSchema- validates messageTemplateId path parameter - Route:
deleteChatMessageTemplateRoute- DELETE/message-templates/:messageTemplateIdwith deletion handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
app.use('/api', defService(partial(features.deleteChatMessageTemplateFeature, [{ dataStores: db }])));
API Endpoint: DELETE /api/message-templates/:messageTemplateId
Response (204 No Content):
{}
Key Features:
- Authorization Control: Restricts access to template owners, organization admins, or system admins
- Safe Deletion: Validates template existence before deletion
- Atomic Operations: Uses MongoDB atomic delete operations
- Error Handling: Comprehensive error handling for validation and database failures
Authorization:
- Requires authentication
- Accessible by template owners, organization administrators, or system administrators
Error Responses:
401: Unauthorized - Invalid or missing authentication403: Forbidden - User lacks permission to delete this template404: Not Found - Template does not exist500: Internal Server Error - Database or system error
findChatMessageTemplatesFeature
Chat message templates listing feature with schema validation and routing.
Purpose: Lists chat message templates with filtering, pagination, and data normalization
Composition:
- Schema:
findChatMessageTemplatesSchema- validates pagination and query filters - Route:
findChatMessageTemplatesRoute- GET/message-templateswith listing handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage:
app.use('/api', defService(findChatMessageTemplatesFeature));
// With database configuration:
app.use('/api', defService(partial(findChatMessageTemplatesFeature, [{ dataStores: db }])));
API Endpoint: GET /api/message-templates
Request Parameters:
- Query Parameters:
page(optional): Page number for pagination (default: 1)limit(optional): Number of templates per page (default: 10)
Response (200 - Success):
{
"data": [
{
"id": "template-123",
"title": "Welcome Message",
"content": "Hello, welcome to our chat!",
"organizationId": "org-456",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
],
"metadata": {
"pagination": {
"hasNext": false,
"hasPrev": false,
"limit": 10,
"page": 1,
"total": 1,
"totalPages": 1
}
}
}
Authorization:
- Requires authentication
- Restricted to admin users only (
checkIdentityType(['admin']))
Error Responses:
401: Unauthorized - Invalid or missing authentication403: Forbidden - User is not an admin404: Not Found - No templates found (returns empty array, not error)500: Internal Server Error - Database or system error
findChatMessageTemplatesForOrganizationFeature
Chat message templates listing for organization feature with schema validation and routing.
Purpose: Lists chat message templates scoped to a specific organization with filtering, pagination, and data normalization
Composition:
- Schema:
findChatMessageTemplatesForOrganizationSchema- validates organization ID path parameter and pagination query parameters - Route:
findChatMessageTemplatesForOrganizationRoute- GET/organizations/:organizationId/message-templateswith organization-specific listing handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage:
app.use('/api', defService(findChatMessageTemplatesForOrganizationFeature));
// With database configuration:
app.use('/api', defService(partial(findChatMessageTemplatesForOrganizationFeature, [{ dataStores: db }])));
API Endpoint: GET /api/organizations/:organizationId/message-templates
Request Parameters:
- Path Parameters:
organizationId(required): Target organization ID to retrieve templates for
- Query Parameters:
page(optional): Page number for pagination (default: 1)limit(optional): Number of templates per page (default: 10)
Response (200 - Success):
{
"data": [
{
"id": "template-123",
"title": "Welcome Message",
"content": "Hello, welcome to our organization!",
"organizationId": "org-456",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
],
"metadata": {
"pagination": {
"hasNext": false,
"hasPrev": false,
"limit": 10,
"page": 1,
"total": 1,
"totalPages": 1
}
}
}
Authorization:
- Requires authentication
- Restricted to organization members with 'owner' or 'admin' roles via
hasOrgRole(['owner', 'admin'])
Error Responses:
401: Unauthorized - Invalid or missing authentication token403: Forbidden - User lacks organization access or insufficient role permissions404: Not Found - Organization not found or no templates available500: Internal Server Error - Database or normalization error
Key Features:
- Organization Scoping: Templates are filtered by organization membership
- Role-Based Access: Only organization owners and admins can access
- Pagination Support: Full pagination with metadata for large template sets
- Data Normalization: Automatic document normalization for API responses
🔔 Subscription Features
createChatSubscriptionFeature
Creates a new chat subscription with validation and routing.
Purpose: Handles subscription creation with complete validation
Composition:
- Schema:
createChatSubscriptionSchema- validates channelId and optional fields - Route:
createChatSubscriptionRoute- POST/subscriptionswith creation handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.createChatSubscriptionFeature, [{ dataStores: db }])));
API Endpoint: POST /api/subscriptions
getChatSubscriptionFeature
Retrieves individual subscription data with access control.
Purpose: Fetches subscription details with proper authorization
Composition:
- Schema:
getChatSubscriptionSchema- validates path parameters - Route:
getChatSubscriptionRoute- GET/subscriptions/:subscriptionIdwith retrieval handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.getChatSubscriptionFeature, [{ dataStores: db }])));
API Endpoint: GET /api/subscriptions/:subscriptionId
findChatSubscriptionsFeature
Searches and lists subscriptions with filtering and pagination.
Purpose: Provides subscription listing with search capabilities
Composition:
- Schema:
findChatSubscriptionsSchema- validates query parameters for filtering - Route:
findChatSubscriptionsRoute- GET/subscriptionswith search and pagination
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.findChatSubscriptionsFeature, [{ dataStores: db }])));
API Endpoint: GET /api/subscriptions
deleteChatSubscriptionFeature
Deletes subscriptions with proper authorization.
Purpose: Removes subscriptions with access control
Composition:
- Schema:
deleteChatSubscriptionSchema- validates path parameters - Route:
deleteChatSubscriptionRoute- DELETE/subscriptions/:subscriptionIdwith deletion handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// With database configuration
app.use('/api', defService(partial(features.deleteChatSubscriptionFeature, [{ dataStores: db }])));
API Endpoint: DELETE /api/subscriptions/:subscriptionId
upsertChatChannelReadStateFeature
Chat channel read state upsert feature with schema validation and routing.
Purpose: Handles upserting channel read states with complete validation
Composition:
- Schema:
upsertChatChannelReadStateSchema- validates channel read state upsert data - Route:
upsertChatChannelReadStateRoute- PUT/channels/:channelId/read-statewith upsert handler
Usage:
import { features } from '@nodeblocks/backend-sdk';
// Direct usage:
app.use('/api', defService(upsertChatChannelReadStateFeature));
// With database (handlers need dataStores):
app.use('/api', defService(partial(upsertChatChannelReadStateFeature, [{ dataStores: db }])));
API Endpoint: PUT /api/channels/:channelId/read-state
Request Body:
{
identityId: string; // required - user identity ID
lastReadMessageId: string; // required - last read message ID
}
Response (204 No Content): Empty response body on successful upsert
Features:
- Automatic upsert logic (create or update based on existence)
- Validates channel existence and user subscription
- Validates last read message existence
- Ensures user can only update their own read state
- Automatic timestamp management
- Proper error handling for missing resources
Error Responses:
401: User is not authenticated403: User is not subscribed to channel or trying to update another user's read state404: Channel or last read message not found500: Database operation failed