Data Models
Relevant source files
The following files were used as context for generating this wiki page:
The data models are the structural foundation of the MessageJS system, defining the entities, their attributes, and the relationships between them. They are formally specified using the Prisma ORM schema, which serves as the single source of truth for the PostgreSQL database structure. These database models are then mirrored as TypeScript interfaces within the @messagejs/core package to ensure type safety and consistency throughout the application logic.
This document outlines the core database models as defined in the Prisma schema, the corresponding TypeScript types used in the application, and the enumerations that enforce data integrity for specific fields. The models are designed to be relational, with clear connections between users, their projects, and the messaging resources they manage.
Database Schema Overview
The core data models are defined in packages/core/prisma/schema.prisma. This schema is used to generate the Prisma Client for database access and to create SQL migration files. The primary entities are User, Project, Service (representing a connector), Template, and MessageLog.
The following Entity-Relationship diagram illustrates the relationships between these core models.
Sources: packages/core/prisma/schema.prisma
User
The User model represents a developer account in the MessageJS system. Each user can own multiple projects.
| Field | Type | Constraints | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the user. |
email | String | @unique | The user's unique email address. |
passwordHash | String | The hashed password for authentication. | |
createdAt | DateTime | @default(now()) | Timestamp of when the user was created. |
projects | Project[] | Relation to the projects owned by the user. |
Sources: packages/core/prisma/schema.prisma:30-36
Project
A Project is a container for all resources related to a specific application, including connectors, templates, and message logs. Each project has a unique API key for authenticating SDK requests.
| Field | Type | Constraints | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the project. |
name | String | The name of the project. | |
apiKey | String | @unique | The unique API key for the project. |
createdAt | DateTime | @default(now()) | Timestamp of when the project was created. |
userId | String | Foreign key linking to the User who owns the project. | |
user | User | @relation | Relation to the parent User model. |
services | Service[] | Relation to the services (connectors) in the project. | |
templates | Template[] | Relation to the templates in the project. | |
messageLogs | MessageLog[] | Relation to the message logs in the project. |
Sources: packages/core/prisma/schema.prisma:38-50
Service (Connector)
The Service model represents a configured third-party messaging provider, such as WhatsApp or Twilio. Credentials for the service are encrypted and stored.
| Field | Type | Constraints | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the service. |
type | ServiceType | The type of messaging service (e.g., WHATSAPP). | |
credentials | String | AES-256 encrypted credentials blob. | |
createdAt | DateTime | @default(now()) | Timestamp of when the service was created. |
projectId | String | Foreign key linking to the parent Project. | |
project | Project | @relation | Relation to the parent Project model. |
messageLogs | MessageLog[] | Relation to messages sent via this service. |
Sources: packages/core/prisma/schema.prisma:52-62
Template
The Template model stores a reusable message format. Templates can contain variables (e.g., {{code}}) that are replaced with dynamic data when a message is sent.
| Field | Type | Constraints | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the template. |
name | String | The user-defined name for the template. | |
body | String | The template content with placeholders. | |
createdAt | DateTime | @default(now()) | Timestamp of when the template was created. |
projectId | String | Foreign key linking to the parent Project. | |
project | Project | @relation | Relation to the parent Project model. |
Sources: packages/core/prisma/schema.prisma:64-72
MessageLog
The MessageLog model tracks every message sent through the system, including its status, recipient, and any errors.
| Field | Type | Constraints | Description |
|---|---|---|---|
id | String | @id @default(cuid()) | Unique identifier for the message log. |
status | MessageStatus | @default(QUEUED) | The current delivery status of the message. |
recipient | String | The recipient's identifier (e.g., phone number). | |
externalMessageId | String? | The unique ID from the third-party provider. | |
error | String? | Stores an error message if the status is FAILED. | |
timestamp | DateTime | @default(now()) | Timestamp of when the log was created. |
projectId | String | Foreign key linking to the parent Project. | |
serviceId | String | Foreign key linking to the Service used. |
Sources: packages/core/prisma/schema.prisma:74-88
TypeScript Interfaces
The file packages/core/src/types/dataModels.ts defines TypeScript interfaces that correspond to the Prisma data models. These interfaces are used throughout the backend application code for type safety. While largely a 1:1 mapping, some fields are named differently or added for application-level logic (e.g., passwordHash vs password).
The diagram below shows the primary TypeScript interfaces and their properties.
API Data Transfer Objects (DTOs)
For API communication, specialized types are defined in packages/core/src/types/apiTypes.ts. These types model the request and response bodies for API endpoints and are often subsets or compositions of the core data models.
For example, the SendMessageRequest is used for the POST /api/v1/messages endpoint and contains the necessary identifiers to create a MessageLog.
// packages/core/src/types/apiTypes.ts:31-38
export interface SendMessageRequest {
connectorId: string;
templateId: string;
to: string;
variables: Record<string, any>;
metadata?: Record<string, any>;
}
Sources: packages/core/src/types/apiTypes.ts:31-38
The following sequence diagram shows how a SendMessageRequest from the client SDK results in the creation of a MessageLog entry in the database.
Enumerations
The schema defines enumerations to constrain the values of certain fields, ensuring data consistency. These are defined in schema.prisma and mirrored as union types in TypeScript.
ServiceType
Defines the supported third-party messaging providers.
| Value | Description |
|---|---|
WHATSAPP | WhatsApp Cloud API |
TELEGRAM | Telegram Bot API |
TWILIO_SMS | Twilio SMS API |
Sources: packages/core/prisma/schema.prisma:17-21, packages/core/prisma/migrations/20251029214807_init/migration.sql:2-3
MessageStatus
Defines the lifecycle of a message as it is processed by the system.
| Value | Description |
|---|---|
QUEUED | The message has been accepted by the API but not yet sent. |
SENT | The message has been successfully sent to the third-party provider. |
DELIVERED | Confirmation of delivery has been received. |
FAILED | The message failed to send or was rejected by the provider. |
UNDELIVERED | The provider confirmed the message could not be delivered. |
Sources: packages/core/prisma/schema.prisma:23-28, packages/core/prisma/migrations/20251029214807_init/migration.sql:5-6
Conclusion
The data models of MessageJS provide a robust and scalable structure for managing users, projects, and messaging operations. By centralizing the schema definition in Prisma, the project ensures a single source of truth that generates both the database structure and the type-safe client used within the application. The clear relationships and use of enumerations enforce data integrity, while the corresponding TypeScript interfaces provide a developer-friendly way to interact with these models throughout the backend services.