197 lines
7.9 KiB
TypeScript
197 lines
7.9 KiB
TypeScript
import { Controller, Get, Body, Param, UseGuards, Query, Patch, Put, Post } from '@nestjs/common';
|
|
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
|
|
import { NotificationService } from '../services/notification.service';
|
|
import { NotificationPreferenceService } from '../services/notification-preference.service';
|
|
import { AuthGuard } from '../../auth/guards/auth.guard';
|
|
import { UserId } from '../../../common/decorators/user-id.decorator';
|
|
import { AdminAuthGuard } from '../../auth/guards/adminAuth.guard';
|
|
import { RestId } from '../../../common/decorators/rest-id.decorator';
|
|
import { UpdatePreferenceDto } from '../dto/update-preference.dto';
|
|
import { CreatePreferenceDto } from '../dto/create-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';
|
|
import { Permissions } from 'src/common/decorators/permissions.decorator';
|
|
import { Permission } from 'src/common/enums/permission.enum';
|
|
|
|
@ApiTags('notifications')
|
|
@Controller()
|
|
export class NotificationsController {
|
|
constructor(
|
|
private readonly notificationService: NotificationService,
|
|
private readonly preferenceService: NotificationPreferenceService,
|
|
) { }
|
|
|
|
@UseGuards(AuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('public/notifications')
|
|
@ApiOperation({ summary: 'Get user restaurant notifications' })
|
|
|
|
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Number of items to return (default: 50)' })
|
|
@ApiQuery({
|
|
name: 'cursor',
|
|
required: false,
|
|
type: String,
|
|
description: 'Cursor for pagination (ID of the last item from previous page)',
|
|
})
|
|
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
|
async getUserNotifications(
|
|
@UserId() userId: string,
|
|
@RestId() restaurantId: string,
|
|
@Query('limit') limit?: number,
|
|
@Query('cursor') cursor?: string,
|
|
@Query('status') status?: 'seen' | 'unseen',
|
|
) {
|
|
return await this.notificationService.findByUserAndRestaurant(
|
|
userId,
|
|
restaurantId,
|
|
limit ? parseInt(limit.toString(), 10) : 50,
|
|
cursor,
|
|
status,
|
|
);
|
|
}
|
|
|
|
@UseGuards(AuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('public/notifications/unseen-count')
|
|
@ApiOperation({ summary: 'Get unseen notifications count for user' })
|
|
|
|
async getUserUnseenCount(@UserId() userId: string, @RestId() restaurantId: string) {
|
|
const count = await this.notificationService.countUnseenByUserAndRestaurant(userId, restaurantId);
|
|
return { count };
|
|
}
|
|
|
|
@UseGuards(AuthGuard)
|
|
@ApiBearerAuth()
|
|
@Put('public/notifications/:id')
|
|
@ApiOperation({ summary: 'Read a notification ' })
|
|
@ApiParam({ name: 'id', description: 'Notification ID' })
|
|
async readNotificationUser(@RestId() restaurantId: string, @Param('id') id: string, @UserId() userId: string) {
|
|
await this.notificationService.readNotificationAsUser(id, userId, restaurantId);
|
|
return { message: NotificationMessage.READ_SUCCESS };
|
|
}
|
|
|
|
@UseGuards(AuthGuard)
|
|
@ApiBearerAuth()
|
|
@Put('public/notifications/read/all')
|
|
@ApiOperation({ summary: 'Read all notification ' })
|
|
async readAllNotificationUser(@RestId() restaurantId: string, @UserId() userId: string) {
|
|
await this.notificationService.readAllNotifsAsUser(userId, restaurantId);
|
|
return { message: NotificationMessage.READ_SUCCESS };
|
|
}
|
|
/* ***************** Admin Endpoints ***************** */
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('admin/notifications')
|
|
@ApiOperation({ summary: 'Get Admin notifications' })
|
|
@ApiQuery({ name: 'limit', required: false, type: Number })
|
|
@ApiQuery({
|
|
name: 'cursor',
|
|
required: false,
|
|
type: String,
|
|
description: 'Cursor for pagination (ID of the last item from previous page)',
|
|
})
|
|
@ApiQuery({ name: 'status', required: false, enum: ['seen', 'unseen'], description: 'Filter by notification status' })
|
|
async getAdminNotifications(
|
|
@AdminId() adminId: string,
|
|
@RestId() restaurantId: string,
|
|
@Query('limit') limit?: number,
|
|
@Query('cursor') cursor?: string,
|
|
@Query('status') status?: 'seen' | 'unseen',
|
|
) {
|
|
const parsedLimit = limit ? parseInt(limit.toString(), 10) : 50;
|
|
return await this.notificationService.findByRestaurant(restaurantId, adminId, parsedLimit, cursor, status);
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('admin/notifications/unseen-count')
|
|
@ApiOperation({ summary: 'Get unseen notifications count for admin' })
|
|
async getAdminUnseenCount(@AdminId() adminId: string, @RestId() restaurantId: string) {
|
|
const count = await this.notificationService.countUnseenByRestaurant(adminId, restaurantId);
|
|
return { count };
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Put('admin/notifications/:id')
|
|
@ApiOperation({ summary: 'Read a notification ' })
|
|
@ApiParam({ name: 'id', description: 'Notification ID' })
|
|
async readNotificationAdmin(@RestId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
|
await this.notificationService.readNotificationAdmin(id, adminId, restaurantId);
|
|
return { message: NotificationMessage.READ_SUCCESS };
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Put('admin/notifications/read/all')
|
|
@ApiOperation({ summary: 'Read all notification ' })
|
|
async readAllNotificationAdmin(@RestId() restaurantId: string, @AdminId() adminId: string, @Param('id') id: string) {
|
|
await this.notificationService.readAllNotifsAsAdmin(adminId, restaurantId);
|
|
return { message: NotificationMessage.READ_SUCCESS };
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Permissions(Permission.MANAGE_SETTINGS)
|
|
@Get('admin/notification-preferences')
|
|
@ApiOperation({ summary: 'Get all notification preferences for a restaurant' })
|
|
async getPreferences(@RestId() restaurantId: string) {
|
|
return this.preferenceService.findByRestaurant(restaurantId);
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Permissions(Permission.MANAGE_SETTINGS)
|
|
@Patch('admin/notification-preferences/:id')
|
|
@ApiOperation({ summary: 'Update notification channels' })
|
|
@ApiParam({ name: 'id', description: 'Notification preference ID' })
|
|
async updatePreference(
|
|
@RestId() restaurantId: string,
|
|
@Param('id') preferenceId: string,
|
|
@Body() dto: UpdatePreferenceDto,
|
|
) {
|
|
return this.preferenceService.updatePreference(preferenceId, restaurantId, dto);
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Permissions(Permission.MANAGE_SETTINGS)
|
|
@Post('admin/notification-preferences')
|
|
@ApiOperation({ summary: 'Create notification preference' })
|
|
async createPreference(
|
|
@RestId() restaurantId: string,
|
|
@Body() dto: CreatePreferenceDto,
|
|
) {
|
|
return this.preferenceService.create(restaurantId, dto);
|
|
}
|
|
|
|
@UseGuards(AdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('admin/notifications/sms-usage')
|
|
@ApiOperation({ summary: 'Get SMS usage for my restaurant' })
|
|
async getRestaurantSmsUsage(@RestId() restaurantId: string) {
|
|
const smsCount = await this.notificationService.getSmsCountByRestaurantId(restaurantId);
|
|
return { smsCount };
|
|
}
|
|
|
|
// super admin endpoints
|
|
|
|
@UseGuards(SuperAdminAuthGuard)
|
|
@ApiBearerAuth()
|
|
@Get('super-admin/notifications/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);
|
|
}
|
|
}
|