src/analytics/analytics.controller.ts
analytics
Methods |
|
| Async exportCsv | |||||||||||||||||||||
exportCsv(from: string, to: string, status: string | undefined, clientId: string | undefined, orgId: string, res: Response)
|
|||||||||||||||||||||
Decorators :
@Get('export/csv')
|
|||||||||||||||||||||
|
Defined in src/analytics/analytics.controller.ts:51
|
|||||||||||||||||||||
|
Parameters :
Returns :
any
|
| Async getAuditLog | |||||||||||||||||||||
getAuditLog(orgId: string, page?: string, limit?: string, entityType?: string, action?: string, userId?: string)
|
|||||||||||||||||||||
Decorators :
@Get('audit-log')
|
|||||||||||||||||||||
|
Defined in src/analytics/analytics.controller.ts:81
|
|||||||||||||||||||||
|
Parameters :
Returns :
unknown
|
| Async getDashboard | ||||||
getDashboard(orgId: string)
|
||||||
Decorators :
@Get('dashboard')
|
||||||
|
Defined in src/analytics/analytics.controller.ts:23
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getReport | ||||||||||||||||||
getReport(type: string, from: string, to: string, clientId: string | undefined, orgId: string)
|
||||||||||||||||||
Decorators :
@Get('report')
|
||||||||||||||||||
|
Defined in src/analytics/analytics.controller.ts:33
|
||||||||||||||||||
|
Parameters :
Returns :
unknown
|
import { Controller, Get, Query, Res, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery } from '@nestjs/swagger';
import { Response } from 'express';
import { AnalyticsService } from './analytics.service';
import { CombinedAuthGuard } from '../auth/guards/combined-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { PrismaService } from '../prisma/prisma.service';
@ApiTags('Analytics')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@Controller('analytics')
export class AnalyticsController {
constructor(
private readonly analyticsService: AnalyticsService,
private readonly prisma: PrismaService,
) {}
@Get('dashboard')
@ApiOperation({ summary: 'Get dashboard KPIs and statistics' })
async getDashboard(@CurrentUser('organizationId') orgId: string) {
return this.analyticsService.getDashboard(orgId);
}
@Get('report')
@ApiOperation({ summary: 'Generate a comprehensive report' })
@ApiQuery({ name: 'type', enum: ['daily', 'weekly', 'monthly', 'client', 'vehicle'], required: true })
@ApiQuery({ name: 'from', required: true, description: 'Start date (ISO string)' })
@ApiQuery({ name: 'to', required: true, description: 'End date (ISO string)' })
@ApiQuery({ name: 'clientId', required: false })
async getReport(
@Query('type') type: string,
@Query('from') from: string,
@Query('to') to: string,
@Query('clientId') clientId: string | undefined,
@CurrentUser('organizationId') orgId: string,
) {
const fromDate = new Date(from);
const toDate = new Date(to);
return this.analyticsService.generateReport(type, fromDate, toDate, clientId, orgId);
}
@Get('export/csv')
@ApiOperation({ summary: 'Export order data as CSV' })
@ApiQuery({ name: 'from', required: true })
@ApiQuery({ name: 'to', required: true })
@ApiQuery({ name: 'status', required: false })
@ApiQuery({ name: 'clientId', required: false })
async exportCsv(
@Query('from') from: string,
@Query('to') to: string,
@Query('status') status: string | undefined,
@Query('clientId') clientId: string | undefined,
@CurrentUser('organizationId') orgId: string,
@Res() res: Response,
) {
const fromDate = new Date(from);
const toDate = new Date(to);
const csv = await this.analyticsService.exportOrdersCsv(
fromDate,
toDate,
{ status, clientId },
orgId,
);
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Content-Disposition', `attachment; filename="orders-export-${from}-to-${to}.csv"`);
res.send(csv);
}
@Get('audit-log')
@UseGuards(CombinedAuthGuard, RolesGuard)
@Roles('SUPER_ADMIN', 'ADMIN')
@ApiOperation({ summary: 'View system audit log — admin only' })
@ApiQuery({ name: 'page', required: false })
@ApiQuery({ name: 'limit', required: false })
@ApiQuery({ name: 'entityType', required: false })
@ApiQuery({ name: 'action', required: false })
@ApiQuery({ name: 'userId', required: false })
async getAuditLog(
@CurrentUser('organizationId') orgId: string,
@Query('page') page?: string,
@Query('limit') limit?: string,
@Query('entityType') entityType?: string,
@Query('action') action?: string,
@Query('userId') userId?: string,
) {
const p = parseInt(page || '1', 10);
const l = Math.min(parseInt(limit || '50', 10), 200);
const skip = (p - 1) * l;
const where: Record<string, unknown> = { organizationId: orgId };
if (entityType) where.entityType = entityType;
if (action) where.action = { contains: action, mode: 'insensitive' };
if (userId) where.userId = userId;
const [items, total] = await Promise.all([
this.prisma.auditLog.findMany({
where: where as any,
skip,
take: l,
orderBy: { createdAt: 'desc' },
include: {
user: { select: { id: true, firstName: true, lastName: true, email: true } },
},
}),
this.prisma.auditLog.count({ where: where as any }),
]);
return {
data: items,
meta: { total, page: p, limit: l, totalPages: Math.ceil(total / l) },
};
}
}