A clean and modular REST API for managing clients, products, and deliveries — including stock validation and JWT authentication.
Built with Express, Sequelize (PostgreSQL), TypeScript, Jest, and Swagger.
- Node.js + Express 5
- TypeScript
- Sequelize ORM (PostgreSQL)
- JWT Authentication
- Jest (unit testing)
- Swagger UI (OpenAPI 3)
- Docker + Docker Compose
npm installCreate a .env file in the project root (optional if you use defaults):
PORT=4000
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=perla
DB_NAME=sportslinedb
JWT_ACCESS_SECRET=change-me-access
JWT_REFRESH_SECRET=change-me-refreshOption A: Use your local PostgreSQL
Option B: Run a temporary PostgreSQL container:
docker run --name sportline_db -e POSTGRES_PASSWORD=perla -e POSTGRES_DB=sportslinedb -p 5432:5432 -d postgres:16npm run dev- API: http://localhost:4000
- Swagger UI: http://localhost:4000/api/docs
- Development (TS):
npm run seed
- Production build (JS):
npm run build && npm run seed:prod
npm run test📝 Note: The server runs
sequelize.sync({ alter: true })on startup.
For production, migrations are strongly recommended.
✅ Deliveries are handled transactionally — stock validation and decrements occur atomically.
The included docker-compose.yml spins up both the API and a PostgreSQL instance.
It can also run the seeder automatically on first boot.
docker-compose up --build- API: http://localhost:4000
- Swagger UI: http://localhost:4000/api/docs
docker-compose downDB_HOST=db
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=example
DB_NAME=sportlinedb
JWT_ACCESS_SECRET=your-strong-secret
JWT_REFRESH_SECRET=your-strong-secret
RUN_SEEDER=true🔧 To disable seeding, set
RUN_SEEDER=falseor remove it from the app service env.
💡 Tip: If you modify DB_* or JWT_* values, ensure they match your app configuration and client settings.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Compile TypeScript (→ dist) |
npm start |
Run from compiled JS |
npm run seed |
Run TypeScript seeder |
npm run seed:prod |
Run seeder from built files |
npm run test |
Run Jest tests with coverage |
npm run test:watch |
Watch mode for Jest |
POST /api/auth/registerPOST /api/auth/loginPOST /api/auth/refresh
GET /api/clientsPOST /api/clientsGET /api/clients/:idPUT /api/clients/:idDELETE /api/clients/:id
GET /api/productsPOST /api/productsGET /api/products/:idPUT /api/products/:idDELETE /api/products/:idGET /api/products/code/:code
POST /api/deliveries(validates and decreases stock)GET /api/deliveries/client/:clientId/history
{
"clientId": 1,
"notes": "Order #123",
"items": [
{ "productId": 10, "quantity": 2 },
{ "productId": 12, "quantity": 1 }
]
}src/
├─ app.ts # Express setup & route mounting
├─ config/db.ts # Sequelize configuration
├─ models/ # Sequelize models
├─ dao/ # Data access layer
├─ services/ # Business logic
├─ controllers/ # Route handlers
├─ routes/ # Express routers
├─ middleware/ # Validation, auth, etc.
├─ dtos/ # Type definitions
├─ utils/ # Helpers (hash, jwt, validation)
├─ docs/swagger.ts # OpenAPI specification
└─ seeders/seeder.ts # Sample data seeder
tests/ # Jest unit tests
- 🔒 Use strong secrets for:
JWT_ACCESS_SECRETJWT_REFRESH_SECRET
- 🚫 Disable
sequelize.sync({ alter: true })in production — use migrations instead. - 🧩 Add logging, monitoring, and error tracking (e.g., Winston + Sentry).
- 📦 Configure persistent storage for PostgreSQL in Docker (
volumes:section).
- Fully typed API with TypeScript (strict mode)
- Modular architecture (DAO + Services + Controllers)
- Automated DB seeding
- Integrated Swagger documentation
- Transactional stock validation
- Jest test coverage ready
This project is distributed under the MIT License.
Feel free to use, modify, and share it under the same terms.