Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

50 Commits

Folders and files

Repository files navigation

Analytics service

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.

Bun Hono MongoDB Redis

Features

  • πŸš€ 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

Tech stack

Component Technology
Runtime Bun
Framework Hono
Database MongoDB Atlas (Mongoose)
Cache Redis (ioredis)
Resilience Circuit Breaker (opossum)
Auth JWT decode (jwt-decode)

Prerequisites

  • Bun (latest version)
  • MongoDB Atlas account or local MongoDB instance
  • Redis (optional - service works without it)

Installation

git clone <repository-url>
cd analytics-service
bun install

Configuration

Create 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 disabled

Database selection

Based on NODE_ENV:

  • development β†’ dev database
  • test β†’ test database
  • production β†’ prod database

Usage

Development

bun run dev

Server starts on http://localhost:3000

Production

NODE_ENV=production bun run src/server.ts

API endpoints

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

Create budget (requires JWT)

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"}'

Get budget status

curl http://localhost:3000/v1/budgets/:id/status

Response:

{
  "limit": 500,
  "spent": 150.00,
  "health": "OK"
}

Health values: OK (<80%), WARNING (80-100%), OVERBUDGET (>100%)

Get chart URL (feature toggle, default ON)

curl http://localhost:3000/v1/budgets/:id/chart

Response (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.

SAGA: Delete user budgets

curl -X DELETE http://localhost:3000/v1/internal/users/:userId

Response:

{
  "status": "ok",
  "deletedCount": 3
}

Architecture

See plan-phases.md for detailed diagrams and implementation phases.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Client    │────▢│    Kong     │────▢│  Analytics  β”‚
β”‚             β”‚     β”‚   Gateway   β”‚     β”‚   Service   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                               β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                          β”‚                          β”‚
                    β–Ό                          β–Ό                          β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚   MongoDB   β”‚           β”‚    Redis    β”‚           β”‚  Expenses   β”‚
             β”‚   (Data)    β”‚           β”‚   (Cache)   β”‚           β”‚  Service    β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

API documentation

  • Swagger UI: http://localhost:3000/swagger
  • OpenAPI JSON: http://localhost:3000/docs

Testing

# Start server in one terminal
bun run dev

# Run tests in another terminal
API_URL=http://localhost:3000 bun test

Test coverage (20 tests)

  • βœ… Health check
  • βœ… Budget CRUD operations
  • βœ… Authorization validation
  • βœ… Cache behavior (hit/miss)
  • βœ… Feature toggle (charts)
  • βœ… SAGA participation
  • βœ… Input validation

Project structure

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

Resilience patterns

Circuit Breaker (expenses-service)

  • Timeout: 3 seconds
  • Error Threshold: 50%
  • Reset Timeout: 10 seconds
  • Fallback: Returns null, service continues

Cache-Aside (Redis)

  • TTL: 5 seconds
  • Key: analytics:budget:stats:{groupId}
  • Graceful: Works without Redis (cache disabled)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages