pager
This commit is contained in:
Generated
+34
@@ -13,6 +13,7 @@
|
|||||||
"@as-integrations/fastify": "^3.1.0",
|
"@as-integrations/fastify": "^3.1.0",
|
||||||
"@aws-sdk/client-s3": "^3.922.0",
|
"@aws-sdk/client-s3": "^3.922.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.922.0",
|
"@aws-sdk/s3-request-presigner": "^3.922.0",
|
||||||
|
"@fastify/cookie": "^11.0.2",
|
||||||
"@fastify/multipart": "^9.3.0",
|
"@fastify/multipart": "^9.3.0",
|
||||||
"@fastify/static": "^8.3.0",
|
"@fastify/static": "^8.3.0",
|
||||||
"@keyv/redis": "^5.1.3",
|
"@keyv/redis": "^5.1.3",
|
||||||
@@ -2236,6 +2237,39 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fastify/cookie": {
|
||||||
|
"version": "11.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fastify/cookie/-/cookie-11.0.2.tgz",
|
||||||
|
"integrity": "sha512-GWdwdGlgJxyvNv+QcKiGNevSspMQXncjMZ1J8IvuDQk0jvkzgWWZFNC2En3s+nHndZBGV8IbLwOI/sxCZw/mzA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/fastify"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/fastify"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "^1.0.0",
|
||||||
|
"fastify-plugin": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@fastify/cookie/node_modules/cookie": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@fastify/cors": {
|
"node_modules/@fastify/cors": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.1.0.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
"@as-integrations/fastify": "^3.1.0",
|
"@as-integrations/fastify": "^3.1.0",
|
||||||
"@aws-sdk/client-s3": "^3.922.0",
|
"@aws-sdk/client-s3": "^3.922.0",
|
||||||
"@aws-sdk/s3-request-presigner": "^3.922.0",
|
"@aws-sdk/s3-request-presigner": "^3.922.0",
|
||||||
|
"@fastify/cookie": "^11.0.2",
|
||||||
"@fastify/multipart": "^9.3.0",
|
"@fastify/multipart": "^9.3.0",
|
||||||
"@fastify/static": "^8.3.0",
|
"@fastify/static": "^8.3.0",
|
||||||
"@keyv/redis": "^5.1.3",
|
"@keyv/redis": "^5.1.3",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { CouponModule } from './modules/coupons/coupon.module';
|
|||||||
import { ReviewModule } from './modules/review/review.module';
|
import { ReviewModule } from './modules/review/review.module';
|
||||||
import { NotificationsModule } from './modules/notifications/notifications.module';
|
import { NotificationsModule } from './modules/notifications/notifications.module';
|
||||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||||
|
import { PagerModule } from './modules/pager/pager.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -48,6 +49,7 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
|
|||||||
ReviewModule,
|
ReviewModule,
|
||||||
NotificationsModule,
|
NotificationsModule,
|
||||||
EventEmitterModule.forRoot(),
|
EventEmitterModule.forRoot(),
|
||||||
|
PagerModule,
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [],
|
providers: [],
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { createParamDecorator, type ExecutionContext } from '@nestjs/common';
|
||||||
|
import type { Request } from 'express';
|
||||||
|
|
||||||
|
export const RestSlug = createParamDecorator((data: unknown, ctx: ExecutionContext): string => {
|
||||||
|
const request = ctx.switchToHttp().getRequest<Request & { slug?: string }>();
|
||||||
|
return request.slug || '';
|
||||||
|
});
|
||||||
@@ -4,6 +4,7 @@ import { ConfigService } from '@nestjs/config';
|
|||||||
import { Logger, ValidationPipe } from '@nestjs/common';
|
import { Logger, ValidationPipe } from '@nestjs/common';
|
||||||
import { getSwaggerConfig } from './config/swagger.config';
|
import { getSwaggerConfig } from './config/swagger.config';
|
||||||
import multipart from '@fastify/multipart';
|
import multipart from '@fastify/multipart';
|
||||||
|
import fastifyCookie from '@fastify/cookie';
|
||||||
|
|
||||||
// 👈 Import the Fastify application type
|
// 👈 Import the Fastify application type
|
||||||
import { type NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
|
import { type NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
|
||||||
@@ -22,6 +23,8 @@ async function bootstrap() {
|
|||||||
{ logger: ['error', 'warn', 'log', 'debug', 'verbose'] },
|
{ logger: ['error', 'warn', 'log', 'debug', 'verbose'] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await app.register(fastifyCookie);
|
||||||
|
|
||||||
await app.register(multipart);
|
await app.register(multipart);
|
||||||
app.useGlobalPipes(new ValidationPipe());
|
app.useGlobalPipes(new ValidationPipe());
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ export class AuthGuard implements CanActivate {
|
|||||||
return type === 'Bearer' ? token : undefined;
|
return type === 'Bearer' ? token : undefined;
|
||||||
}
|
}
|
||||||
private extractSlugFromHeader(request: Request): string | undefined {
|
private extractSlugFromHeader(request: Request): string | undefined {
|
||||||
const slug = request.headers['X-Slug'] as string;
|
// Fastify normalizes headers to lowercase, so check both cases
|
||||||
|
const slug = (request.headers['x-slug'] || request.headers['X-Slug']) as string;
|
||||||
return slug;
|
return slug;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { CanActivate, ExecutionContext, Injectable, Inject, Logger } from '@nestjs/common';
|
||||||
|
import { Request } from 'express';
|
||||||
|
import { JwtService } from '@nestjs/jwt';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { ITokenPayload } from '../interfaces/IToken-payload';
|
||||||
|
|
||||||
|
export interface UserOptionalAuthRequest extends Request {
|
||||||
|
userId?: string;
|
||||||
|
restId?: string;
|
||||||
|
slug?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class OptionalAuthGuard implements CanActivate {
|
||||||
|
private readonly logger = new Logger(OptionalAuthGuard.name);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(JwtService)
|
||||||
|
private readonly jwtService: JwtService,
|
||||||
|
@Inject(ConfigService)
|
||||||
|
private readonly configService: ConfigService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
|
const request = context.switchToHttp().getRequest<UserOptionalAuthRequest>();
|
||||||
|
const token = this.extractTokenFromHeader(request);
|
||||||
|
const slug = this.extractSlugFromHeader(request);
|
||||||
|
|
||||||
|
// If no token is provided, allow the request without authentication
|
||||||
|
if (!slug) {
|
||||||
|
console.log('No slug provided');
|
||||||
|
this.logger.warn('No slug provided');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!token) {
|
||||||
|
request['slug'] = slug;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to verify the token if it exists
|
||||||
|
try {
|
||||||
|
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
||||||
|
const payload = await this.jwtService.verifyAsync<ITokenPayload>(token, {
|
||||||
|
secret,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Validate payload structure
|
||||||
|
if (!payload.userId || !payload.restId) {
|
||||||
|
this.logger.warn('Invalid token payload structure', payload);
|
||||||
|
// Allow request but don't set user info
|
||||||
|
request['slug'] = slug;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate slug if provided
|
||||||
|
if (slug && payload.slug !== slug) {
|
||||||
|
this.logger.warn('Token slug does not match header slug', {
|
||||||
|
tokenSlug: payload.slug,
|
||||||
|
headerSlug: slug,
|
||||||
|
});
|
||||||
|
// Allow request but don't set user info
|
||||||
|
request['slug'] = slug;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token is valid, set user info
|
||||||
|
request['userId'] = payload.userId;
|
||||||
|
request['restId'] = payload.restId;
|
||||||
|
request['slug'] = slug;
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
// Token is invalid or expired, but allow the request anyway
|
||||||
|
this.logger.debug('Token verification failed in OptionalAuthGuard', {
|
||||||
|
error: err instanceof Error ? err.message : 'Unknown error',
|
||||||
|
});
|
||||||
|
// Set restId from slug
|
||||||
|
|
||||||
|
request['slug'] = slug;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractTokenFromHeader(request: Request): string | undefined {
|
||||||
|
const [type, token] = request.headers.authorization?.split(' ') ?? [];
|
||||||
|
return type === 'Bearer' ? token : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractSlugFromHeader(request: Request): string | undefined {
|
||||||
|
// Fastify normalizes headers to lowercase, so check both cases
|
||||||
|
const slug = (request.headers['x-slug'] || request.headers['X-Slug']) as string;
|
||||||
|
return slug;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class CreatePagerDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
@ApiProperty({ description: 'Table number' })
|
||||||
|
tableNumber!: string;
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiPropertyOptional({ description: 'Message' })
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||||
|
import { PagerStatus } from '../interface/pager';
|
||||||
|
|
||||||
|
export class UpdatePagerStatusDto {
|
||||||
|
@ApiProperty({ description: 'Status of the pager', enum: PagerStatus })
|
||||||
|
@IsEnum(PagerStatus)
|
||||||
|
@IsNotEmpty()
|
||||||
|
status!: PagerStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { Entity, ManyToOne, Property, Enum } from '@mikro-orm/core';
|
||||||
|
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||||
|
import { User } from '../../users/entities/user.entity';
|
||||||
|
import { Restaurant } from '../../restaurants/entities/restaurant.entity';
|
||||||
|
import { PagerStatus } from '../interface/pager';
|
||||||
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
|
|
||||||
|
@Entity({ tableName: 'pagers' })
|
||||||
|
export class Pager extends BaseEntity {
|
||||||
|
@Property({ type: 'string' })
|
||||||
|
cookieId!: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Restaurant)
|
||||||
|
restaurant!: Restaurant;
|
||||||
|
|
||||||
|
@Property({ type: 'string' })
|
||||||
|
tableNumber!: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { nullable: true })
|
||||||
|
user?: User;
|
||||||
|
|
||||||
|
@ManyToOne(() => Admin, { nullable: true })
|
||||||
|
staff?: Admin;
|
||||||
|
|
||||||
|
@Property({ type: 'string', nullable: true })
|
||||||
|
message?: string;
|
||||||
|
|
||||||
|
@Enum(() => PagerStatus)
|
||||||
|
status: PagerStatus = PagerStatus.Pending;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export enum PagerStatus {
|
||||||
|
Pending = 'pending',
|
||||||
|
Acknowledged = 'acknowledged',
|
||||||
|
Rejected = 'rejected',
|
||||||
|
Completed = 'completed',
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import { Controller, Get, Post, Body, UseGuards, Res, Req, Patch, Param } from '@nestjs/common';
|
||||||
|
import { PagerService } from './pager.service';
|
||||||
|
import { CreatePagerDto } from './dto/create-pager.dto';
|
||||||
|
import { OptionalAuthGuard } from '../auth/guards/optinalAuth.guard';
|
||||||
|
import { RestId } from 'src/common/decorators/rest-id.decorator';
|
||||||
|
import { UserId } from 'src/common/decorators/user-id.decorator';
|
||||||
|
import { RestSlug } from 'src/common/decorators/rest-slug.decorator';
|
||||||
|
import { ApiTags, ApiOperation, ApiBody, ApiHeader, ApiBearerAuth, ApiParam } from '@nestjs/swagger';
|
||||||
|
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
|
import { AdminAuthGuard } from '../auth/guards/adminAuth.guard';
|
||||||
|
import { AdminId } from 'src/common/decorators/admin-id.decorator';
|
||||||
|
import { UpdatePagerStatusDto } from './dto/update-pager.dto';
|
||||||
|
|
||||||
|
@ApiTags('pager')
|
||||||
|
@Controller()
|
||||||
|
export class PagerController {
|
||||||
|
constructor(private readonly pagerService: PagerService) {}
|
||||||
|
|
||||||
|
@UseGuards(OptionalAuthGuard)
|
||||||
|
@Post('public/pager')
|
||||||
|
@ApiOperation({ summary: 'Create a new pager request' })
|
||||||
|
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier' })
|
||||||
|
@ApiHeader({ name: 'Authorization', required: false, description: 'Bearer token (optional authentication)' })
|
||||||
|
@ApiBody({ type: CreatePagerDto })
|
||||||
|
async create(
|
||||||
|
@Body() createPagerDto: CreatePagerDto,
|
||||||
|
@Res() reply: FastifyReply,
|
||||||
|
@RestSlug() slug: string,
|
||||||
|
@RestId() restId?: string,
|
||||||
|
@UserId() userId?: string,
|
||||||
|
) {
|
||||||
|
// Convert empty strings to undefined for cleaner validation
|
||||||
|
const normalizedRestId = restId || undefined;
|
||||||
|
const normalizedUserId = userId || undefined;
|
||||||
|
|
||||||
|
const pager = await this.pagerService.create(createPagerDto, {
|
||||||
|
restId: normalizedRestId,
|
||||||
|
userId: normalizedUserId,
|
||||||
|
slug,
|
||||||
|
});
|
||||||
|
reply.setCookie('pagerId', pager.cookieId, {
|
||||||
|
httpOnly: true,
|
||||||
|
secure: process.env.NODE_ENV === 'production',
|
||||||
|
maxAge: 1000 * 60 * 60 * 24 * 1, // 1 days
|
||||||
|
path: '/',
|
||||||
|
});
|
||||||
|
return reply.code(200).send({
|
||||||
|
success: true,
|
||||||
|
message: 'Pager request created successfully',
|
||||||
|
data: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(OptionalAuthGuard)
|
||||||
|
@Get('public/pager')
|
||||||
|
@ApiOperation({ summary: 'Get all pager requests for the current session' })
|
||||||
|
@ApiHeader({ name: 'X-Slug', required: true, description: 'Restaurant slug identifier' })
|
||||||
|
@ApiHeader({ name: 'Authorization', required: false, description: 'Bearer token (optional authentication)' })
|
||||||
|
async findAll(@Req() request: FastifyRequest) {
|
||||||
|
const cookieId = request.cookies['pagerId'] || undefined;
|
||||||
|
if (!cookieId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.pagerService.findAll(cookieId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(AdminAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@Get('admin/pager')
|
||||||
|
@ApiOperation({ summary: 'Get all pager requests for the restaurant' })
|
||||||
|
async findAllAdmin(@RestId() restId: string) {
|
||||||
|
return this.pagerService.findAllByRestaurantId(restId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(AdminAuthGuard)
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@Patch('admin/pager/:pagerId/status')
|
||||||
|
@ApiParam({ name: 'pagerId', required: true, type: String })
|
||||||
|
@ApiOperation({ summary: 'Update the status of a pager request' })
|
||||||
|
@ApiBody({ type: UpdatePagerStatusDto })
|
||||||
|
async updateStatus(
|
||||||
|
@Param('pagerId') pagerId: string,
|
||||||
|
@RestId() restId: string,
|
||||||
|
@AdminId() adminId: string,
|
||||||
|
@Body() dto: UpdatePagerStatusDto,
|
||||||
|
) {
|
||||||
|
return this.pagerService.updateStatus(pagerId, restId, adminId, dto.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { PagerService } from './pager.service';
|
||||||
|
import { PagerController } from './pager.controller';
|
||||||
|
import { MikroOrmModule } from '@mikro-orm/nestjs';
|
||||||
|
import { Pager } from './entities/pager.entity';
|
||||||
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
|
import { RolesModule } from '../roles/roles.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [MikroOrmModule.forFeature([Pager]), JwtModule, RolesModule],
|
||||||
|
controllers: [PagerController],
|
||||||
|
providers: [PagerService],
|
||||||
|
})
|
||||||
|
export class PagerModule {}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { CreatePagerDto } from './dto/create-pager.dto';
|
||||||
|
import { User } from '../users/entities/user.entity';
|
||||||
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
|
import { Restaurant } from '../restaurants/entities/restaurant.entity';
|
||||||
|
import { Pager } from './entities/pager.entity';
|
||||||
|
import { PagerStatus } from './interface/pager';
|
||||||
|
import { ulid } from 'ulid';
|
||||||
|
import { Admin } from '../admin/entities/admin.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PagerService {
|
||||||
|
constructor(private readonly em: EntityManager) {}
|
||||||
|
|
||||||
|
async create(createPagerDto: CreatePagerDto, params: { restId?: string; userId?: string; slug: string }) {
|
||||||
|
const { restId, userId, slug } = params;
|
||||||
|
let restaurant: Restaurant | null = null;
|
||||||
|
let user: User | null = null;
|
||||||
|
if (!restId && !userId && !slug) {
|
||||||
|
throw new BadRequestException('Invalid parameters');
|
||||||
|
}
|
||||||
|
if (restId) {
|
||||||
|
restaurant = await this.em.findOne(Restaurant, { id: restId });
|
||||||
|
if (!restaurant) {
|
||||||
|
throw new NotFoundException('Restaurant not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (userId) {
|
||||||
|
user = await this.em.findOne(User, { id: userId });
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundException('User not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!restaurant && slug) {
|
||||||
|
restaurant = await this.em.findOne(Restaurant, { slug });
|
||||||
|
if (!restaurant) {
|
||||||
|
throw new NotFoundException('Restaurant not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pager = this.em.create(Pager, {
|
||||||
|
...createPagerDto,
|
||||||
|
restaurant: restaurant!,
|
||||||
|
user,
|
||||||
|
cookieId: ulid().toString(),
|
||||||
|
status: PagerStatus.Pending,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.em.persistAndFlush(pager);
|
||||||
|
return pager;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll(cookieId: string) {
|
||||||
|
const pagers = await this.em.find(Pager, { cookieId }, { populate: ['user'] });
|
||||||
|
return pagers;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAllByRestaurantId(restId: string) {
|
||||||
|
const pagers = await this.em.find(Pager, { restaurant: { id: restId } }, { populate: ['user'] });
|
||||||
|
return pagers;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateStatus(pagerId: string, restId: string, staffId: string, status: PagerStatus) {
|
||||||
|
const pager = await this.em.findOne(Pager, { id: pagerId, restaurant: { id: restId } });
|
||||||
|
if (!pager) {
|
||||||
|
throw new NotFoundException('Pager not found *');
|
||||||
|
}
|
||||||
|
const staff = await this.em.findOne(Admin, { id: staffId });
|
||||||
|
if (!staff) {
|
||||||
|
throw new NotFoundException('Staff not found');
|
||||||
|
}
|
||||||
|
pager.status = status;
|
||||||
|
if (status === PagerStatus.Acknowledged) {
|
||||||
|
pager.staff = staff;
|
||||||
|
}
|
||||||
|
await this.em.persistAndFlush(pager);
|
||||||
|
return pager;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user