

# **TUTORHUB**

**FRONTEND GUIDE FOR AI CODING AGENTS - PART 12 - Messaging Service**

This document is a part of a REST API guide for the tutorhub project.
It is designed for AI agents that will generate frontend code to consume the project’s backend.

This document provides extensive instruction for the usage of messaging

## Service Access

Messaging service management is handled through service specific base urls.

Messaging  service may be deployed to the preview server, staging server, or production server. Therefore,it has 3 access URLs.
The frontend application must support all deployment environments during development, and the user should be able to select the target API server on the login page (already handled in first part.).

For the messaging service, the base URLs are:

* **Preview:** `https://tutorhub.prw.mindbricks.com/messaging-api`
* **Staging:** `https://tutorhub-stage.mindbricks.co/messaging-api`
* **Production:** `https://tutorhub.mindbricks.co/messaging-api`


## Scope

**Messaging Service Description**

Real-time messaging service: student-tutor chat (bidirectional), admin-student warnings (one-way), admin-tutor communication (bidirectional). Uses RealtimeHub for WebSocket chat with persistence, typing, and read receipts.

Messaging service provides apis and business logic for following data objects in tutorhub application. 
Each data object may be either a central domain of the application data structure or a related helper data object for a central concept.
Note that data object concept is equal to table concept in the database, in the service database each data object is represented as a db table scheme and the object instances as table rows.  


**`conversation` Data Object**: Represents a chat channel between two participants. Types: studentTutor (bidirectional enrolled chat), adminStudent (one-way admin warnings), adminTutor (bidirectional admin-tutor communication).

**`chatMessage` Data Object**: Auto-generated message DataObject for the chat RealtimeHub. Stores all messages with typed content payloads.

**`chatModeration` Data Object**: Auto-generated moderation DataObject for the chat RealtimeHub. Stores block and silence actions for room-level user moderation.


## Messaging Service Frontend Description By The Backend Architect

## Messaging Service UX Guide

### Three Channel Types:
1. **Student ↔ Tutor** (studentTutor): Bidirectional chat between enrolled student and their tutor. Created when enrollment becomes active.
2. **Admin → Student** (adminStudent): One-way channel. Admin sends warnings/notices. Student can only read, not reply.
3. **Admin ↔ Tutor** (adminTutor): Bidirectional. Admin sends warnings, tutor can reply/discuss.

### UX Behavior:
- Inbox shows all conversations sorted by lastMessageAt descending
- Unread badge count per conversation
- For adminStudent conversations, hide the message input for students — show a notice: 'This is a notification channel. You cannot reply.'
- Warning messages (messageType=warning) should render with a yellow/amber alert style, distinct from regular text messages
- System messages render centered, gray, smaller font
- Show participant name + avatar in conversation header
- Real-time: typing indicators, read receipts, online presence

## API Structure

### Object Structure of a Successful Response

When the service processes requests successfully, it wraps the requested resource(s) within a JSON envelope. This envelope includes the data and essential metadata such as configuration details and pagination information, providing context to the client.

**HTTP Status Codes:**

* **200 OK**: Returned for successful GET, LIST, UPDATE, or DELETE operations, indicating that the request was processed successfully.
* **201 Created**: Returned for CREATE operations, indicating that the resource was created successfully.

**Success Response Format:**

For successful operations, the response includes a `"status": "OK"` property, signaling that the request executed successfully. The structure of a successful response is outlined below:

```json
{
  "status":"OK",
  "statusCode": 200,   
  "elapsedMs":126,
  "ssoTime":120,
  "source": "db",
  "cacheKey": "hexCode",
  "userId": "ID",
  "sessionId": "ID",
  "requestId": "ID",
  "dataName":"products",
  "method":"GET",
  "action":"list",
  "appVersion":"Version",
  "rowCount":3,
  "products":[{},{},{}],
  "paging": {
    "pageNumber":1, 
    "pageRowCount":25, 
    "totalRowCount":3,
    "pageCount":1
  },
  "filters": [],
  "uiPermissions": []
}
```
* **`products`**: In this example, this key contains the actual response content, which may be a single object or an array of objects depending on the operation.

### Additional Data

Each API may include additional data besides the main data object, depending on the business logic of the API. These will be provided in each API’s response signature.

### Error Response

If a request encounters an issue—whether due to a logical fault or a technical problem—the service responds with a standardized JSON error structure. The HTTP status code indicates the nature of the error, using commonly recognized codes for clarity:

