sms count endpoint

This commit is contained in:
2025-12-22 23:37:42 +03:30
parent 4dafba955e
commit 1f96081dff
3 changed files with 79 additions and 0 deletions
@@ -10,6 +10,7 @@ import { UpdatePreferenceDto } from '../dto/update-preference.dto';
import { AdminId } from 'src/common/decorators/admin-id.decorator';
import { API_HEADER_SLUG } from 'src/common/constants/index';
import { NotificationMessage } from 'src/common/enums/message.enum';
import { SuperAdminAuthGuard } from 'src/modules/auth/guards/superAdminAuth.guard';
@ApiTags('notifications')
@Controller()
@@ -149,4 +150,19 @@ export class NotificationsController {
) {
return this.preferenceService.updatePreference(preferenceId, restaurantId, dto);
}
@UseGuards(SuperAdminAuthGuard)
@ApiBearerAuth()
@Get('super-admin/sms-count')
@ApiOperation({ summary: 'Get SMS count for each restaurant with pagination' })
@ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)', minimum: 1 })
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 10)', minimum: 1 })
async getSmsCount(
@Query('page') page?: number,
@Query('limit') limit?: number,
) {
const parsedPage = page ? parseInt(page.toString(), 10) : 1;
const parsedLimit = limit ? parseInt(limit.toString(), 10) : 10;
return await this.notificationService.getSmsCountByRestaurant(parsedPage, parsedLimit);
}
}
@@ -1,11 +1,63 @@
import { Injectable } from '@nestjs/common';
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
import { SmsLog } from '../entities/smsLogs.entity';
import { PaginatedResult } from '../../../common/interfaces/pagination.interface';
@Injectable()
export class SmsLogRepository extends EntityRepository<SmsLog> {
constructor(readonly em: EntityManager) {
super(em, SmsLog);
}
async getSmsCountByRestaurant(
page: number = 1,
limit: number = 10,
): Promise<PaginatedResult<{ restaurantId: string; restaurantName: string; smsCount: number }>> {
const offset = (page - 1) * limit;
// Get total count of unique restaurants with SMS logs
const totalResult = await this.em.execute(
`
SELECT COUNT(DISTINCT sl.restaurant_id) as total
FROM sms_logs sl
WHERE sl.restaurant_id IS NOT NULL
`,
);
const total = parseInt(totalResult[0]?.total || '0', 10);
// Get paginated results with SMS counts grouped by restaurant
const results = await this.em.execute(
`
SELECT
r.id as "restaurantId",
r.name as "restaurantName",
COUNT(sl.id)::int as "smsCount"
FROM sms_logs sl
INNER JOIN restaurants r ON sl.restaurant_id = r.id
GROUP BY r.id, r.name
ORDER BY "smsCount" DESC, r.name ASC
LIMIT ? OFFSET ?
`,
[limit, offset],
);
const data = results.map((row: any) => ({
restaurantId: row.restaurantId,
restaurantName: row.restaurantName || 'Unknown',
smsCount: parseInt(row.smsCount || '0', 10),
}));
const totalPages = Math.ceil(total / limit);
return {
data,
meta: {
total,
page,
limit,
totalPages,
},
};
}
}
@@ -5,6 +5,9 @@ import { NotificationPreferenceService } from './notification-preference.service
import { NotificationQueueService } from './notification-queue.service';
import { NotificationsGateway } from '../notifications.gateway';
import { NotifChannelEnum, NotifRequest, NotifTitleEnum } from '../interfaces/notification.interface';
import { SmsLog } from '../entities/smsLogs.entity';
import { SmsLogRepository } from '../repositories/sms-log.repository';
import { PaginatedResult } from '../../../common/interfaces/pagination.interface';
@Injectable()
export class NotificationService {
@@ -15,6 +18,7 @@ export class NotificationService {
private readonly preferenceService: NotificationPreferenceService,
private readonly queueService: NotificationQueueService,
private readonly notificationGateway: NotificationsGateway,
private readonly smsLogRepository: SmsLogRepository,
) { }
async sendNotification(params: NotifRequest): Promise<Notification[]> {
@@ -263,4 +267,11 @@ export class NotificationService {
};
return this.em.nativeUpdate(Notification, where, { seenAt: new Date() });
}
async getSmsCountByRestaurant(
page: number = 1,
limit: number = 10,
): Promise<PaginatedResult<{ restaurantId: string; restaurantName: string; smsCount: number }>> {
return this.smsLogRepository.getSmsCountByRestaurant(page, limit);
}
}