A NestJS-based RESTful API , using TypeORM with PostgreSQL. This README provides instructions for contributors to set up the project and details the available API endpoints.
| Method | Endpoint | Description | Request Body | Response |
|---|---|---|---|---|
| POST | /api/v1/users |
Create a new user | CreateUserDto (name, email, password) |
UserResponseDto (name, email, message) |
| GET | /api/v1/users/:id |
Get a user by ID | None | UserResponseDto (name, email, message) |
| GET | /api/v1/users |
Get all users | None | UserResponseDto[] |
| PUT | /api/v1/users/:id |
Update a user by ID | UpdateUserDto (name?, email?, password?) |
UserResponseDto (name, email, message) |
| DELETE | /api/v1/users/:id |
Delete a user by ID | None | string (success message) |
curl -X POST http://localhost:3000/api/v1/users -H "Content-Type: application/json" -d '{ "name": "Oladele20", "email": "samuel@mailto.com","password": "password3" }'Response:
{
"name": "Oladele20",
"email": "samuel@mailto.com",
"message": "user created successfully..."
}curl http://localhost:3000/api/v1/users/1Response:
{
"name": "Oladele20",
"email": "samuel@mailto.com",
}curl http://localhost:3000/api/v1/usersResponse:
[
{
"name": "Oladele1",
"email": "stringing20@mail.com"
},
{
"name": "Oladele20",
"email": "samuel@mailto.com"
}
]curl -X PUT http://localhost:3000/api/v1/users/1 -H "Content-Type: application/json" -d '{"name":"blurbeast"}'Response:
{
"name": "blurbeast",
"email": "samuel@mailto.com",
"message": "user updated successfully"
}curl -X DELETE http://localhost:3000/api/v1/users/1Response:
"User deleted successfully"- Node.js: v20.x (install via
nvm):curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash nvm install 20 nvm use 20 - PostgreSQL: Install and ensure it’s running:
sudo apt update sudo apt install postgresql postgresql-contrib sudo service postgresql start
- Git: Installed for cloning the repository.
-
Clone the Repository:
git clone https://github.com/your-username/my-fans-backend.git cd my-fans-backend -
Install Dependencies:
npm install
-
Configure Environment: Copy the example file and adjust values for your local PostgreSQL instance:
cp .env.example .env
Required variables (see
.env.examplefor the full list):Variable Description DB_HOST,DB_PORT,DB_NAME,DB_USERNAME,DB_PASSWORDPostgreSQL connection JWT_SECRET(orJWT_ACCESS_SECRET)Access-token signing secret JWT_EXPIRES_IN(orJWT_ACCESS_EXPIRATION)Access-token lifetime PORTHTTP server port (default 3000)NODE_ENVdevelopment,test, orproductionThe app validates environment variables at startup and exits with a readable error if required values are missing or invalid.
-
Start the Application:
npm run start:dev
-
Test APIs: Use the
curlcommands in the API Documentation section to verify endpoints.
Run the unit test suite:
npm testRun the end-to-end suite:
npm run test:e2eThe e2e suite uses a dedicated PostgreSQL test database and does not read your normal DB_* variables.
Integration tests use Testcontainers to spin up a real PostgreSQL container automatically — no manual database setup or credentials required. The only prerequisite is a running Docker daemon.
# Make sure Docker is running first
docker info
# Run the full integration suite
npm run test:integrationWhat happens under the hood:
- Testcontainers pulls
postgres:16(cached after the first run) and starts a container on a random free port. - All TypeORM migrations run against the fresh database. If any migration fails, the suite exits immediately with a clear error.
- Each test file clears all tables in
beforeEachso tests are fully isolated and order-independent. - After the suite finishes the container is stopped and removed automatically.
The integration tests cover:
| Spec file | Scenarios |
|---|---|
users-pagination.integration.spec.ts |
Default limit, custom limit, cursor-based next page, role filter, status filter, search |
user-sessions.integration.spec.ts |
Session creation, multi-session login, token rotation, logout, logout-all, revoked-token rejection |
user-profile-constraints.integration.spec.ts |
Duplicate email rejection, non-unique display name, profile field persistence, bio length limit |
If you want to keep the container running between runs for faster iteration, set TESTCONTAINERS_RYUK_DISABLED=true in your shell. The next npm run test:integration will start a fresh container as usual once RYUK is re-enabled. By default it connects to:
TEST_DB_HOST=127.0.0.1
TEST_DB_PORT=5432
TEST_DB_NAME=my_fans_test
TEST_DB_USERNAME=postgres
TEST_DB_PASSWORD=postgres
TEST_JWT_SECRET=test-jwt-secret
TEST_JWT_EXPIRES_IN=1hCreate the database once before running locally:
createdb -h 127.0.0.1 -U postgres my_fans_testOverride the TEST_DB_* variables if your local PostgreSQL user, password, host, or port differs. Test data is truncated between specs.
Populate the local database with test users by running:
npm run seed:devThe script is idempotent — re-running it skips users that already exist.
To wipe the users table first and start fresh:
npm run seed:dev -- --fresh
⚠️ The script refuses to run whenNODE_ENV=production.
| Name | Password | Role (future) | |
|---|---|---|---|
| Fan One | fan1@dev.local | Fan1Pass! | fan |
| Fan Two | fan2@dev.local | Fan2Pass! | fan |
| Creator One | creator1@dev.local | Creator1Pass! | creator |
| Creator Two | creator2@dev.local | Creator2Pass! | creator |
| Admin | admin@dev.local | AdminPass! | admin |
These credentials are development-only and must never be used in production.
curl -H "Authorization: Bearer <ACCESS_TOKEN>" "http://localhost:3000/creators/me/analytics?days=30"Response:
{
"data": {
"subscriberCount": 120,
"newSubscribers": 15,
"churnedSubscribers": 3,
"periodDays": 30,
"topReferrers": []
}
}- Fork the repository.
- Clone your fork locally:
git clone https://github.com/your-username/my-fans-backend.git
- Create a feature branch:
git checkout -b feature/your-feature
- Make changes and commit:
If Husky linting blocks the commit, bypass temporarily:
git commit -m "Add your feature or fix"git commit -m "Add your feature or fix" --no-verify - Push to your fork:
git push origin feature/your-feature
- Open a Pull Request on the main repository.
- Not-Null Constraint Errors:
- Ensure
CreateUserDtohas valid data forname,email, andpassword. - Check migrations for correct
Usertable schema (NOT NULLconstraints).
- Ensure
- Database Connection Issues:
- Verify
.envvariables (DB_HOST,DB_PORT,DB_NAME,DB_USERNAME,DB_PASSWORD). - Check PostgreSQL status:
sudo service postgresql status
- Verify
- Pagination, filtering & search
- Cursor pagination migration
- Logging & monitoring
- API versioning and breaking change policy
MIT License