* **400 Bad Request**: The request was improperly formatted or contained invalid parameters.
* **401 Unauthorized**: The request lacked a valid authentication token; login is required.
* **403 Forbidden**: The current token does not grant access to the requested resource.
* **404 Not Found**: The requested resource was not found on the server.
* **500 Internal Server Error**: The server encountered an unexpected condition.

Each error response is structured to provide meaningful insight into the problem, assisting in efficient diagnosis and resolution.

```js
{
  "result": "ERR",
  "status": 400,
  "message": "errMsg_organizationIdisNotAValidID",
  "errCode": 400,
  "date": "2024-03-19T12:13:54.124Z",
  "detail": "String"
}
```


## Conversation Data Object

Represents a chat channel between two participants. Types: studentTutor (bidirectional enrolled chat), adminStudent (one-way admin warnings), adminTutor (bidirectional admin-tutor communication).

### Conversation  Data Object Frontend Description By The Backend Architect

## Conversation UX
- Each conversation is a private channel between exactly 2 participants
- For `studentTutor` type: both parties can send messages. Only exists between enrolled student-tutor pairs.
- For `adminStudent` type: admin sends warnings/notices, student can only READ. Hide message input for student, show 'Admin notification channel' banner.
- For `adminTutor` type: both admin and tutor can send and read. Tutor can reply to warnings.
- Conversation list sorted by `lastMessageAt` descending.
- Show unread count badge.
- Warning messages (type=warning) render with amber alert styling.


### Conversation Data Object Properties

Conversation data object has got following properties that are represented as table fields in the database scheme. 
These properties don't stand just for data storage, but each may have different settings to manage the business logic. 

| Property | Type | IsArray | Required | Secret | Description |
|----------|------|---------|----------|--------|-------------|
| `conversationType` | String | false | Yes | No | Channel type: studentTutor, adminStudent, or adminTutor. Determines messaging permissions. |
| `participantA` | ID | false | Yes | No | First participant userId. For studentTutor: the student. For adminStudent/adminTutor: the admin. |
| `participantB` | ID | false | Yes | No | Second participant userId. For studentTutor: the tutor. For adminStudent: the student. For adminTutor: the tutor. |
| `enrollmentId` | ID | false | No | No | FK to enrollment. Only set for studentTutor conversations to link chat to enrollment context. |
| `lastMessageAt` | Date | false | No | No | Timestamp of the most recent message. Used for sorting conversations in inbox. |
| `lastMessagePreview` | String | false | No | No | Truncated preview of last message content. Shown in conversation list. |
| `status` | String | false | Yes | No | Conversation status: active or closed. |
| `participantAName` | String | false | No | No | Cached display name of participant A for quick rendering in conversation list. |
| `participantBName` | String | false | No | No | Cached display name of participant B for quick rendering in conversation list. |
| `courseTitle` | String | false | No | No | Cached course pack title for display. Set on conversation creation for studentTutor type. |
* Required properties are mandatory for creating objects and must be provided in the request body if no default value, formula or session bind is set.



### Enum Properties
Enum properties are defined with a set of allowed values, ensuring that only valid options can be assigned to them. 
The enum options value will be stored as strings in the database, 
but when a data object is created an additional property with the same name plus an idx suffix will be created, which will hold the index of the selected enum option.
You can use the {fieldName_idx} property to sort by the enum value or when your enum options represent a hiyerarchy of values.
In the frontend input components, enum type properties should only accept values from an option component that lists the enum options.

- **conversationType**: [studentTutor, adminStudent, adminTutor]

- **status**: [active, closed]


### Relation Properties

`participantA` `participantB` `enrollmentId`

Mindbricks supports relations between data objects, allowing you to define how objects are linked together.
The relations may reference to a data object either in this service or in another service. Id the reference is remote, backend handles the relations through service communication or elastic search.
These relations should be respected in the frontend so that instaead of showing the related objects id, the frontend should list human readable values from other data objects.
If the relation points to another service, frontend should use the referenced service api in case it needs related data.
The relation logic is montly handled in backend so the api responses feeds the frontend about the relational data. 
In mmost cases the api response will provide the relational data as well as the main one.

In frontend, please ensure that, 

