RESTful API for inventory management, product control, and order dispatching for a distribution company.
- Runtime: Bun (Express runs on Bun — not Bun.serve)
- Framework: Express 5 + TypeScript
- ORM: Prisma 7 (SQLite via
PrismaBunSQLite) - Auth: JWT with jose + bcrypt
- Validation: Zod
- Docs: Swagger UI at
/api-docs
- Bun >= 1.3
# 1. Install dependencies
bun install
# 2. Create environment file
cp .env.example .env
# Edit .env — minimum required:
# DATABASE_URL=file:./prisma/dev.db
# PORT=3000
# JWT_SECRET=any-secure-string
# 3. Run migrations (creates prisma/dev.db automatically)
bun run prisma:m
# 4. Generate Prisma client
bun run prisma:g
# 5. Seed initial data
bun run prisma:seed
# 6. Start development server
bun run devServer runs at http://localhost:3000.
| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
Path to SQLite file | file:./prisma/dev.db |
PORT |
Server port | 3000 |
NODE_ENV |
Environment | development |
JWT_SECRET |
JWT signing secret | — (required) |
JWT_ACCESS_TOKEN_EXPIRES_IN |
Access token expiry | 15m |
JWT_REFRESH_TOKEN_EXPIRES_IN |
Refresh token expiry | 7d |
CORS_ORIGINS |
Allowed CORS origins (comma-separated) | http://localhost:3000 |
bun run dev # Development with hot-reload (bun --watch)
bun run build # Compile TypeScript to dist/
bun run start # Production (from dist/)
bun run lint # ESLint
bun run format # Prettier
bun run prisma:g # Generate Prisma client
bun run prisma:m # Run migrations
bun run prisma:studio # Prisma Studio (database GUI)
bun run prisma:seed # Seed test data| Role | Password | |
|---|---|---|
| ADMIN | admin@stockflow.com |
Admin123! |
| OPERATOR | operator@stockflow.com |
Operator123! |
The seed also creates 3 categories and 7 products (3 with low stock to test /api/reports/low-stock).
| Method | Route | Description |
|---|---|---|
| POST | /api/auth/register |
Register a new user |
| POST | /api/auth/login |
Login, returns JWT |
| Method | Route | Role | Description |
|---|---|---|---|
| GET | /api/categories |
ADMIN, OPERATOR | List categories |
| POST | /api/categories |
ADMIN | Create category |
| GET | /api/products |
ADMIN, OPERATOR | List products (paginated, filter by ?categoryId=) |
| POST | /api/products |
ADMIN | Create product |
| PUT | /api/products/:id |
ADMIN | Update product |
| DELETE | /api/products/:id |
ADMIN | Delete product (soft delete) |
| GET | /api/reports/low-stock |
ADMIN | Products where stock <= minStock |
| POST | /api/orders |
ADMIN, OPERATOR | Create order (transactional) |
| GET | /api/orders/:id |
ADMIN, OPERATOR | Order detail with products |
| PATCH | /api/orders/:id/status |
ADMIN, OPERATOR | Update order status |
http://localhost:3000/api-docs
{ "success": true, "data": {}, "meta": {}, "error": null }
{ "success": false, "data": null, "meta": {}, "error": { "message": "..." } }
{ "success": false, "data": null, "meta": {}, "error": { "message": "...", "fields": [{ "field": "email", "message": "..." }] } }Paginated response (GET /api/products):
{
"success": true,
"data": [...],
"meta": { "pagination": { "page": 1, "pageSize": 20, "total": 7, "nextPage": null, "prevPage": null } },
"error": null
}| Role | Access |
|---|---|
ADMIN |
Full access. Manages products, categories, reports and orders. |
OPERATOR |
Can list products and categories. Can create and manage orders. |
- Order creation — transactional: stock is verified for all products before proceeding. If any product lacks sufficient stock → full rollback, descriptive error, DB unchanged.
- Order cancellation: automatically restores stock for every product in the order within a single transaction.
- Valid status transitions: only
PENDING → DISPATCHEDorPENDING → CANCELLED. BothDISPATCHEDandCANCELLEDare final states. - Low-stock alert: products where
stock <= minStock. - Soft delete: deleted products use
deletedAt— no physical deletion. - Historical price:
priceAtOrderinOrderItemfreezes the product price at the time of purchase.
The bruno/StockFlow API/ folder contains a ready-to-import collection for Bruno.
bruno/StockFlow API/
├── Auth/ register, login (saves token automatically)
├── Categories/ list, create
├── Products/ list, filter by category, create, update, delete
├── Reports/ low-stock
└── Orders/ create (success), create (insufficient stock), detail, update status
How to use:
- Open Bruno → Open Collection → select
bruno/StockFlow API/ - Select the local environment
- Run
Auth/02-Login— the token is saved automatically into{{token}} - Run the remaining endpoints in order