Trello-like API is an API for collaborative project management inspired by Trello. It is built using Node.js, Express.js, PostgreSQL, JWT authentication, Redis for caching, Sequelize ORM, BullMQ, and Docker and testing with Jest + Supertest. The project follows Clean Architecture, and Domain-Driven Design (DDD) to ensure maintainability and scalability. It features authentication management, roles, teams, tasks, attachments, and more.
- β Authentication with JWT (access/refresh tokens)
- β Emails are sent to verify the authenticity of the user and to be able to change the password or activate the account.
- β
Roles per subscription plan:
basic
,premium
- β Collaborative project management and organization through roles using workspaces, projects, and teams, each with its own members
- β
User roles by context belonging to workspaces, projects or teams:
owner
,admin
,member
- β You can organize your project using lists and cards. If you wish, you can organize the tasks on each card using labels, checklists, adding attachments like images, assigning members to the card or to the checklist items.
- β Clean Architecture + DDD
- β
Full CRUD:
- Users (with recursive deletion)
- Workspaces, Projects, and Teams
- Lists, Cards, labels, attachments, checklists and checklist Items
- Members in: Workspaces, projects, teams, card members and chekcklist items
- β Assigning/de-assigning equipment to projects
- β Securely upload files and images with Cloudinary
- β Secure download via proxy endpoint with streams
- β Message queues with BullMQ for sending emails and uploading files
- β Authorization middlewares to manage permissions and roles
- β Validation with Joi
The project includes an automated task using node-cron
that runs every day at midnight (00:00
). This scheduled job checks for users who haven't verified their email within 7 days of account creation and removes them from the system. This helps keep the database clean and free of inactive accounts.
- JWT Authentication with refresh tokens managed from Redis and cookies.
- Subscription plans:
basic
: Creation and limited membership of workspaces, projects, and teamspremium
: Limited but expanded ability to create and join workspaces, projects, and teams.
- Hierarchical roles by entity (
workspace
,project
,team
):owner
: Full control, including ownership transferadmin
: manage membersmember
: You can only contribute to the project with lists, cards, and information within each card, but you cannot manage members or update the project.
- Node.js - Backend runtime
- Express.js - Web framework
- PostgreSQL - Database
- Sequelize ORM - Object-Relational Mapping
- Redis - Caching system
- JWT Authentication - Secure authentication(Access/Refresh tokens)
- Docker - Containerized environment
- Winston & Morgan - Logging and performance monitoring
- Nodemailer - Email service
- Joi - Data validation
- Express-rate-limit - Rate limiting middleware
- BullMQ - Task queue for sending emails and uploading files in the background
- Cloudinary - Host files and images for free
- Swagger - API documentation
- PM2 - Management of production processes
- Jest - Testing framework
- Supetest - Node.js library for testing APIs
- π¦ Features
- Technologies Used
- Project Structure
- π§ͺ Testing
- How to Run the Project
- Available Scripts
- ER schema of the database
- Project Status
- π€ API Example Requests & Responses
- User Testing Flow (via Swagger UI)
- Documentation API
- Developer
- License
The project follows Clean Architecture and Domain-Driven Design (DDD) principles. The api/src/
and tests/
directory is structured as follows:
api/src/
βββ application/
β βββ dtos/
β βββ services/
β βββ use-cases/
βββ domain/
β βββ repositories/ (contracts)
β βββ entities/
β βββ value-objects/
βββ infrastructure/
β βββ adapters/
| βββ queues/
β βββ repositories/ (implementations)
β βββ store/ (DB, ORM, cache configuration)
βββ interfaces/
β βββ controllers/
β βββ middlewares/
β βββ routes/
β βββ schemas/
βββ config/ (environment variables)
βββ utils/ (helpers)
/tests/
βββ unit/
β βββ [Entidad]/
β βββ [UseCaseName].test.js # Ej: user/DeleteAccountUseCase.test.js
β
βββ e2e/
β βββ [Entidad].e2e.js # Ej: users.e2e.js β all user endpoints
β
βββ setupTest.js # Global mocks: Cloudinary, Nodemailer, etc.
This project includes comprehensive automated testing using Jest:
β Current test coverage:
- Statements: 84.39%
- Branches: 59.34%
- Functions: 83.94%
- Lines: 86.85%
This coverage is based on end-to-end testing, ensuring that real user flows and API behavior are validated. Unit testing was also applied to core use cases.
-
Test Types:
- Unit tests: Located in /tests/unit/. Each folder corresponds to a domain entity and contains tests for its use cases individually (e.g. User/DeleteAccountUseCase.test.js).
-
End-to-End (E2E) tests:
- Located in /tests/e2e/. Each file represents a domain entity and tests all related endpoints (e.g. users.e2e.js includes tests for user registration, login, profile update, etc.). These tests include seeded data to simulate real scenarios.
-
Running tests
- Unit test with:
npm run test
- E2E test with:
npm run e2e
Remember: After downloading the project make sure that the .env.e2e file is in the repository to be able to run the tests.
- Unit test with:
The API documentation is available through Swagger UI, providing an interactive interface to explore and test the endpoints.
- Visit the following URL to access the Swagger documentation:
Swagger UI - Production
Ensure to set the server to:https://trello-like-project-api.onrender.com/api/v1/
- Remote server.
-
When running the project locally, you can access the Swagger documentation at:
Swagger UI - Development
Ensure to set the server to:http://localhost:3000/api/v1/
- Local server. -
If you specify a different port in the
.env
file (other than3000
), the local backend URL will change accordingly. For example, if the port is set to4000
, the Swagger documentation will be available at:
And the server should be set to:http://localhost:4000/api/v1/
.
Swagger UI offers a user-friendly way to test the API endpoints, view request/response formats, and understand the available features.
Here you can see a preview of the Swagger documentation:
- Docker installed on your machine
- Node.js and npm installed
- Have a Redis account or download a redis image with docker in the .yml file
- Have a Cloudinary account
- For email sending to work, you need a Gmail password. You can access it at https://myaccount.google.com/apppasswords. It will give you a password like: abcd efg hijkl. Remove the spaces and paste it into the .env file in SMT_PASS.
-
Clone the repository:
git clone git@github.com:OscarS05/Trello-like-project.git cd Trello-like-project
-
Create a .env file based on the
.env.example
provided in the project root -
Start the services using Docker Compose:
docker-compose up -d
-
Install dependencies:
npm install --legacy-peer-deps
-
Run database migrations:
npm run migrations:run
-
Start the development server: If you have already registered, can log in successfully and you do not have to send emails:
npm run dev
or,
If you need user registration with email confirmation:
npm run pm2
"scripts": {
"pm2": "pm2 start ecosystem.config.js",
"dev": "nodemon ./api/index.js",
"start": "pm2-runtime ecosystem.config.js",
"lint": "eslint ./api",
"lint:fix": "eslint ./api --fix",
"test": "jest",
"migrations:generate": "sequelize-cli migration:generate --name",
"migrations:run": "sequelize-cli db:migrate",
"migrations:revert": "sequelize-cli db:migrate:undo",
"migrations:delete": "sequelize-cli db:migrate:undo:all",
"migrations:status": "sequelize-cli db:migrate:status",
"seed:all": "sequelize-cli db:seed:all",
"seed:undo": "sequelize-cli db:seed:undo:all",
"e2e": "NODE_ENV=e2e jest --config ./jest-e2e.json --verbose --detectOpenHandles --forceExit --runInBand",
"e2e:ci": "NODE_ENV=ci jest --config ./jest-e2e.json --verbose --detectOpenHandles --forceExit --runInBand",
"e2e:coverage": "NODE_ENV=e2e jest --config ./jest-e2e.json --verbose --detectOpenHandles --forceExit --coverage"
}
The file with the ER diagram is located in the root of the project:
- Trello-like-api-db-schema.drawio To edit it, install the "Draw.io Integration" extension in VSCode. If the diagram doesn't display, right-click on the file β "Reopen Editor With" β "Draw.io".
If you want to view the .png image of the database's ER schema, you must view it from the GitHub repository because it cannot be viewed properly in VSC.
The project is completed. All backend functionalities have been implemented successfully. It runs locally with tools like Insomnia or Postman.
Note The authentication system, along with the creation of lists and cards, is part of the Software Analysis and Development Technologist (SENA) certification. The rest of the project was a voluntary and self-taught creation after SENA.
This section guides you through the basic flow to test the API step by step using Swagger UI. It assumes no frontend is available, and all actions will be performed through the documented endpoints.
Endpoint: POST /api/v1/users/
Create a new user by providing the required fields. After registration, a verification email is automatically sent to the registered email address.
This is a required step after sign-up.
- Copy the token from the email and paste it into the lock icon (top-right in Swagger UI) as a Bearer Token.
- Then call:
POST /auth/verify-email
If you did not receive the email or need to resend it, you can use:
POST /auth/send-verification-email
β to send again.POST /auth/resend-verification-email
β recommended when integrating with a frontend for safer resend control.
If you forget your password:
- Send a verification email to your registered email:
POST /auth/send-verification-email
- Copy the token from the email and verify it:
POST /auth/verify-email-to-recover-password
(use lock icon for Bearer token) - Update your password:
PATCH /auth/password
- Log in again:
POST /auth/login
β You'll receive an accessToken.
- Use the accessToken received from
POST /auth/login
in all subsequent endpoints (starting from/workspaces
). - Paste the accessToken in the Swagger UI lock icon.
- The token is valid for 1 hour. After that:
- You can log in again, or
- Refresh your token using:
POST /auth/refresh-tokens
(uses cookie-stored refreshToken and returns a new accessToken)
π‘ In a frontend application, this token would be passed via the Authorization header using the Bearer scheme.
- Create a workspace:
POST /workspaces
- Create a project (required to interact with the system):
POST /workspaces/{workspaceId}/projects
Optionally, set a background image URL. - To update the background after creation:
PATCH /workspaces/{workspaceId}/projects/{projectId}/background
If you want to test the API quickly, you can skip the steps related to adding members and managing teams. These features are entirely optional and depend on how you intend to use the system. To get started right away, jump directly to Step 8 to begin creating lists and cards. This allows you to explore the core functionality of the API without additional setup. Perfect for quick testing in Swagger UI!
- Add a member to the workspace:
POST /workspaces/{workspaceId}/members
- Add that member to the project:
POST /workspaces/{workspaceId}/projects/{projectId}/members
If you'd like to work with teams:
- Create a team:
POST /workspaces/{workspaceId}/teams
- Add members to the team:
POST /workspaces/{workspaceId}/teams/{teamId}/members
(Only members already in the workspace can be added to teams or projects.) - Assign a project to the team:
POST /workspaces/{workspaceId}/teams/{teamId}/projects/{projectId}
This will automatically add any missing team members to the project.
- Create a list:
POST /workspaces/{workspaceId}/projects/{projectId}/lists
- Create a card within a list:
POST /lists/{listId}/cards
(Cards can represent tasks, goals, or phases β up to the user's definition.)
- Assign members to cards:
POST /cards/{cardId}/members/{projectMemberId}
(Only members of the project can be assigned.) - Create labels (e.g., In Progress, Completed):
POST /projects/{projectId}/cards/{cardId}/labels
- Optionally change label visibility:
PATCH /cards/{cardId}/labels/{labelId}/visibility
- Add attachments (files or images):
POST /cards/{cardId}/attachments
- Create a checklist inside a card:
POST /cards/{cardId}/checklists
- Duplicate a checklist from another card in the same project:
POST /cards/{cardId}/checklists/{checklistId}/copy
- Add checklist items:
POST /cards/{cardId}/checklists/{checklistId}/checklist-items
(Optionally assign members during creation) - Assign more members to a checklist item:
POST /checklists/{checklistId}/checklist-items/{checklistItemId}/members
(If member already assigned, the response will return an empty array.)
- Get a full overview of your board:
GET /workspaces/projects/{projectId}/board
- Get detailed information about a specific card:
GET /lists/{listId}/cards/{cardId}/information
The system supports advanced features such as:
- Transferring ownership of workspaces, projects, or teams.
- Promoting or demoting member roles.
- Removing teams from projects with options to keep or remove team members from that project.
Below are sample requests and responses for key endpoints in the API. These examples demonstrate how authentication, data retrieval, and resource creation work in the system.
POST /api/v1/auth/login
Authenticate a user with their email and password. A successful login returns an access token and sets a secure refresh token cookie.
body:
{
"email": "johndoe@example.com",
"password": "O123456@k"
}
body:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Set-cookie(Header):
refresh-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
GET /api/v1/lists/:listId/cards/:cardId/information
Retrieve detailed information about a specific card, including its metadata, labels, members, attachments, and checklists.
- π‘οΈ Authentication Required: Bearer token
- π Access Control:
- If the project is private, the requester must be a project member.
- If project visibility is workspace, any workspace member can access.
- Returns 403 Forbidden or 404 Not Found as appropriate.
body:
GET /api/v1/lists/7427d184-3a63-4995-9b5d-9862357ed2db/cards/6da5bc61-8590-4db3-a497-6b4a006c2064/information
body:
{
"card": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "string",
"description": "string",
"listId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdAt": "2025-05-02T16:37:17.921Z",
"labels": [
{
"id": "28436f1c-b90e-4b0d-815f-0ad9016ce92b",
"name": "Not started",
"color": "#FFFFFF",
"projectId": "9c8b7e8a-394a-4e47-8f8f-9e66fa4e3a6b",
"isVisible": true
}
],
"cardMembers": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"projectMemberId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Juanita"
}
],
"attachments": [
{
"id": "dbb98467-81ad-4018-90f6-cbf581eac82d",
"filename": "Agroplus-db-scheme.jpg",
"url": "https://res.cloudinary.com/dfprxzekh/image/upload/v1744326304/card-attachments/file_ysjlp7.jpg",
"cardId": "1a8ad354-e5bb-49f7-95b3-5cdfa0533233",
"type": "image/jpeg",
"createdAt": "2025-04-10T23:05:04.884Z"
}
],
"checklists": [
{
"id": "b818e9a7-0eed-4556-89c0-d3c8b9352cfd",
"name": "Task 2",
"cardId": "449f8ab9-1f3a-4d7d-af3d-40be1a8958eb",
"createdAt": "2025-04-12T02:37:49.832Z",
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "item 1",
"checklistId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"isChecked": true,
"dueDate": "2025-05-02T16:37:17.921Z",
"createdAt": "2025-05-02T16:37:17.921Z",
"members": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"projectMemberId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Juanita"
}
]
}
]
}
]
}
}
POST /api/v1/checklists/{checklistId}/checklist-items/{checklistItemId}/members
Assign one or more project members to a specific checklist item in a single request, improving performance and reducing latency.
- π‘οΈ Authentication Required: Bearer token
- π Validation:
- All parameters must be valid UUIDs.
- Requester must be a project member.
- All projectMemberIds must belong to the project.
body:
{
"projectMemberIds": [
"8942a2d8-02c8-464e-8a9a-2d5b8c839ea3",
"26de1037-0474-4e11-bca1-ec344376744b"
]
}
body:
{
"checklistItemMemberAdded": [
{
"id": "93cb4c3c-c9c4-420d-8d2e-0268b74036b0",
"name": "lilo",
"checklistItemId": "327c2217-6383-4305-b20a-ca6d9cb1758d",
"projectMemberId": "26de1037-0474-4e11-bca1-ec344376744b",
"addedAt": "2025-04-09T00:57:42.282Z"
},
{
"id": "93cb4c3c-c9c4-420d-8d2e-0268b74036b0",
"name": "juanita",
"checklistItemId": "327c2217-6383-4305-b20a-ca6d9cb1758d",
"projectMemberId": "26de1037-0474-4e11-bca1-ec344376744b",
"addedAt": "2025-04-09T00:57:42.282Z"
}
]
}
CURRENTLY NOT AVAILABLE
Swagger UI - Production
Note: If you are testing the link in production, please wait a moment/minutes for the application to load. The free plan on Render suspends the application after 15 minutes of inactivity, but it will reactivate when you access the link. This process may take a few seconds. It's also possible that my free hosting plan has expired and the link isn't working.
Watch a 2-3 minute video demonstration showcasing how to use the API via Swagger in production. The video highlights key features such as authentication, creating workspaces, and managing projects.
Trello-like API Demonstration Video
Click the link above to watch a short demonstration showcasing some features of the Autumn API.
This project is licensed under the Creative Commons BY-NC 4.0 License.