1- instaead of these relational ids you show the main human readable field of the related target data (like name),
2- if this data object needs a user input of these relational ids, you should provide a combobox with the list of possible records or (a searchbox) to select with the realted target data object main human readable field.


- **participantA**: ID
Relation to `user`.id

The target object is a parent object, meaning that the relation is a one-to-many relationship from target to this object.

Required: Yes

- **participantB**: ID
Relation to `user`.id

The target object is a parent object, meaning that the relation is a one-to-many relationship from target to this object.

Required: Yes

- **enrollmentId**: ID
Relation to `enrollment`.id

The target object is a parent object, meaning that the relation is a one-to-many relationship from target to this object.

Required: No



## ChatMessage Data Object

Auto-generated message DataObject for the chat RealtimeHub. Stores all messages with typed content payloads.



### ChatMessage Data Object Properties

ChatMessage data object has got following properties that are represented as table fields in the database scheme. 
These properties don't stand just for data storage, but each may have different settings to manage the business logic. 

| Property | Type | IsArray | Required | Secret | Description |
|----------|------|---------|----------|--------|-------------|
| `roomId` | ID | false | Yes | No | Reference to the room this message belongs to |
| `senderId` | ID | false | No | No | Reference to the user who sent this message |
| `senderName` | String | false | No | No | Display name of the sender (denormalized from user profile at send time) |
| `senderAvatar` | String | false | No | No | Avatar URL of the sender (denormalized from user profile at send time) |
| `messageType` | Enum | false | Yes | No | Content type discriminator for this message |
| `content` | Object | false | Yes | No | Type-specific content payload (structure depends on messageType) |
| `timestamp` |  | false | No | No | Message creation time |
| `status` | Enum | false | No | No | Message moderation status |
| `replyTo` | Object | false | No | No | Reply thread reference { id, preview } |
* Required properties are mandatory for creating objects and must be provided in the request body if no default value, formula or session bind is set.



### Enum Properties
Enum properties are defined with a set of allowed values, ensuring that only valid options can be assigned to them. 
The enum options value will be stored as strings in the database, 
but when a data object is created an additional property with the same name plus an idx suffix will be created, which will hold the index of the selected enum option.
You can use the {fieldName_idx} property to sort by the enum value or when your enum options represent a hiyerarchy of values.
In the frontend input components, enum type properties should only accept values from an option component that lists the enum options.

- **messageType**: [text, image, document, system, warning]

- **status**: [pending, approved, rejected]



### Filter Properties

`roomId` `senderId` `senderName` `senderAvatar` `messageType` `content` `timestamp` `status` `replyTo`

Filter properties are used to define parameters that can be used in query filters, allowing for dynamic data retrieval based on user input or predefined criteria.
These properties are automatically mapped as API parameters in the listing API's.

- **roomId**: ID  has a filter named `roomId`

- **senderId**: ID  has a filter named `senderId`

- **senderName**: String  has a filter named `senderName`

- **senderAvatar**: String  has a filter named `senderAvatar`

- **messageType**: Enum  has a filter named `messageType`

- **content**: Object  has a filter named `content`

- **timestamp**:   has a filter named `timestamp`

- **status**: Enum  has a filter named `status`

- **replyTo**: Object  has a filter named `replyTo`


## ChatModeration Data Object

Auto-generated moderation DataObject for the chat RealtimeHub. Stores block and silence actions for room-level user moderation.



### ChatModeration Data Object Properties

ChatModeration data object has got following properties that are represented as table fields in the database scheme. 
These properties don't stand just for data storage, but each may have different settings to manage the business logic. 

| Property | Type | IsArray | Required | Secret | Description |
|----------|------|---------|----------|--------|-------------|
| `roomId` | ID | false | Yes | No | Reference to the room where the moderation action applies |
| `userId` | ID | false | Yes | No | The user who is blocked or silenced |
| `action` | Enum | false | Yes | No | Moderation action type |
| `reason` | Text | false | No | No | Optional reason for the moderation action |
| `duration` | Integer | false | No | No | Duration in seconds. 0 means permanent |
| `expiresAt` |  | false | No | No | Expiry timestamp. Null means permanent |
| `issuedBy` | ID | false | No | No | The moderator who issued the action |
* Required properties are mandatory for creating objects and must be provided in the request body if no default value, formula or session bind is set.



