- Add modules: ai, audit, billing-usage, biometrics, branches, dashboard, feature-flags, invoices, mcp, mobile, notifications, partners, payment-terminals, products, profiles, purchases, reports, sales, storage, warehouses, webhooks, whatsapp - Add controllers, DTOs, entities, and services for each module - Add shared services and utilities Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
174 lines
4.7 KiB
TypeScript
174 lines
4.7 KiB
TypeScript
/**
|
|
* 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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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);
|
|
}
|
|
}
|
|
}
|