Skip to content

Commit 0e66f16

Browse files
kelvinsbfilipepacheco
authored andcommitted
feat: only show contact on shelter public routes on authorized roles
1 parent 2849b54 commit 0e66f16

File tree

4 files changed

+77
-203
lines changed

4 files changed

+77
-203
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { UserDecorator } from './user.decorator';
2+
3+
export { UserDecorator };

src/guards/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ async function isRightSessionRole(
4141
return false;
4242
}
4343

44-
export { canActivate };
44+
export { canActivate, isRightSessionRole };

src/shelter/shelter.controller.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { ApiTags } from '@nestjs/swagger';
1515
import { ShelterService } from './shelter.service';
1616
import { ServerResponse } from '../utils';
1717
import { StaffGuard } from '@/guards/staff.guard';
18+
import { ApplyUser } from '@/guards/apply-user.guard';
19+
import { UserDecorator } from '@/decorators/UserDecorator';
1820

1921
@ApiTags('Abrigos')
2022
@Controller('shelters')
@@ -35,9 +37,10 @@ export class ShelterController {
3537
}
3638

3739
@Get(':id')
38-
async show(@Param('id') id: string) {
40+
@UseGuards(ApplyUser)
41+
async show(@UserDecorator() user: any, @Param('id') id: string) {
3942
try {
40-
const data = await this.shelterService.show(id);
43+
const data = await this.shelterService.show(id, user);
4144
return new ServerResponse(200, 'Successfully get shelter', data);
4245
} catch (err: any) {
4346
this.logger.error(`Failed to get shelter: ${err}`);

src/shelter/shelter.service.ts

Lines changed: 68 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
import { z } from 'zod';
22
import { Injectable } from '@nestjs/common';
3-
import { Prisma } from '@prisma/client';
3+
import * as qs from 'qs';
4+
import { Prisma, AccessLevel } from '@prisma/client';
45
import { DefaultArgs } from '@prisma/client/runtime/library';
6+
57
import { PrismaService } from '../prisma/prisma.service';
68
import {
7-
ComplexSearchSchema,
89
CreateShelterSchema,
910
FullUpdateShelterSchema,
1011
UpdateShelterSchema,
11-
} from './types';
12-
import { SeachQueryProps } from '@/decorators/search-query/types';
13-
import { SupplyPriority } from 'src/supply/types';
12+
} from './types/types';
13+
import { SearchSchema } from '../types';
14+
import { ShelterSearch, parseTagResponse } from './ShelterSearch';
15+
import { SupplyPriority } from '../supply/types';
16+
import { IFilterFormProps } from './types/search.types';
17+
import { isRightSessionRole } from '@/guards/utils';
1418

1519
@Injectable()
1620
export class ShelterService {
17-
constructor(private readonly prismaService: PrismaService) {}
21+
private voluntaryIds: string[] = [];
22+
23+
constructor(private readonly prismaService: PrismaService) {
24+
this.loadVoluntaryIds();
25+
}
1826

1927
async store(body: z.infer<typeof CreateShelterSchema>) {
2028
const payload = CreateShelterSchema.parse(body);
@@ -53,7 +61,13 @@ export class ShelterService {
5361
});
5462
}
5563

56-
async show(id: string) {
64+
async show(id: string, user: any) {
65+
const isLogged = await isRightSessionRole(
66+
[AccessLevel.User, AccessLevel.Staff],
67+
user?.sessionId,
68+
user?.userId,
69+
);
70+
5771
const data = await this.prismaService.shelter.findFirst({
5872
where: {
5973
id,
@@ -65,7 +79,7 @@ export class ShelterService {
6579
pix: true,
6680
shelteredPeople: true,
6781
capacity: true,
68-
contact: true,
82+
contact: isLogged,
6983
petFriendly: true,
7084
prioritySum: true,
7185
latitude: true,
@@ -74,6 +88,7 @@ export class ShelterService {
7488
shelterSupplies: {
7589
select: {
7690
priority: true,
91+
quantity: true,
7792
supply: {
7893
select: {
7994
id: true,
@@ -99,229 +114,82 @@ export class ShelterService {
99114
return data;
100115
}
101116

102-
async index(props: SeachQueryProps) {
103-
const { handleSearch } = props;
104-
105-
return await handleSearch<Prisma.ShelterSelect<DefaultArgs>>(
106-
this.prismaService.shelter,
107-
{
108-
select: {
109-
id: true,
110-
name: true,
111-
pix: true,
112-
address: true,
113-
capacity: true,
114-
contact: true,
115-
petFriendly: true,
116-
shelteredPeople: true,
117-
prioritySum: true,
118-
verified: true,
119-
latitude: true,
120-
longitude: true,
121-
createdAt: true,
122-
updatedAt: true,
123-
shelterSupplies: {
124-
where: {
125-
priority: {
126-
gt: SupplyPriority.UnderControl,
127-
},
128-
},
129-
select: {
130-
priority: true,
131-
supply: {
132-
select: {
133-
id: true,
134-
name: true,
135-
supplyCategory: {
136-
select: {
137-
id: true,
138-
name: true,
139-
},
140-
},
141-
createdAt: true,
142-
updatedAt: true,
143-
},
144-
},
145-
},
146-
},
147-
},
148-
},
149-
);
150-
}
151-
152-
async search(props: z.infer<typeof ComplexSearchSchema>) {
153-
const payload = ComplexSearchSchema.parse({
154-
...props,
155-
supplyCategories:
156-
typeof props['supplyCategories[]'] === 'string'
157-
? [props['supplyCategories[]']]
158-
: props['supplyCategories[]'],
159-
supplies:
160-
typeof props['supplies[]'] === 'string'
161-
? [props['supplies[]']]
162-
: props['supplies[]'],
163-
});
164-
165-
const shelterStatusFilter = this.addShelterStatusFilter(payload);
166-
const where = this.mountWhereFilter(payload);
167-
const take = payload.perPage;
168-
const skip = payload.perPage * (payload.page - 1);
169-
170-
if (shelterStatusFilter.length > 0) {
171-
where['AND'].push({
172-
OR: shelterStatusFilter,
173-
});
174-
}
175-
176-
const count = await this.prismaService.shelter.count({
177-
where: where,
178-
});
179-
180-
const results = await this.prismaService.shelter.findMany({
181-
where: where,
182-
orderBy: {
183-
prioritySum: 'desc',
184-
},
117+
async index(query: any) {
118+
const {
119+
order,
120+
orderBy,
121+
page,
122+
perPage,
123+
search: searchQuery,
124+
} = SearchSchema.parse(query);
125+
const queryData = qs.parse(searchQuery) as unknown as IFilterFormProps;
126+
const { query: where } = new ShelterSearch(this.prismaService, queryData);
127+
const count = await this.prismaService.shelter.count({ where });
128+
129+
const take = perPage;
130+
const skip = perPage * (page - 1);
131+
132+
const whereData: Prisma.ShelterFindManyArgs<DefaultArgs> = {
185133
take,
186134
skip,
135+
orderBy: { [orderBy]: order },
136+
where,
137+
};
138+
139+
const results = await this.prismaService.shelter.findMany({
140+
...whereData,
187141
select: {
188142
id: true,
189143
name: true,
190144
pix: true,
191145
address: true,
192146
capacity: true,
193147
contact: true,
194-
verified: true,
195148
petFriendly: true,
196149
shelteredPeople: true,
197150
prioritySum: true,
151+
verified: true,
198152
latitude: true,
199153
longitude: true,
200154
createdAt: true,
201155
updatedAt: true,
202156
shelterSupplies: {
203157
where: {
204158
priority: {
205-
gt: SupplyPriority.UnderControl,
159+
notIn: [SupplyPriority.UnderControl],
206160
},
207161
},
208-
select: {
209-
priority: true,
210-
supply: {
211-
select: {
212-
id: true,
213-
name: true,
214-
supplyCategory: {
215-
select: {
216-
id: true,
217-
name: true,
218-
},
219-
},
220-
createdAt: true,
221-
updatedAt: true,
222-
},
223-
},
162+
orderBy: {
163+
updatedAt: 'desc',
164+
},
165+
include: {
166+
supply: true,
224167
},
225168
},
226169
},
227170
});
228-
return { perPage: payload.perPage, page: payload.page, count, results };
229-
}
230171

231-
private mountWhereFilter(payload: z.infer<typeof ComplexSearchSchema>) {
232-
const filter: any = {
233-
AND: [
234-
{
235-
OR: [
236-
{ address: { contains: payload.search, mode: 'insensitive' } },
237-
{ name: { contains: payload.search, mode: 'insensitive' } },
238-
],
239-
},
240-
],
241-
};
172+
const parsed = parseTagResponse(queryData, results, this.voluntaryIds);
242173

243-
const shelterSuppliesFilter = {
244-
shelterSupplies: {
245-
some: {},
246-
},
174+
return {
175+
page,
176+
perPage,
177+
count,
178+
results: parsed,
247179
};
248-
249-
if (payload.priority) {
250-
shelterSuppliesFilter.shelterSupplies.some['priority'] = parseInt(
251-
payload.priority,
252-
);
253-
}
254-
255-
if (payload?.supplyCategories && payload?.supplyCategories.length !== 0) {
256-
shelterSuppliesFilter.shelterSupplies.some['supply'] = {
257-
supplyCategoryId: {
258-
in: payload.supplyCategories,
259-
},
260-
};
261-
}
262-
263-
if (payload?.supplies && payload?.supplies.length !== 0) {
264-
shelterSuppliesFilter.shelterSupplies.some['supplyId'] = {
265-
in: payload.supplies,
266-
};
267-
}
268-
269-
if (Object.keys(shelterSuppliesFilter.shelterSupplies.some).length !== 0) {
270-
filter['AND'].push(shelterSuppliesFilter);
271-
}
272-
273-
return filter;
274180
}
275181

276-
private addShelterStatusFilter(payload: z.infer<typeof ComplexSearchSchema>) {
277-
const shelterStatusFilter: any = [];
278-
279-
if (payload.filterAvailableShelter) {
280-
shelterStatusFilter.push({
281-
AND: [
282-
{
283-
capacity: {
284-
gt: this.prismaService.shelter.fields.shelteredPeople,
285-
},
182+
loadVoluntaryIds() {
183+
this.prismaService.supplyCategory
184+
.findMany({
185+
where: {
186+
name: {
187+
in: ['Especialistas e Profissionais', 'Voluntariado'],
286188
},
287-
{
288-
capacity: { not: null },
289-
},
290-
{
291-
shelteredPeople: { not: null },
292-
},
293-
],
294-
});
295-
}
296-
297-
if (payload.filterUnavailableShelter) {
298-
shelterStatusFilter.push({
299-
AND: [
300-
{
301-
capacity: {
302-
lte: this.prismaService.shelter.fields.shelteredPeople,
303-
},
304-
},
305-
{
306-
capacity: { not: null },
307-
},
308-
{
309-
shelteredPeople: { not: null },
310-
},
311-
],
312-
});
313-
}
314-
315-
if (payload.waitingShelterAvailability) {
316-
shelterStatusFilter.push({
317-
capacity: null,
318-
});
319-
320-
shelterStatusFilter.push({
321-
shelteredPeople: null,
189+
},
190+
})
191+
.then((resp) => {
192+
this.voluntaryIds.push(...resp.map((s) => s.id));
322193
});
323-
}
324-
325-
return shelterStatusFilter;
326194
}
327195
}

0 commit comments

Comments
 (0)