### Enum Properties
Enum properties are defined with a set of allowed values, ensuring that only valid options can be assigned to them. 
The enum options value will be stored as strings in the database, 
but when a data object is created an additional property with the same name plus an idx suffix will be created, which will hold the index of the selected enum option.
You can use the {fieldName_idx} property to sort by the enum value or when your enum options represent a hiyerarchy of values.
In the frontend input components, enum type properties should only accept values from an option component that lists the enum options.

- **action**: [blocked, silenced]


### Relation Properties

`roomId`

Mindbricks supports relations between data objects, allowing you to define how objects are linked together.
The relations may reference to a data object either in this service or in another service. Id the reference is remote, backend handles the relations through service communication or elastic search.
These relations should be respected in the frontend so that instaead of showing the related objects id, the frontend should list human readable values from other data objects.
If the relation points to another service, frontend should use the referenced service api in case it needs related data.
The relation logic is montly handled in backend so the api responses feeds the frontend about the relational data. 
In mmost cases the api response will provide the relational data as well as the main one.

In frontend, please ensure that, 

1- instaead of these relational ids you show the main human readable field of the related target data (like name),
2- if this data object needs a user input of these relational ids, you should provide a combobox with the list of possible records or (a searchbox) to select with the realted target data object main human readable field.


- **roomId**: ID
Relation to `conversation`.id

The target object is a parent object, meaning that the relation is a one-to-many relationship from target to this object.

Required: Yes


### Filter Properties

`roomId` `userId` `action` `reason` `duration` `expiresAt` `issuedBy`

Filter properties are used to define parameters that can be used in query filters, allowing for dynamic data retrieval based on user input or predefined criteria.
These properties are automatically mapped as API parameters in the listing API's.

- **roomId**: ID  has a filter named `roomId`

- **userId**: ID  has a filter named `userId`

- **action**: Enum  has a filter named `action`

- **reason**: Text  has a filter named `reason`

- **duration**: Integer  has a filter named `duration`

- **expiresAt**:   has a filter named `expiresAt`

- **issuedBy**: ID  has a filter named `issuedBy`



## Default CRUD APIs

For each data object, the backend architect may designate **default APIs** for standard operations (create, update, delete, get, list). These are the APIs that frontend CRUD forms and AI agents should use for basic record management. If no default is explicitly set (`isDefaultApi`), the frontend generator auto-discovers the most general API for each operation.

### Conversation Default APIs

| Operation | API Name | Route | Explicitly Set |
|-----------|----------|-------|----------------|
| Create | `createConversation` | `/v1/conversations` | Yes |
| Update | _none_ | - | Auto |
| Delete | _none_ | - | Auto |
| Get | `getConversation` | `/v1/conversations/:conversationId` | Yes |
| List | `listMyConversations` | `/v1/myconversations` | Yes |
### ChatMessage Default APIs

| Operation | API Name | Route | Explicitly Set |
|-----------|----------|-------|----------------|
| Create | _none_ | - | Auto |
| Update | `updateChatMessage` | `/v1/v1/chat-messages/:id` | Yes |
| Delete | `deleteChatMessage` | `/v1/v1/chat-messages/:id` | Yes |
| Get | `getChatMessage` | `/v1/v1/chat-messages/:id` | Yes |
| List | `listChatMessages` | `/v1/v1/chat-messages` | Yes |
### ChatModeration Default APIs

| Operation | API Name | Route | Explicitly Set |
|-----------|----------|-------|----------------|
| Create | _none_ | - | Auto |
| Update | _none_ | - | Auto |
| Delete | _none_ | - | Auto |
| Get | _none_ | - | Auto |
| List | _none_ | - | Auto |

When building CRUD forms for a data object, use the default create/update APIs listed above. The form fields should correspond to the API's body parameters. For relation fields, render a dropdown loaded from the related object's list API using the display label property.





## API Reference

### `Create Conversation` API
**[Default create API]** — This is the designated default `create` API for the `conversation` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Creates a new conversation between two participants. For studentTutor type, requires valid enrollment. For adminStudent/adminTutor, only admin can create.

**API Frontend Description By The Backend Architect**

## Create Conversation
- Tutors/students can create studentTutor conversations.
- Only admin can create adminStudent or adminTutor conversations.
- Before creating, check if conversation already exists between the two participants of same type.

**Rest Route**

The `createConversation` API REST controller can be triggered via the following route:

`/v1/conversations`


**Rest Request Parameters**


