Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/supply/supply.controller.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {
Body,
Controller,
DefaultValuePipe,
Get,
HttpException,
Logger,
Param,
ParseIntPipe,
Post,
Put,
Query,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';

Expand All @@ -31,6 +34,21 @@ export class SupplyController {
}
}

@Get('top')
async top(
@Query('perPage', new DefaultValuePipe(10), ParseIntPipe) perPage: number,
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
@Query('shelterId') shelterId: string,
) {
try {
const data = await this.supplyServices.top({ perPage, page, shelterId });
return new ServerResponse(200, 'Successfully get top supplies', data);
} catch (err: any) {
this.logger.error(`Failed to get supplies: ${err}`);
throw new HttpException(err?.code ?? err?.name ?? `${err}`, 400);
}
}

@Post('')
async store(@Body() body) {
try {
Expand Down
28 changes: 26 additions & 2 deletions src/supply/supply.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import z from 'zod';
import { Injectable } from '@nestjs/common';

import { Prisma } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { CreateSupplySchema, UpdateSupplySchema } from './types';
import {
CreateSupplySchema,
SupplySearchSchema,
UpdateSupplySchema,
} from './types';

@Injectable()
export class SupplyService {
Expand Down Expand Up @@ -53,4 +57,24 @@ export class SupplyService {

return data;
}

async top(body: z.infer<typeof SupplySearchSchema>) {
const payload = SupplySearchSchema.parse(body);
const take = payload.perPage;
const skip = payload.perPage * (payload.page - 1);

const query = Prisma.sql`SELECT name, count(*)::int as amount
FROM shelter_supplies
LEFT JOIN supplies ON shelter_supplies.supply_id = supplies.id
${
payload.shelterId
? Prisma.sql`WHERE shelter_id = ${payload.shelterId}`
: Prisma.empty
}
GROUP BY name
ORDER BY amount DESC
LIMIT ${take} OFFSET ${skip}`;

return await this.prismaService.$queryRaw(query);
}
}
17 changes: 16 additions & 1 deletion src/supply/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ const SupplySchema = z.object({
updatedAt: z.string().nullable().optional(),
});

const SupplySearchSchema = z.object({
shelterId: z.string().nullable().optional(),
page: z.preprocess((v) => +((v ?? '1') as string), z.number().min(1)),
perPage: z.preprocess(
(v) => +((v ?? '10') as string),
z.number().min(1).max(100),
),
});

const CreateSupplySchema = SupplySchema.omit({
id: true,
createdAt: true,
Expand All @@ -27,4 +36,10 @@ const UpdateSupplySchema = SupplySchema.pick({
supplyCategoryId: true,
}).partial();

export { SupplySchema, CreateSupplySchema, UpdateSupplySchema, SupplyPriority };
export {
SupplySchema,
SupplySearchSchema,
CreateSupplySchema,
UpdateSupplySchema,
SupplyPriority,
};