ChatPRT is a real-time AI chat application powered by OpenAI's GPT-3.5. It allows users to create an account, securely sign in, start new conversations, interact with ChatGPT, view and delete conversation history, and seamlessly resume previous conversations from where they left off.
This project integrates with the OpenAI Platform, enabling the application to leverage OpenAI's artificial intelligence models and provide real-time conversational experiences.
- License
- Technologies
- Getting Started
- Demo
- API Routes & Authentication
- Testing
- Database
- Infrastructure
This project is licensed under the MIT License.
- ReactJS: An open-source JavaScript library for building user interfaces (UI). Developed by Meta, React is based on reusable components, enabling the creation of dynamic and interactive applications efficiently.
- TypeScript: A superset of JavaScript that adds optional static typing. It helps developers catch errors earlier in the development process while improving code maintainability and scalability.
- Styled Components: A library for React and React Native that enables writing CSS directly within JavaScript components. It provides features such as dynamic props and scoped styling, making styles easier to manage.
- Axios: A promise-based HTTP client for browsers and Node.js. It offers a simple API for making HTTP requests and supports features such as interceptors, request cancellation, and data transformation.
- Vite: A fast and modern frontend build tool that provides an extremely efficient development experience with instant server startup, Hot Module Replacement (HMR), and optimized production builds.
- React Icons: A library that provides a collection of popular icon packs for React applications, making it easy to include scalable vector icons in your UI.
- React Spinners: A React library that provides customizable loading spinner components for displaying loading states in web applications.
- React Query: A powerful library for managing asynchronous server state in React applications, including data fetching, caching, synchronization, and background updates.
- Node.js: A JavaScript runtime used to build the server-side environment of the application.
- NestJS: A progressive Node.js framework used to build scalable and maintainable backend APIs.
- TypeORM: An Object-Relational Mapping (ORM) library for TypeScript and JavaScript that simplifies working with relational databases.
- MySQL: A relational database management system used to store the application's data.
- Bcrypt: A library used for securely hashing user passwords before storing them in the database.
- JSON Web Token (JWT): A library used to implement secure authentication through JSON Web Tokens.
- Dotenv: A module that loads environment variables from a
.envfile into the Node.js runtime. - CORS: Express middleware that enables Cross-Origin Resource Sharing (CORS) for HTTP requests.
- HTTP Status Codes: A package that provides named constants for HTTP status codes.
- Jest: A JavaScript testing framework focused on simplicity and reliability.
- Supertest: A library for testing HTTP APIs through automated integration tests.
- UUIDv4: A package for generating version 4 Universally Unique Identifiers (UUIDs).
- Docker: A platform for defining and running multi-container applications, simplifying development, deployment, and environment consistency.
- Swagger: A framework for documenting REST APIs, providing an interactive interface to explore and test endpoints.
- OpenAI: The official library used to integrate OpenAI's AI models into the application.
- Terraform: An Infrastructure as Code (IaC) tool used to provision and manage cloud infrastructure declaratively, ensuring consistency and automation.
- Google Cloud Platform (GCP): Google's cloud computing platform, providing scalable infrastructure and managed services for deploying and hosting applications.
Before running the project, make sure you have the following installed on your machine:
Git
Docker
Clone the repository using the following command:
git clone git@github.com:danielbped/ChatPRT.gitNavigate to the project directory:
cd ChatPRTTo run the application correctly, a few environment variables need to be configured.
At the root of the project, rename the .env.example file to .env. This file already contains all the required variables to initialize the database.
Inside the Backend directory, create a .env file with the following configuration:
MYSQL_DB_USER=root
MYSQL_DB_NAME=chat-prt
MYSQL_DB_HOST=localhost
MYSQL_DB_PASSWORD=password
MYSQL_DB_ROOT_PASSWORD=password
MYSQL_DB_PORT=3306
SECRET_KEY_JWT=chat-prt
OPENAI_API_URL=https://api.openai.com/v1/chat/completions
OPENAI_PROJECT=
OPENAI_ORGANIZATION=
OPENAI_MODEL=An example configuration file (.env.example) is already included in the project. Simply rename it to .env to use the default database configuration.
If you prefer to use a local MySQL instance instead of the Docker container, update the database variables with your local credentials.
To enable the OpenAI integration, you'll need an OpenAI account with an active project. Fill in the following environment variables:
OPENAI_PROJECT: Your OpenAI project ID.OPENAI_ORGANIZATION: Your OpenAI organization ID.OPENAI_MODEL: The model you want to use.
This project was originally built using gpt-3.5-turbo, but any supported chat model can be configured depending on your OpenAI account.
For more information on how to obtain these credentials, refer to the OpenAI Production Best Practices.
With the environment variables properly configured, simply run the following Docker command to build and start the application:
docker-compose up -d --build
If everything has been configured correctly, the following message will be displayed in the terminal:
[+] Running 5/5
Network chatprt_backend_network Created
Network chatprt_frontend_network Created
Container chatprt-chatprt-db-1 Started
Container chatprt-chatprt-backend-1 Started
Container chatprt-chatprt-frontend-1 Started
Now, you can access the application at:
http://localhost:8000to use the application interface.http://localhost:3000/docsto view the available API routes.
To stop the application and shut down the Docker containers, run the following command:
docker-compose down
Prisma icons created by Freepik - Flaticon
- Status 200 (OK)
- Description: The application is healthy and running properly.
- Status 500 (Internal Server Error)
- Description: The application is not working correctly.
Requests related to users (POST /user and POST /login) have a similar behavior. Both endpoints will return the authenticated user and an access token.
This token is required for all other routes and must be provided through the Authorization parameter in the request headers, using the following format: Bearer token. For example, if the token is: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ, the Authorization header should have the following value: Bearer yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ.
| Parameter | Type | Description | Example |
|---|---|---|---|
firstName |
String | User's first name | "Douglas" |
lastName |
String | User's last name | "Adams" |
email |
String | User's email address | "douglasadams@email.com" |
password |
String | User's password | "s3nh4_f0rt3" |
-
Status 201 (Created)
- Description: User successfully created.
-
{ "token": "yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ", "user": { "firstName": "Douglas", "lastName": "Adams", "email": "douglasadams@email.com", "id": "123456789", "createdAt": "2024-05-02T12:00:00Z", "updatedAt": "2024-05-02T12:00:00Z" } }
-
Status 400 (Bad Request)
- Description: Invalid data provided.
-
Status 500 (Internal Server Error)
- Description: Internal system error.
| Parameter | Type | Description | Example |
|---|---|---|---|
email |
String | User's email address | "douglasadams@email.com" |
password |
String | User's password | "s3nh4_f0rt3" |
-
Status 200 (OK)
- Description: Login successfully completed.
-
{ "token": "yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ", "user": { "firstName": "Douglas", "lastName": "Adams", "email": "douglasadams@email.com", "id": "123456789", "createdAt": "2024-05-02T12:00:00Z", "updatedAt": "2024-05-02T12:00:00Z" } }
-
Status 401 (Unauthorized)
- Description: Invalid credentials.
-
Status 500 (Internal Server Error)
- Description: Internal system error.
| Parameter | Type | Description | Example |
|---|---|---|---|
content |
String | Message content to be sent | "What is the answer to life, the universe, and everything?" |
conversation |
Object | Conversation where the message is inserted | See the example below |
Example of the conversation object:
{
"id": "123456789",
"messages": [],
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z",
"user": {
"id": "42",
"firstName": "Douglas",
"lastName": "Adams",
"email": "douglasadams@example.com",
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z"
}
}- Status 201 (Created)
- Description: Message successfully created.
{
"content": "What is the answer to life, the universe, and everything?",
"response": "42",
"conversation": {
"id": "123456789",
"messages": [],
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z",
"user": {
"id": "42",
"firstName": "Douglas",
"lastName": "Adams",
"email": "douglasadams@example.com",
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z"
}
},
"id": "123456789",
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z"
}
- Status 401 (Unauthorized)
- Description: User is not authorized.
- Status 400 (Bad Request)
- Description: Invalid data provided.
- Status 500 (Internal Server Error)
- Description: Internal system error.
| Parameter | Type | Description | Example |
|---|---|---|---|
id |
String | User ID | "42" |
-
Status 200 (OK)
-
Description: Request successfully completed.
-
[ { "id": "123456789", "user": { "id": "42", "firstName": "Douglas", "lastName": "Adams", "email": "douglasadams@example.com" }, "messages": [], "createdAt": "2024-05-02T12:00:00Z", "updatedAt": "2024-05-02T12:00:00Z" } ]
-
-
Status 401 (Unauthorized)
- Description: User is not authorized.
-
Status 404 (Not Found)
- Description: User not found.
-
Status 400 (Bad Request)
- Description: Invalid data provided.
| Parameter | Type | Description | Example |
|---|---|---|---|
user |
Object | User participating in the conversation | See the example below |
Example of the user object:
{
"id": "42",
"firstName": "Douglas",
"lastName": "Adams",
"email": "douglasadams@example.com",
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z"
}- Status 201 (Created)
- Description: Conversation successfully created.
{
"id": "123456789",
"user": {
"id": "42",
"firstName": "Douglas",
"lastName": "Adams",
"email": "douglasadams@example.com",
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z"
},
"createdAt": "2024-05-02T12:00:00Z",
"updatedAt": "2024-05-02T12:00:00Z",
"messages": []
}- Status 401 (Unauthorized)
- Description: User is not authorized.
- Status 400 (Bad Request)
- Description: Invalid data provided.
| Parameter | Type | Description | Example |
|---|---|---|---|
id |
String | Conversation ID | "123456789" |
-
Status 200 (OK)
- Description: Conversation successfully deleted.
-
Status 401 (Unauthorized)
- Description: User is not authorized.
-
Status 404 (Not Found)
- Description: Conversation not found.
-
Status 400 (Bad Request)
- Description: Invalid data provided.
When running the application, you can view all available routes, including their respective request bodies and parameters.
Simply navigate to http://localhost:3000/docs, where an exclusive API documentation page is available, built using Swagger.
The application includes unit tests for all routes and middlewares, as well as End-to-End (E2E) tests covering all routes.
To run the tests, execute the following command inside the /Backend directory:
npm run test
The database was developed using MySQL, with the support of the TypeORM ORM for migrations and queries.
The database architecture consists of three tables (User, Message, and Conversation), and their columns can be seen below:
| Column | Type |
|---|---|
id |
String |
firstName |
String |
lastName |
String |
email |
String |
password |
String |
createdAt |
Date |
updatedAt |
Date |
| Column | Type |
|---|---|
id |
String |
conversation |
Conversation |
content |
String |
response |
String |
createdAt |
Date |
updatedAt |
Date |
| Column | Type |
|---|---|
id |
String |
user |
User |
messages |
Message[] |
createdAt |
Date |
updatedAt |
Date |
To improve the delivery process and enable continuous integration, two workflow scripts were developed to run at specific stages of the development process. Both workflows are available in the .github folder.
This script is responsible for updating the application images on Docker Hub whenever a push is made to the master branch.
This script is responsible for validating the application's integrity and running all automated tests whenever a new Pull Request is opened.
The Terraform configuration is available in the Terraform folder. Inside the main file, you can find the complete deployment configuration for the application's Docker images, which are deployed on Cloud Run. It also includes the configuration for the MySQL database instance hosted on Cloud SQL.