The `createConversation` api has got 9 regular request parameters  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| conversationType  | String  | true | request.body?.["conversationType"] |
| participantA  | ID  | true | request.body?.["participantA"] |
| participantB  | ID  | true | request.body?.["participantB"] |
| enrollmentId  | ID  | false | request.body?.["enrollmentId"] |
| lastMessageAt  | Date  | false | request.body?.["lastMessageAt"] |
| lastMessagePreview  | String  | false | request.body?.["lastMessagePreview"] |
| participantAName  | String  | false | request.body?.["participantAName"] |
| participantBName  | String  | false | request.body?.["participantBName"] |
| courseTitle  | String  | false | request.body?.["courseTitle"] |
**conversationType** : Channel type: studentTutor, adminStudent, or adminTutor. Determines messaging permissions.
**participantA** : First participant userId. For studentTutor: the student. For adminStudent/adminTutor: the admin.
**participantB** : Second participant userId. For studentTutor: the tutor. For adminStudent: the student. For adminTutor: the tutor.
**enrollmentId** : FK to enrollment. Only set for studentTutor conversations to link chat to enrollment context.
**lastMessageAt** : Timestamp of the most recent message. Used for sorting conversations in inbox.
**lastMessagePreview** : Truncated preview of last message content. Shown in conversation list.
**participantAName** : Cached display name of participant A for quick rendering in conversation list.
**participantBName** : Cached display name of participant B for quick rendering in conversation list.
**courseTitle** : Cached course pack title for display. Set on conversation creation for studentTutor type.



**REST Request**
To access the api you can use the **REST** controller with the path **POST  /v1/conversations**
```js
  axios({
    method: 'POST',
    url: '/v1/conversations',
    data: {
            conversationType:"String",  
            participantA:"ID",  
            participantB:"ID",  
            enrollmentId:"ID",  
            lastMessageAt:"Date",  
            lastMessagePreview:"String",  
            participantAName:"String",  
            participantBName:"String",  
            courseTitle:"String",  
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "201",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "conversation",
	"method": "POST",
	"action": "create",
	"appVersion": "Version",
	"rowCount": 1,
	"conversation": {
		"id": "ID",
		"conversationType": "String",
		"conversationType_idx": "Integer",
		"participantA": "ID",
		"participantB": "ID",
		"enrollmentId": "ID",
		"lastMessageAt": "Date",
		"lastMessagePreview": "String",
		"status": "String",
		"status_idx": "Integer",
		"participantAName": "String",
		"participantBName": "String",
		"courseTitle": "String",
		"isActive": true,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID"
	}
}
```


### `Get Conversation` API
**[Default get API]** — This is the designated default `get` API for the `conversation` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Get a single conversation by ID. Only participants or admin can view.


**Rest Route**

The `getConversation` API REST controller can be triggered via the following route:

`/v1/conversations/:conversationId`


**Rest Request Parameters**


The `getConversation` api has got 1 regular request parameter  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| conversationId  | ID  | true | request.params?.["conversationId"] |
**conversationId** : This id paremeter is used to query the required data object.



**REST Request**
To access the api you can use the **REST** controller with the path **GET  /v1/conversations/:conversationId**
```js
  axios({
    method: 'GET',
    url: `/v1/conversations/${conversationId}`,
    data: {
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "conversation",
	"method": "GET",
	"action": "get",
	"appVersion": "Version",
	"rowCount": 1,
	"conversation": {
		"id": "ID",
		"conversationType": "String",
		"conversationType_idx": "Integer",
		"participantA": "ID",
		"participantB": "ID",
		"enrollmentId": "ID",
		"lastMessageAt": "Date",
		"lastMessagePreview": "String",
		"status": "String",
		"status_idx": "Integer",
		"participantAName": "String",
		"participantBName": "String",
		"courseTitle": "String",
		"isActive": true,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID",
		"enrollment": {
			"coursePackId": "ID",
			"studentId": "ID",
			"tutorProfileId": "ID"
		}
	}
}
```


### `List Myconversations` API
**[Default list API]** — This is the designated default `list` API for the `conversation` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Lists all conversations where the current user is a participant. Sorted by lastMessageAt descending.

**API Frontend Description By The Backend Architect**

## Inbox / Conversation List
- Shows all conversations for the logged-in user sorted by most recent.
- Show: other participant name, last message preview, timestamp, unread badge.
- For adminStudent type show 'Admin Notice' label. For adminTutor show 'Admin' label.
- Clicking opens the chat view.

