RESTful API for project management with CRUD operations, built with Node.js, TypeScript, Express, Prisma, and PostgreSQL.
- β CRUD Operations for Project entity
- β AI-Powered Analytics with Google Gemini for project insights
- β Aggregated Statistics for data visualization and reporting
- β TypeScript with strict mode and ESM
- β Prisma ORM with PostgreSQL
- β Express Validator for request validation
- β
Swagger UI for API documentation at
/docs - β Business Logic Validation (endDate requirements based on status)
- β Custom Error Handling with structured error responses
- β Jest Tests with 100% coverage on utils and validation
- β Clean Code architecture (controllers, services, middlewares)
- Node.js >= 18
- PostgreSQL database
- npm or yarn
Visit http://localhost:3000/docs for Swagger documentation.
git clone https://github.com/nataliahe24/project-api-rest.git
cd project-api-restnpm install express cors @prisma/client dotenv swagger-ui-express swagger-jsdoc express-validatornpm install -D typescript ts-node tsx nodemon prisma @types/node @types/express @types/cors @types/swagger-jsdoc @types/swagger-ui-expressnpm install @google/generative-ainpm install -D jest ts-jest @jest/globals @types/jestCreate a .env file in the root directory:
DATABASE_URL="postgresql://postgres:password@localhost:5432/name_db"
PORT=?Database URL Format:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE
Getting your Gemini API Key:
- Visit Google AI Studio
- Sign in with your Google account
- Click "Create API Key" or "Get API Key"
- Copy the key and paste it in your
.envfile
Note: The Gemini API has a generous free tier. The API key is required for the AI analytics endpoint.
npx prisma init --datasource-provider postgresqlThis command creates the database tables based on your schema:
npx prisma migrate dev --name initNote: If you make changes to
prisma/schema.prisma, run migrations again:npx prisma migrate dev --name your_migration_name
npx prisma generateNote: Run this command every time you change the Prisma schema.
| Script | Command | Description |
|---|---|---|
| Development | npm run dev |
Start development server with hot reload |
| Test | npm test |
Run all tests with Jest |
| Test Watch | npm run test:watch |
Run tests in watch mode |
| Test Coverage | npm run test:coverage |
Run tests with coverage report |
npm run devπ Server running at: http://localhost:${PORT}
- π API Base URL: http://localhost:${PORT}
- π Swagger Documentation: http://localhost:${PORT}/docs
- π Example Endpoint: http://localhost:${PORT}/project
npm testnpm run test:watchnpm run test:coverageCurrent coverage for core business logic:
- Utils: 100% coverage (AppError, DateIsRequired) - 20 tests
- Validations: 100% coverage (body.validation) - 15 tests
- Service: Mocked Prisma tests - 20 tests
Total: 55 tests β
| Method | Endpoint | Description |
|---|---|---|
| GET | /project |
Get all projects |
| GET | /project/:id |
Get project by ID |
| POST | /project |
Create a new project |
| PUT | /project/:id |
Update a project |
| DELETE | /project/:id |
Delete a project |
| Method | Endpoint | Description |
|---|---|---|
| GET | /analytics/graphics |
Get aggregated project statistics by status |
| GET | /analytics/:id |
Generate AI-powered analysis for a project |
Get aggregated data for charts and visualizations.
Response (200 OK):
{
"totalProjects": 10,
"projectsByStatus": [
{
"status": "in progress",
"count": 6,
"percentage": 60.0
},
{
"status": "completed",
"count": 4,
"percentage": 40.0
}
],
"completedProjects": 4,
"inProgressProjects": 6
}Use Cases:
- Generate pie/donut charts showing project distribution by status
- Create bar charts with project counts per status
- Display KPIs and metrics in dashboards
- Generate executive reports with portfolio metrics
Generate an AI-powered executive summary for a specific project using Google Gemini.
Parameters:
id(path parameter) - Project ID
Response (200 OK):
{
"summary": "This Cloud Migration project aims to transition internal servers and storage to AWS infrastructure. Key objectives include improved scalability, cost optimization, and enhanced reliability. Currently in progress, the migration demonstrates forward-thinking IT strategy. Recommendations: ensure comprehensive backup procedures, staff training on AWS services, and phased implementation to minimize disruption.",
"totalProjects": 1,
"generatedAt": "2025-10-20T12:30:45.123Z"
}Error Responses:
- 404 Not Found - Project doesn't exist
{
"message": "Project not found",
"statusCode": 404,
"type": "NotFoundError"
}- 500 Internal Server Error - AI service unavailable or API key not configured
{
"message": "Failed to generate AI analysis. Please try again later.",
"statusCode": 500,
"type": "AIServiceError"
}Use Cases:
- Generate executive summaries automatically for reports
- Identify patterns and trends in project portfolio
- Obtain insights for strategic decision-making
- Prepare presentations for stakeholders
- Monthly/quarterly portfolio analysis
Requirements:
- Valid
GEMINI_API_KEYin environment variables - Active internet connection
- Project must exist in database
Request Body:
{
"name": "New Project",
"description": "Project description",
"status": "in progress",
"startDate": "2025-01-01T00:00:00.000Z"
}Response (201 Created):
{
"id": 1,
"name": "New Project",
"description": "Project description",
"status": "in progress",
"startDate": "2025-01-01T00:00:00.000Z",
"endDate": null,
"createdAt": "2025-10-19T06:00:00.000Z",
"updatedAt": "2025-10-19T06:00:00.000Z"
}Request Body:
{
"name": "Completed Project",
"description": "This project is done",
"status": "completed",
"startDate": "2025-01-01T00:00:00.000Z",
"endDate": "2025-12-31T00:00:00.000Z"
}Request Body:
{
"status": "completed",
"endDate": "2025-12-31T00:00:00.000Z"
}-
Status: "in progress"
endDateis optional (can be null or omitted)- If
endDateis provided β 400 Error
-
Status: "completed"
endDateis required- If
endDateis missing/null β 400 Error
β Invalid - Completed without endDate:
{
"name": "Project",
"status": "completed",
"startDate": "2025-01-01T00:00:00.000Z"
}Response: 400 Bad Request
{
"message": "End date is required when status is Completed"
}β Invalid - In progress with endDate:
{
"name": "Project",
"status": "in progress",
"startDate": "2025-01-01T00:00:00.000Z",
"endDate": "2025-12-31T00:00:00.000Z"
}Response: 400 Bad Request
{
"message": "End date is not allowed when status is In Progress"
}project-api-rest/
βββ src/
β βββ app.ts # Express application setup
β βββ configurations/
β β βββ swagger.ts # Swagger/OpenAPI configuration
β βββ controllers/
β β βββ analytics.controller.ts # Analytics request handlers
β β βββ project.controller.ts # Project request handlers
β βββ interfaces/
β β βββ analytics.interface.ts # Analytics TypeScript interfaces
β β βββ project.interface.ts # Project TypeScript interfaces
β βββ middlewares/
β β βββ body.validation.ts # Express-validator rules
β β βββ global.error.handle.ts # Global error handler
β β βββ validate.request.ts # Validation middleware
β β βββ __tests__/ # Middleware tests
β βββ routes/
β β βββ index.ts # Dynamic route loader
β β βββ analytics.ts # Analytics routes
β β βββ project.ts # Project routes
β βββ services/
β β βββ analytics.service.ts # Analytics business logic with AI
β β βββ project.service.ts # Project business logic
β β βββ __tests__/ # Service tests
β βββ utils/
β βββ app.error.ts # Custom error class
β βββ validate.date.ts # Date validation utility
β βββ __tests__/ # Utility tests
βββ prisma/
β βββ schema.prisma # Prisma schema
β βββ migrations/ # Database migrations
βββ jest.config.cjs # Jest configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Project dependencies
- Node.js - Runtime environment
- TypeScript - Type-safe JavaScript
- Express 5 - Web framework
- Prisma - ORM for PostgreSQL
- PostgreSQL - Relational database
- Google Gemini AI - AI-powered project analysis
- Swagger UI Express - API documentation
- Express Validator - Request validation
- Jest - Testing framework
- ts-jest - TypeScript preprocessor for Jest
# View your database in Prisma Studio (GUI)
npx prisma studio
# Create a new migration after schema changes
npx prisma migrate dev --name migration_name
# Apply pending migrations
npx prisma migrate deploy
# Reset database (WARNING: deletes all data)
npx prisma migrate reset
# Regenerate Prisma Client after schema changes
npx prisma generate
# Format your Prisma schema file
npx prisma format
# Validate your Prisma schema
npx prisma validate# Run development server
npm run dev
# Run tests once
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watchProblem: P1001: Can't reach database server
Solution:
- Ensure PostgreSQL is running
- Check your
.envfile has correct credentials - Verify database exists:
psql -U postgres -c "CREATE DATABASE projects_db;"
Problem: Cannot find module '@prisma/client'
Solution:
npm install @prisma/client
npx prisma generateProblem: Schema drift detected
Solution:
npx prisma migrate reset
npx prisma migrate devProblem: Tests failing due to module resolution
Solution: Ensure you're using Node.js >= 18 and run:
npm install
npm testmodel Project {
id Int @id @default(autoincrement())
name String
description String?
status String
startDate DateTime
endDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Tests focus on critical business logic:
- DateIsRequired Utility (
validate.date.test.ts)
- β Status "completed" requires endDate
- β Status "in progress" rejects endDate
- β Proper error throwing with AppError
- β Edge cases (empty strings, null values)
- β ISO date string handling
- AppError Class (
app.error.test.ts)
- β Default values (statusCode: 400, type: "AppError")
- β Custom statusCode and type
- β Error inheritance from Error class
- β Throwable and catchable
- β Stack trace preservation
- β POST: Required fields validation
- β PUT: Optional fields (partial updates)
- β Status enum validation (case-insensitive)
- β Date format validation (ISO8601)
- β Empty body handling for PUT
- β getProjects: Returns all projects, handles empty arrays
- β getProjectById: Returns project by ID, throws AppError (404) when not found
- β createProject: Creates in progress/completed projects, validates endDate rules
- β updateProject: Updates fields, validates status transitions, enforces business rules
- β deleteProject: Deletes projects, validates existence before deletion
- β Uses mocked PrismaClient for isolated unit testing
# Run all tests
npm test
# Watch mode (auto-rerun on changes)
npm run test:watch
# With coverage report
npm run test:coverageTest Suites: 4 passed, 4 total
Tests: 52 assed, 52total
Snapshots: 0 total
Time: ~10s
The API uses structured error responses:
{
"message": "Error message",
"statusCode": 400,
"type": "ValidationError"
}Error Types:
ValidationError(400) - Input validation failedNotFoundError(404) - Resource not foundAppError(400) - General application error
feat:New featuresfix:Bug fixesrefactor:Code changes without affecting functionalitytest:Adding or updating testschore:Maintenance tasksdocs:Documentation changes
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
ISC
Natalia Henao
- GitHub: @nataliahe24
- Repository: project-api-rest
Built with β€οΈ using TypeScript, Express, and Prisma