RESTful API backend for a billing and invoicing management system. Built with Node.js and Express, powered by Firebase Firestore as the database. It provides full CRUD operations for products, clients, suppliers, categories, sales, employees, and daily revenue reports.
๐ Live Demo: https://sistema-facturacion-front-roan.vercel.app/
| Technology | Purpose |
|---|---|
| Node.js | Runtime environment |
| Express | Web framework |
| Firebase Admin SDK | Firestore database & authentication |
| Nodemailer | Email service (password recovery) |
| Bcrypt | Password hashing |
| Helmet | HTTP security headers |
| CORS | Cross-origin resource sharing |
| express-rate-limit | Rate limiting (demo mode) |
| Docker | Containerization |
| GitHub Actions | CI/CD pipeline |
- ๐ Session-based authentication with secure HTTP-only cookies
- ๐ฆ Full CRUD for products, clients, suppliers, categories, and sales
- ๐ฅ Employee management with role-based access
- ๐ Daily revenue reports with date range filtering and payment method breakdown
- ๐ง Password recovery via email
- ๐ก๏ธ Security hardened with Helmet, CORS whitelist, and rate limiting
- ๐ฎ Demo mode with configurable request limits
- ๐ณ Docker-ready with non-root user and automated deployments
- Node.js v18 or higher
- npm v9 or higher
- A Firebase project with Firestore enabled
- A Firebase Service Account Key (JSON file)
# Clone the repository
git clone https://github.com/AugustoC01/sistema-facturacion-back.git
cd sistema-facturacion-back
# Install dependencies
npm installCreate a .env.local file in the root directory based on the .example.env template:
# API Configuration
PORT = 8080
CORS_ORIGINS = https://yourdomain.com
NODE_ENV = development
APP_MODE = production
MAX_LIMIT = 30
# Firebase
GOOGLE_APPLICATION_CREDENTIALS = ./serviceAccountKey.json
# Nodemailer (Gmail)
SENDER = your-email@gmail.com
PASS = your-app-password| Variable | Description |
|---|---|
PORT |
Server port (default: 8080) |
CORS_ORIGINS |
Comma-separated list of allowed origins |
NODE_ENV |
development or production โ dev mode auto-allows localhost:5173 |
APP_MODE |
Set to demo to enable rate limiting |
MAX_LIMIT |
Max daily requests allowed in demo mode (default: 30) |
GOOGLE_APPLICATION_CREDENTIALS |
Path to your Firebase service account JSON file |
SENDER |
Email address used for sending password recovery emails |
PASS |
App password for the sender email account |
npm run devThe server will start on http://localhost:<PORT> with hot-reload via Nodemon.
# Build the image
docker build -t sistema-facturacion-back .
# Run the container
docker run -p 8080:8080 \
--env-file .env \
-v /path/to/serviceAccountKey.json:/app/secrets/serviceAccountKey.json \
sistema-facturacion-backsrc/
โโโ index.js # App entry point & middleware setup
โโโ config.js # Environment config & CORS options
โโโ controllers/ # Request handlers
โ โโโ authController.js
โ โโโ categoryController.js
โ โโโ clientController.js
โ โโโ employeeController.js
โ โโโ productController.js
โ โโโ reportsController.js
โ โโโ saleController.js
โ โโโ supplierController.js
โโโ routes/ # Route definitions
โ โโโ router.js # Main router (mounts all sub-routes)
โ โโโ authRoute.js
โ โโโ categoryRoute.js
โ โโโ clientRoute.js
โ โโโ employeeRoute.js
โ โโโ productRoute.js
โ โโโ reportRoute.js
โ โโโ saleRoute.js
โ โโโ supplierRoute.js
โโโ middleware/
โ โโโ userAuth.js # Session authentication middleware
โ โโโ demoRateLimiter.js
โโโ service/
โ โโโ firebase.js # Firebase Admin SDK initialization
โ โโโ db.js # Generic Firestore CRUD operations
โ โโโ employeeService.js
โโโ utils/
โโโ bcrypt.js # Password hashing helpers
โโโ idGenerator.js # Unique ID generation (nanoid)
โโโ nodemailer.js # Email sending
โโโ objectUtils.js
โ ๏ธ All endpoints except/user/*require an active session cookie (sessionId). Unauthenticated requests will receive a401 Unauthorizedresponse.
Base URL: http://localhost:8080
| Method | Endpoint | Description |
|---|---|---|
POST |
/user/signup |
Register a new employee |
POST |
/user/login |
Log in and receive a session cookie |
POST |
/user/logout |
Log out and clear the session |
POST |
/user/forgotPassword |
Send a password recovery email |
Request / Response Details
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword"
}{
"email": "john@example.com",
"password": "securepassword"
}โ
On success, a sessionId cookie is set automatically.
No body required. Clears the session cookie.
{
"email": "john@example.com"
}๐ง A new auto-generated password will be sent to the provided email.
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/employees |
Get all employees |
GET |
/employees/:id |
Get employee by ID |
PUT |
/employees/:id |
Update employee |
DELETE |
/employees/:id |
Delete employee |
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/categories |
Get all categories |
GET |
/categories/:id |
Get category by ID |
POST |
/categories |
Create a new category |
PUT |
/categories/:id |
Update a category |
DELETE |
/categories/:id |
Delete a category |
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/products |
Get all products |
GET |
/products/:id |
Get product by ID |
POST |
/products |
Create a new product |
PUT |
/products/:id |
Update a product |
DELETE |
/products/:id |
Delete a product |
Filtering & Queries:
| Method | Endpoint | Description |
|---|---|---|
GET |
/products/category/:categoryId |
Get products by category |
GET |
/products/supplier/:supplierId |
Get products by supplier |
GET |
/products/stock/enabled |
Get products in stock |
GET |
/products/stock/disabled |
Get out-of-stock products |
GET |
/products/stock/:quantity |
Get products with stock below a quantity |
GET |
/products/higherPrice/:price |
Get products above a price |
GET |
/products/lowerPrice/:price |
Get products below a price |
Field Operations:
| Method | Endpoint | Description |
|---|---|---|
DELETE |
/products/remove/:id/field |
Delete a specific field from a product |
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/suppliers |
Get all suppliers |
GET |
/suppliers/:id |
Get supplier by ID |
POST |
/suppliers |
Create a new supplier |
PUT |
/suppliers/:id |
Update a supplier |
DELETE |
/suppliers/:id |
Delete a supplier |
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/clients |
Get all clients |
GET |
/clients/:id |
Get client by ID |
POST |
/clients |
Create a new client |
PUT |
/clients/:id |
Update a client |
DELETE |
/clients/:id |
Delete a client |
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/sales |
Get all sales |
GET |
/sales/:id |
Get sale by ID |
POST |
/sales |
Create a new sale |
PUT |
/sales/:id |
Update a sale |
DELETE |
/sales/:id |
Delete a sale |
๐ Creating or deleting a sale automatically updates the daily revenue report.
๐ Requires authentication
| Method | Endpoint | Description |
|---|---|---|
GET |
/reports |
Get all daily reports |
GET |
/reports/days/:begin/:end |
Get total revenue between two dates |
Date format for the range query:
DD-MM-YYYY(e.g.,/reports/days/01-01-2025/31-01-2025)
This project includes a GitHub Actions workflow that automatically deploys to a VPS on every push to main. The pipeline connects via SSH and runs a deployment script on the server.
Required GitHub Secrets:
VPS_HOSTโ Server IP/hostnameVPS_USERโ SSH usernameSSH_PRIVATE_KEYโ Private SSH key
- Expand employees management features
- Expand providers/suppliers management
- Add more analytics and reporting capabilities
This project is licensed under the ISC license.
Made with โค๏ธ by Augusto