**Rest Route**

The `listMyConversations` API REST controller can be triggered via the following route:

`/v1/myconversations`


**Rest Request Parameters**
The `listMyConversations` api has got no request parameters.    




**REST Request**
To access the api you can use the **REST** controller with the path **GET  /v1/myconversations**
```js
  axios({
    method: 'GET',
    url: '/v1/myconversations',
    data: {
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "conversations",
	"method": "GET",
	"action": "list",
	"appVersion": "Version",
	"rowCount": "\"Number\"",
	"conversations": [
		{
			"id": "ID",
			"conversationType": "String",
			"conversationType_idx": "Integer",
			"participantA": "ID",
			"participantB": "ID",
			"enrollmentId": "ID",
			"lastMessageAt": "Date",
			"lastMessagePreview": "String",
			"status": "String",
			"status_idx": "Integer",
			"participantAName": "String",
			"participantBName": "String",
			"courseTitle": "String",
			"isActive": true,
			"recordVersion": "Integer",
			"createdAt": "Date",
			"updatedAt": "Date",
			"_owner": "ID",
			"enrollment": [
				{
					"coursePackId": "ID",
					"studentId": "ID",
					"tutorProfileId": "ID"
				},
				{},
				{}
			]
		},
		{},
		{}
	],
	"paging": {
		"pageNumber": "Number",
		"pageRowCount": "NUmber",
		"totalRowCount": "Number",
		"pageCount": "Number"
	},
	"filters": [],
	"uiPermissions": []
}
```


### `Send Systemmessage` API
Interservice API called by adminPanel for moderation warnings. Creates/finds admin conversation with target user and sends a warning message. M2M only.

**API Frontend Description By The Backend Architect**

This API is not called from frontend. It is an interservice endpoint for adminPanel to deliver moderation warnings as chat messages.

**Rest Route**

The `sendSystemMessage` API REST controller can be triggered via the following route:

`/v1/sendsystemmessage`


**Rest Request Parameters**


The `sendSystemMessage` api has got 6 regular request parameters  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| targetUserId  | ID  | true | request.body?.["targetUserId"] |
| targetUserRole  | String  | true | request.body?.["targetUserRole"] |
| messageContent  | Text  | true | request.body?.["messageContent"] |
| resolutionType  | String  | false | request.body?.["resolutionType"] |
| complaintId  | ID  | false | request.body?.["complaintId"] |
| severity  | String  | false | request.body?.["severity"] |
**targetUserId** : The userId of the user to send the warning to
**targetUserRole** : Role of target: student or tutor. Determines conversation type
**messageContent** : The warning message content
**resolutionType** : Moderation resolution type: warn, requireEdit, removeCourse, suspend, ban
**complaintId** : Reference to original complaint/issue ID
**severity** : Warning severity: info, warning, critical



**REST Request**
To access the api you can use the **REST** controller with the path **POST  /v1/sendsystemmessage**
```js
  axios({
    method: 'POST',
    url: '/v1/sendsystemmessage',
    data: {
            targetUserId:"ID",  
            targetUserRole:"String",  
            messageContent:"Text",  
            resolutionType:"String",  
            complaintId:"ID",  
            severity:"String",  
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "201",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "conversation",
	"method": "POST",
	"action": "create",
	"appVersion": "Version",
	"rowCount": 1,
	"conversation": {
		"id": "ID",
		"conversationType": "String",
		"conversationType_idx": "Integer",
		"participantA": "ID",
		"participantB": "ID",
		"enrollmentId": "ID",
		"lastMessageAt": "Date",
		"lastMessagePreview": "String",
		"status": "String",
		"status_idx": "Integer",
		"participantAName": "String",
		"participantBName": "String",
		"courseTitle": "String",
		"isActive": true,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID"
	}
}
```


### `List Chatmessages` API
**[Default list API]** — This is the designated default `list` API for the `chatMessage` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
List messages in a chat hub room. Accessible by admins and room participants.


**Rest Route**

The `listChatMessages` API REST controller can be triggered via the following route:

`/v1/v1/chat-messages`


**Rest Request Parameters**



**Filter Parameters**

The `listChatMessages` api supports 9 optional filter parameters for filtering list results:

**roomId** (`ID`): Reference to the room this message belongs to

- Single: `?roomId=<value>`
- Multiple: `?roomId=<value1>&roomId=<value2>`
- Null: `?roomId=null`


