Skip to content

Commit e639f2c

Browse files
committed
feat(exercises): ⚡ added search query on exercises endpoint
added feature for getting the exercise based on bodypart, exercise name, muscles name, equipment
1 parent 2016e16 commit e639f2c

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

src/infra/mongodb/models/exercises/exercise.schema.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,22 @@ const exerciseSchema = new mongoose.Schema<IExerciseDoc, IExerciseModel>(
3030
],
3131
targetMuscles: [
3232
{
33-
type: String,
34-
index: true
33+
type: String
3534
}
3635
],
3736
bodyParts: [
3837
{
39-
type: String,
40-
index: true
38+
type: String
4139
}
4240
],
4341
equipments: [
4442
{
45-
type: String,
46-
index: true
43+
type: String
4744
}
4845
],
4946
secondaryMuscles: [
5047
{
51-
type: String,
52-
index: true
48+
type: String
5349
}
5450
]
5551
},
@@ -59,7 +55,13 @@ const exerciseSchema = new mongoose.Schema<IExerciseDoc, IExerciseModel>(
5955
)
6056

6157
exerciseSchema.plugin(toJSONWithoutId)
62-
58+
exerciseSchema.index({
59+
name: 'text',
60+
targetMuscles: 'text',
61+
bodyParts: 'text',
62+
equipments: 'text',
63+
secondaryMuscles: 'text'
64+
})
6365
/**
6466
* check if the similar equipment name already exists
6567
* @param {string} name

src/modules/exercises/controllers/exercise.controller.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,29 @@ export class ExerciseController implements Routes {
152152
tags: ['Exercises'],
153153
summary: 'Retrive all exercises.',
154154
description: 'Retrive list of all the exercises.',
155-
operationId: 'getMuscles',
155+
operationId: 'getExercises',
156156
request: {
157157
query: z.object({
158+
search: z.string().optional().openapi({
159+
title: 'Search Query',
160+
description:
161+
'A string to filter exercises based on a search term. This can be used to find specific exercises by name or description.',
162+
type: 'string',
163+
example: 'cardio',
164+
default: ''
165+
}),
158166
offset: z.coerce.number().nonnegative().optional().openapi({
159-
title: '',
160-
description: 'Number of exercises to skip',
167+
title: 'Offset',
168+
description:
169+
'The number of exercises to skip from the start of the list. Useful for pagination to fetch subsequent pages of results.',
161170
type: 'number',
162171
example: 10,
163172
default: 0
164173
}),
165174
limit: z.coerce.number().positive().max(100).optional().openapi({
166-
title: '',
167-
description: 'Maximum number of exercises to return',
175+
title: 'Limit',
176+
description:
177+
'The maximum number of exercises to return in the response. Limits the number of results for pagination purposes.',
168178
maximum: 100,
169179
minimum: 1,
170180
type: 'number',
@@ -197,9 +207,9 @@ export class ExerciseController implements Routes {
197207
}
198208
}),
199209
async (ctx) => {
200-
const { offset, limit = 10 } = ctx.req.valid('query')
210+
const { offset, limit = 10, search } = ctx.req.valid('query')
201211
const { origin, pathname } = new URL(ctx.req.url)
202-
const response = await this.exerciseService.getExercise({ offset, limit })
212+
const response = await this.exerciseService.getExercise({ offset, limit, search })
203213
return ctx.json({
204214
success: true,
205215
data: {

src/modules/exercises/use-cases/get-exercises/get-exercise.usecase.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { IExerciseDoc, IExerciseModel } from '#infra/mongodb/models/exercises/ex
44
export interface GetExerciseArgs {
55
offset?: number
66
limit?: number
7+
search?: string
78
}
89

910
export interface GetExerciseReturnArgs {
@@ -15,14 +16,16 @@ export interface GetExerciseReturnArgs {
1516
export class GetExercisesUseCase implements IUseCase<GetExerciseArgs, GetExerciseReturnArgs> {
1617
constructor(private readonly exerciseModel: IExerciseModel) {}
1718

18-
async execute({ offset, limit }: GetExerciseArgs): Promise<GetExerciseReturnArgs> {
19+
async execute({ offset, limit, search }: GetExerciseArgs): Promise<GetExerciseReturnArgs> {
1920
try {
2021
const safeOffset = Math.max(0, Number(offset) || 0)
2122
const safeLimit = Math.max(1, Math.min(100, Number(limit) || 10))
23+
const searchQuery = search ? { $text: { $search: search } } : {}
24+
2225
const totalCounts = await this.exerciseModel.countDocuments()
2326
const totalPages = Math.ceil(totalCounts / safeLimit)
2427
const currentPage = Math.floor(safeOffset / safeLimit) + 1
25-
const result = await this.exerciseModel.find({}).skip(safeOffset).limit(safeLimit).exec()
28+
const result = await this.exerciseModel.find(searchQuery).skip(safeOffset).limit(safeLimit).exec()
2629

2730
return {
2831
totalPages,

0 commit comments

Comments
 (0)