Documento de evaluacion: Ver documento-entrega.md para el detalle de todos los requisitos implementados, su ubicacion en el codigo y la nota a la que se opta.
A microservice for managing budgets and analytics, built with Bun and Hono. Part of the 0debt project.
- π Fast: Built on Bun runtime for optimal performance
- π Budget Management: Create, update, delete, and monitor budgets
- π JWT Auth: User identification via Kong Gateway (Trust the Gateway)
- β‘ Redis Cache: Cache-Aside pattern with 5s TTL
- π Circuit Breaker: Resilient integration with expenses-service (opossum)
- π Charts: QuickChart.io integration with Feature Toggle
- π SAGA Support: Internal endpoint for distributed transactions
- π‘οΈ Rate Limit: Middleware propio por plan en el endpoint de QuickChart (FREE/PRO/ENTERPRISE)
- π API Documentation: Swagger UI for interactive API testing
- π§ͺ Testing: 20+ tests covering all scenarios
| Component | Technology |
|---|---|
| Runtime | Bun |
| Framework | Hono |
| Database | MongoDB Atlas (Mongoose) |
| Cache | Redis (ioredis) |
| Resilience | Circuit Breaker (opossum) |
| Auth | JWT decode (jwt-decode) |
- Bun (latest version)
- MongoDB Atlas account or local MongoDB instance
- Redis (optional - service works without it)
git clone <repository-url>
cd analytics-service
bun installCreate a .env file:
# Required
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/
NODE_ENV=development
# Optional (graceful defaults)
REDIS_URL=redis://localhost:6379 # Without Redis = cache disabled
EXPENSES_SERVICE_URL=http://localhost:3000 # Without URL = mock data
ENABLE_CHARTS=true # Without = feature disabledBased on NODE_ENV:
developmentβdevdatabasetestβtestdatabaseproductionβproddatabase
bun run devServer starts on http://localhost:3000
NODE_ENV=production bun run src/server.ts| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /v1/health |
Health check | No |
| POST | /v1/budgets |
Create budget | Yes |
| GET | /v1/budgets/group/:groupId |
List group budgets | No |
| PUT | /v1/budgets/:id |
Update limit | No |
| DELETE | /v1/budgets/:id |
Delete budget | No |
| GET | /v1/budgets/:id/status |
Get status (cached) | No |
| GET | /v1/budgets/:id/chart |
Get chart URL | No |
| DELETE | /v1/internal/users/:userId |
SAGA: Delete user data | Internal |
curl -X POST http://localhost:3000/v1/budgets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <jwt-token>" \
-d '{"groupId":"group-123","category":"Food","limitAmount":500,"period":"monthly"}'curl http://localhost:3000/v1/budgets/:id/statusResponse:
{
"limit": 500,
"spent": 150.00,
"health": "OK"
}Health values: OK (<80%), WARNING (80-100%), OVERBUDGET (>100%)
curl http://localhost:3000/v1/budgets/:id/chartResponse (default or ENABLE_CHARTS not set, unless explicitly false):
{
"url": "https://quickchart.io/chart?c=..."
}Rate limit por plan (middleware propio, ventana mensual ~30 dΓas):
- FREE: 2 req/mes
- PRO: 15 req/mes
- ENTERPRISE: 50 req/mes
Sin token se aplica FREE y se usa IP/userId como clave. Para deshabilitar la feature, define
ENABLE_CHARTS=false.
curl -X DELETE http://localhost:3000/v1/internal/users/:userIdResponse:
{
"status": "ok",
"deletedCount": 3
}See plan-phases.md for detailed diagrams and implementation phases.
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Client ββββββΆβ Kong ββββββΆβ Analytics β
β β β Gateway β β Service β
βββββββββββββββ βββββββββββββββ ββββββββ¬βββββββ
β
ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β MongoDB β β Redis β β Expenses β
β (Data) β β (Cache) β β Service β
βββββββββββββββ βββββββββββββββ βββββββββββββββ
- Swagger UI:
http://localhost:3000/swagger - OpenAPI JSON:
http://localhost:3000/docs
# Start server in one terminal
bun run dev
# Run tests in another terminal
API_URL=http://localhost:3000 bun test- β Health check
- β Budget CRUD operations
- β Authorization validation
- β Cache behavior (hit/miss)
- β Feature toggle (charts)
- β SAGA participation
- β Input validation
analytics-service/
βββ .github/
β βββ workflows/
β βββ deploy.yaml # CI/CD: Build + Deploy to Coolify
β βββ test.yaml # CI: Run tests on tag
βββ src/
β βββ clients/
β β βββ expensesClient.ts # Circuit Breaker client
β βββ config/
β β βββ database.ts # MongoDB connection
β β βββ openapi.ts # OpenAPI specification
β β βββ redis.ts # Redis connection + retry
β βββ controllers/
β β βββ budgetController.ts # All budget handlers
β βββ helpers/
β β βββ userContext.ts # JWT decode helper
β βββ middleware/
β β βββ chartRateLimiter.ts # Rate limit by plan
β βββ models/
β β βββ budgetSchema.ts # Mongoose schema
β βββ routes/
β β βββ budgets.ts # Route definitions
β βββ services/
β β βββ chartService.ts # QuickChart URL generator
β βββ server.ts # Entry point
βββ tests/
β βββ integration/
β βββ budget.test.ts # 20 integration tests
βββ Dockerfile # Docker image
βββ package.json
βββ documento-entrega.md # Evaluation criteria
βββ README.md
- Timeout: 3 seconds
- Error Threshold: 50%
- Reset Timeout: 10 seconds
- Fallback: Returns
null, service continues
- TTL: 5 seconds
- Key:
analytics:budget:stats:{groupId} - Graceful: Works without Redis (cache disabled)
MIT