**senderId** (`ID`): Reference to the user who sent this message

- Single: `?senderId=<value>`
- Multiple: `?senderId=<value1>&senderId=<value2>`
- Null: `?senderId=null`


**senderName** (`String`): Display name of the sender (denormalized from user profile at send time)

- Single (partial match, case-insensitive): `?senderName=<value>`
- Multiple: `?senderName=<value1>&senderName=<value2>`
- Null: `?senderName=null`


**senderAvatar** (`String`): Avatar URL of the sender (denormalized from user profile at send time)

- Single (partial match, case-insensitive): `?senderAvatar=<value>`
- Multiple: `?senderAvatar=<value1>&senderAvatar=<value2>`
- Null: `?senderAvatar=null`


**messageType** (`Enum`): Content type discriminator for this message

- Single: `?messageType=<value>` (case-insensitive)
- Multiple: `?messageType=<value1>&messageType=<value2>`
- Null: `?messageType=null`


**content** (`Object`): Type-specific content payload (structure depends on messageType)

- Single: `?content=<value>`
- Multiple: `?content=<value1>&content=<value2>`
- Null: `?content=null`

**timestamp** (`String`): Message creation time

- Single (partial match, case-insensitive): `?timestamp=<value>`
- Multiple: `?timestamp=<value1>&timestamp=<value2>`
- Null: `?timestamp=null`


**status** (`Enum`): Message moderation status

- Single: `?status=<value>` (case-insensitive)
- Multiple: `?status=<value1>&status=<value2>`
- Null: `?status=null`


**replyTo** (`Object`): Reply thread reference { id, preview }

- Single: `?replyTo=<value>`
- Multiple: `?replyTo=<value1>&replyTo=<value2>`
- Null: `?replyTo=null`


**REST Request**
To access the api you can use the **REST** controller with the path **GET  /v1/v1/chat-messages**
```js
  axios({
    method: 'GET',
    url: '/v1/v1/chat-messages',
    data: {
    
    },
    params: {
    
        // Filter parameters (see Filter Parameters section above)
        // roomId: '<value>' // Filter by roomId
        // senderId: '<value>' // Filter by senderId
        // senderName: '<value>' // Filter by senderName
        // senderAvatar: '<value>' // Filter by senderAvatar
        // messageType: '<value>' // Filter by messageType
        // content: '<value>' // Filter by content
        // timestamp: '<value>' // Filter by timestamp
        // status: '<value>' // Filter by status
        // replyTo: '<value>' // Filter by replyTo
            }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "chatMessages",
	"method": "GET",
	"action": "list",
	"appVersion": "Version",
	"rowCount": "\"Number\"",
	"chatMessages": [
		{
			"id": "ID",
			"roomId": "ID",
			"senderId": "ID",
			"senderName": "String",
			"senderAvatar": "String",
			"messageType": "Enum",
			"messageType_idx": "Integer",
			"content": "Object",
			"timestamp": null,
			"status": "Enum",
			"status_idx": "Integer",
			"replyTo": "Object",
			"isActive": true,
			"recordVersion": "Integer",
			"createdAt": "Date",
			"updatedAt": "Date",
			"_owner": "ID"
		},
		{},
		{}
	],
	"paging": {
		"pageNumber": "Number",
		"pageRowCount": "NUmber",
		"totalRowCount": "Number",
		"pageCount": "Number"
	},
	"filters": [],
	"uiPermissions": []
}
```


### `Get Chatmessage` API
**[Default get API]** — This is the designated default `get` API for the `chatMessage` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Get a single chat hub message by ID.


**Rest Route**

The `getChatMessage` API REST controller can be triggered via the following route:

`/v1/v1/chat-messages/:id`


**Rest Request Parameters**


The `getChatMessage` api has got 2 regular request parameters  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| chatMessageId  | ID  | true | request.params?.["chatMessageId"] |
| id  | String  | true | request.params?.["id"] |
**chatMessageId** : This id paremeter is used to query the required data object.
**id** : This parameter will be used to select the data object that is queried



