TalkBox persists all application data in MongoDB through two Mongoose schemas:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/abdelhafid37/talkbox/llms.txt
Use this file to discover all available pages before exploring further.
User and Message. Mongoose provides schema-level validation, type coercion, and the populate helper that resolves ObjectId references into embedded subdocuments — a pattern TalkBox uses heavily when returning conversation history. Both schemas enable the timestamps option, so every document automatically carries createdAt and updatedAt fields managed by Mongoose.
User model
TheUser schema represents a registered account. It stores the minimal information needed to authenticate a user and display their identity to other participants in the chat.
Fields
The user’s public display name, shown in the chat sidebar and on message bubbles. Leading and trailing whitespace is stripped by the
trim option before the value is saved. Enforced as unique at the MongoDB index level — attempting to register a duplicate username returns a validation error.The user’s email address, used as the login credential alongside their password. Leading and trailing whitespace is stripped by
trim before the value is saved. Enforced as unique at the MongoDB index level — duplicate email registrations are rejected before they reach the database.The user’s hashed password. The plain-text password submitted during registration is never stored; the auth controller passes it through
bcrypt.hash() before calling User.create(). During login, bcrypt.compare() validates the submitted password against this stored hash. This field is never included in API responses — the /api/users endpoints return only _id, username, and email.Automatically set by Mongoose when the document is first created (
timestamps: true). Not explicitly defined in the schema.Automatically updated by Mongoose on every save. Not explicitly defined in the schema.
The
password field is intentionally omitted from all user-facing query results. Controllers that return user data use Mongoose’s select("-password") projection to strip it before sending the response.Message model
TheMessage schema represents a single chat message exchanged between two users. References to User documents are stored as MongoDB ObjectIds rather than embedded subdocuments, keeping the messages collection compact.
Fields
The MongoDB
_id of the user who sent the message. Stored as a reference so that the User document can be joined via Mongoose populate. When conversation history is returned by the API or emitted over the socket, sender is populated to include username only (select: "username").The MongoDB
_id of the user who is the intended recipient. Stored and populated in the same way as sender. The getConversation query uses both sender and receiver fields together to filter all messages exchanged between a specific pair of users, regardless of direction.The text body of the message. Leading and trailing whitespace is stripped by
trim before the value is persisted. There is currently no maximum-length constraint defined in the schema.Automatically set by Mongoose when the message is first created. The chat UI uses this timestamp (formatted with
date-fns) to display the send time on each message bubble.Automatically maintained by Mongoose. Messages are not edited in the current version of TalkBox, so this value equals
createdAt in practice.Relationships
Messages and users are linked by MongoDB ObjectId references, following the standard Mongooseref / populate pattern. Two key relationships exist:
Message.sender → User— every message knows which user sent it.Message.receiver → User— every message knows which user should receive it.
sendMessage socket event, populate is called immediately on the new document before it is emitted to both parties, so the client never needs to make a secondary request to resolve usernames:
getConversation controller queries for messages where the pair appears in either direction and populates both reference fields using the same projection.
Indexes and uniqueness
MongoDB unique indexes are declared directly on theUser schema via Mongoose’s unique: true shorthand. Mongoose creates these indexes automatically on first connection when they do not already exist:
| Collection | Field | Index type |
|---|---|---|
users | username | Unique |
users | email | Unique |
messages collection in the current schema. For production deployments handling large conversation histories, a compound index on { sender: 1, receiver: 1, createdAt: -1 } would significantly improve the performance of the getConversation query.