/** * Usage Controller * * REST API endpoints for usage tracking */ import { Router, Request, Response, NextFunction } from 'express'; import { DataSource } from 'typeorm'; import { UsageTrackingService } from '../services'; import { RecordUsageDto, UpdateUsageDto, IncrementUsageDto, UsageMetrics } from '../dto'; export class UsageController { public router: Router; private service: UsageTrackingService; constructor(dataSource: DataSource) { this.router = Router(); this.service = new UsageTrackingService(dataSource); this.initializeRoutes(); } private initializeRoutes(): void { // Current usage this.router.get('/tenant/:tenantId/current', this.getCurrentUsage.bind(this)); this.router.get('/tenant/:tenantId/summary', this.getUsageSummary.bind(this)); this.router.get('/tenant/:tenantId/limits', this.checkLimits.bind(this)); // Usage history this.router.get('/tenant/:tenantId/history', this.getUsageHistory.bind(this)); this.router.get('/tenant/:tenantId/report', this.getUsageReport.bind(this)); // Record usage this.router.post('/', this.recordUsage.bind(this)); this.router.put('/:id', this.updateUsage.bind(this)); this.router.post('/increment', this.incrementMetric.bind(this)); } /** * GET /usage/tenant/:tenantId/current * Get current usage for tenant */ private async getCurrentUsage(req: Request, res: Response, next: NextFunction): Promise { try { const usage = await this.service.getCurrentUsage(req.params.tenantId); res.json({ data: usage }); } catch (error) { next(error); } } /** * GET /usage/tenant/:tenantId/summary * Get usage summary with limits */ private async getUsageSummary(req: Request, res: Response, next: NextFunction): Promise { try { const summary = await this.service.getUsageSummary(req.params.tenantId); res.json({ data: summary }); } catch (error) { next(error); } } /** * GET /usage/tenant/:tenantId/limits * Check if tenant exceeds limits */ private async checkLimits(req: Request, res: Response, next: NextFunction): Promise { try { const limits = await this.service.checkLimits(req.params.tenantId); res.json({ data: limits }); } catch (error) { next(error); } } /** * GET /usage/tenant/:tenantId/history * Get usage history */ private async getUsageHistory(req: Request, res: Response, next: NextFunction): Promise { try { const { startDate, endDate } = req.query; if (!startDate || !endDate) { res.status(400).json({ error: 'startDate and endDate are required' }); return; } const history = await this.service.getUsageHistory( req.params.tenantId, new Date(startDate as string), new Date(endDate as string) ); res.json({ data: history }); } catch (error) { next(error); } } /** * GET /usage/tenant/:tenantId/report * Get usage report */ private async getUsageReport(req: Request, res: Response, next: NextFunction): Promise { try { const { startDate, endDate, granularity } = req.query; if (!startDate || !endDate) { res.status(400).json({ error: 'startDate and endDate are required' }); return; } const report = await this.service.getUsageReport( req.params.tenantId, new Date(startDate as string), new Date(endDate as string), (granularity as 'daily' | 'weekly' | 'monthly') || 'monthly' ); res.json({ data: report }); } catch (error) { next(error); } } /** * POST /usage * Record usage for period */ private async recordUsage(req: Request, res: Response, next: NextFunction): Promise { try { const dto: RecordUsageDto = req.body; const usage = await this.service.recordUsage(dto); res.status(201).json({ data: usage }); } catch (error) { next(error); } } /** * PUT /usage/:id * Update usage record */ private async updateUsage(req: Request, res: Response, next: NextFunction): Promise { try { const dto: UpdateUsageDto = req.body; const usage = await this.service.update(req.params.id, dto); res.json({ data: usage }); } catch (error) { next(error); } } /** * POST /usage/increment * Increment a specific metric */ private async incrementMetric(req: Request, res: Response, next: NextFunction): Promise { try { const dto: IncrementUsageDto = req.body; await this.service.incrementMetric( dto.tenantId, dto.metric as keyof UsageMetrics, dto.amount || 1 ); res.json({ success: true }); } catch (error) { next(error); } } }