**REST Request**
To access the api you can use the **REST** controller with the path **GET  /v1/v1/chat-messages/:id**
```js
  axios({
    method: 'GET',
    url: `/v1/v1/chat-messages/${id}`,
    data: {
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "chatMessage",
	"method": "GET",
	"action": "get",
	"appVersion": "Version",
	"rowCount": 1,
	"chatMessage": {
		"id": "ID",
		"roomId": "ID",
		"senderId": "ID",
		"senderName": "String",
		"senderAvatar": "String",
		"messageType": "Enum",
		"messageType_idx": "Integer",
		"content": "Object",
		"timestamp": null,
		"status": "Enum",
		"status_idx": "Integer",
		"replyTo": "Object",
		"isActive": true,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID"
	}
}
```


### `Delete Chatmessage` API
**[Default delete API]** — This is the designated default `delete` API for the `chatMessage` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Delete a chat hub message. Admins can delete any message; users can delete their own.


**Rest Route**

The `deleteChatMessage` API REST controller can be triggered via the following route:

`/v1/v1/chat-messages/:id`


**Rest Request Parameters**


The `deleteChatMessage` api has got 2 regular request parameters  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| chatMessageId  | ID  | true | request.params?.["chatMessageId"] |
| id  | String  | true | request.params?.["id"] |
**chatMessageId** : This id paremeter is used to select the required data object that will be deleted
**id** : This parameter will be used to select the data object that want to be deleted



**REST Request**
To access the api you can use the **REST** controller with the path **DELETE  /v1/v1/chat-messages/:id**
```js
  axios({
    method: 'DELETE',
    url: `/v1/v1/chat-messages/${id}`,
    data: {
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "chatMessage",
	"method": "DELETE",
	"action": "delete",
	"appVersion": "Version",
	"rowCount": 1,
	"chatMessage": {
		"id": "ID",
		"roomId": "ID",
		"senderId": "ID",
		"senderName": "String",
		"senderAvatar": "String",
		"messageType": "Enum",
		"messageType_idx": "Integer",
		"content": "Object",
		"timestamp": null,
		"status": "Enum",
		"status_idx": "Integer",
		"replyTo": "Object",
		"isActive": false,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID"
	}
}
```


### `Update Chatmessage` API
**[Default update API]** — This is the designated default `update` API for the `chatMessage` data object. Frontend generators and AI agents should use this API for standard CRUD operations.
Update a chat hub message content. Only the message sender or admins can edit.


**Rest Route**

The `updateChatMessage` API REST controller can be triggered via the following route:

`/v1/v1/chat-messages/:id`


**Rest Request Parameters**


The `updateChatMessage` api has got 4 regular request parameters  

| Parameter              | Type                   | Required | Population                   |
| ---------------------- | ---------------------- | -------- | ---------------------------- |
| chatMessageId  | ID  | true | request.params?.["chatMessageId"] |
| content  | Object  | false | request.body?.["content"] |
| status  | Enum  | false | request.body?.["status"] |
| id  | String  | true | request.params?.["id"] |
**chatMessageId** : This id paremeter is used to select the required data object that will be updated
**content** : Type-specific content payload (structure depends on messageType)
**status** : Message moderation status
**id** : This parameter will be used to select the data object that want to be updated



**REST Request**
To access the api you can use the **REST** controller with the path **PATCH  /v1/v1/chat-messages/:id**
```js
  axios({
    method: 'PATCH',
    url: `/v1/v1/chat-messages/${id}`,
    data: {
            content:"Object",  
            status:"Enum",  
    
    },
    params: {
    
        }
  });
```   
**REST Response**


```json
{
	"status": "OK",
	"statusCode": "200",
	"elapsedMs": 126,
	"ssoTime": 120,
	"source": "db",
	"cacheKey": "hexCode",
	"userId": "ID",
	"sessionId": "ID",
	"requestId": "ID",
	"dataName": "chatMessage",
	"method": "PATCH",
	"action": "update",
	"appVersion": "Version",
	"rowCount": 1,
	"chatMessage": {
		"id": "ID",
		"roomId": "ID",
		"senderId": "ID",
		"senderName": "String",
		"senderAvatar": "String",
		"messageType": "Enum",
		"messageType_idx": "Integer",
		"content": "Object",
		"timestamp": null,
		"status": "Enum",
		"status_idx": "Integer",
		"replyTo": "Object",
		"isActive": true,
		"recordVersion": "Integer",
		"createdAt": "Date",
		"updatedAt": "Date",
		"_owner": "ID"
	}
}
```



**After this prompt, the user may give you new instructions to update the output of this prompt or provide subsequent prompts about the project.**


