Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Добавление нового синтаксиса запросов, улучшение документации, добавление новых данных и полей #162

Merged
merged 92 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
c4ca8f2
refactor(app.module.ts): simplify imports array in AppModule
mdwitr0 Sep 6, 2023
3ee2572
chore(pipes): remove unused parse-dot-notation-query.pipe.ts and pars…
mdwitr0 Sep 7, 2023
372fc78
feat(season): add support for versioned season DTOs
mdwitr0 Sep 7, 2023
4568ded
chore(paginated.decorator.ts): add additional fields to the entitiesF…
mdwitr0 Sep 7, 2023
8086ffa
Merge pull request #140 from mdwitr0/issues/139
mdwitr0 Sep 7, 2023
bbdfe33
chore(package.json): update readmeio package to version 6.2.0
mdwitr0 Sep 7, 2023
5f4a814
refactor(movie.dto.ts): reorganize imports and remove unused imports
mdwitr0 Sep 7, 2023
79a7d82
fix: don't updated movie and persons in meilisearch
mdwitr0 Sep 14, 2023
a72762d
Merge pull request #144 from mdwitr0/issues/142
mdwitr0 Sep 14, 2023
4a24cb3
feat(paginated.decorator.ts): add support for including specific fiel…
mdwitr0 Sep 20, 2023
8cf2823
Merge pull request #145 from mdwitr0/issues/135
mdwitr0 Sep 20, 2023
4b1e4f6
feat: add isSeries to movie search
mdwitr0 Sep 21, 2023
b9653fa
Merge pull request #146 from mdwitr0/issues/133
mdwitr0 Sep 21, 2023
e211142
feat: add other fields to movie search
mdwitr0 Sep 22, 2023
3c5d362
Merge pull request #148 from mdwitr0/issues/133
mdwitr0 Sep 22, 2023
24e914d
feat: add movies collection list
mdwitr0 Sep 22, 2023
9ddba3e
feat: add lists to movie
mdwitr0 Sep 22, 2023
bbccdbb
chore: add version params to BaseController
mdwitr0 Sep 22, 2023
57aa7a5
Merge pull request #149 from mdwitr0/issues/147
mdwitr0 Sep 22, 2023
a9df05b
chore: add lists to query pipes
mdwitr0 Sep 23, 2023
5293569
feat: add filters to random method
mdwitr0 Oct 8, 2023
8d4871e
chore: update description on random method
mdwitr0 Oct 11, 2023
44630ee
chore: add docker-compose local
mdwitr0 Oct 11, 2023
5866123
feat: add rating and year to linked movies
mdwitr0 Oct 11, 2023
d90d1aa
Merge pull request #153 from mdwitr0/issues/152
mdwitr0 Oct 11, 2023
4642d30
chore: add v1.4 search movie model
mdwitr0 Oct 19, 2023
be76d66
Merge remote-tracking branch 'origin/develop' into develop
mdwitr0 Oct 19, 2023
2b6b063
chore: add v1.4 search person model
mdwitr0 Oct 19, 2023
282e365
chore: update styles path to swagger docs
mdwitr0 Oct 24, 2023
a3505e2
feat: add v1.4 persons search
mdwitr0 Oct 24, 2023
bf8cf25
feat: add v1.4 movies search
mdwitr0 Oct 24, 2023
96db508
feat: add v1.4 to search sync
mdwitr0 Oct 24, 2023
935ec87
Merge pull request #154 from mdwitr0/issues/116
mdwitr0 Oct 24, 2023
240792d
feat: add networks to movie
mdwitr0 Oct 25, 2023
3280ecc
Merge pull request #156 from mdwitr0/issues/155
mdwitr0 Oct 25, 2023
192f355
chore: update health cases
mdwitr0 Oct 25, 2023
0343822
chore: update docs
mdwitr0 Oct 26, 2023
8618495
chore: add is number & min-max validation
mdwitr0 Oct 27, 2023
ec1d25a
chore: add is number & min-max validation
mdwitr0 Oct 27, 2023
43f2f99
chore: add query params strategy
mdwitr0 Oct 29, 2023
95308fd
chore: add validate is number with strategy
mdwitr0 Oct 29, 2023
275f431
chore: add validation cases to number values
mdwitr0 Oct 29, 2023
e408c6e
chore: add validation cases to is start with & refactor is number and…
mdwitr0 Oct 29, 2023
6a5282d
chore: add validation cases to is length exact
mdwitr0 Oct 30, 2023
2789382
chore: add is enum, is values, ale array lengths validation cases
mdwitr0 Oct 31, 2023
61fa2e6
chore: update swagger docs
mdwitr0 Oct 31, 2023
30e85b6
chore: update swagger docs
mdwitr0 Oct 31, 2023
22be744
chore: add is boolean validation
mdwitr0 Oct 31, 2023
6455828
chore: add is date validation
mdwitr0 Oct 31, 2023
de6fc2d
chore: add movie v1.4 model
mdwitr0 Oct 31, 2023
7891ab1
refactor: optimize query param strategies & add default strategies
mdwitr0 Nov 1, 2023
3dc038b
chore: add build where to strategies
mdwitr0 Nov 1, 2023
739f2f3
refactor: remove init strategies in validation
mdwitr0 Nov 1, 2023
c3063c6
chore: add set by number to filter builder
mdwitr0 Nov 2, 2023
8047028
chore: add set string, boolean, date to filter builder
mdwitr0 Nov 2, 2023
fb780ae
refactor: query filter builder
mdwitr0 Nov 2, 2023
2e7db46
chore: add to array decorator
mdwitr0 Nov 2, 2023
e1292bc
chore: add array handling in ParseNumber decorator
mdwitr0 Nov 2, 2023
4beb427
style: add generic to toWhere
mdwitr0 Nov 2, 2023
9b44048
chore: changed setBoolean in FilterBuilder to accept single value ins…
mdwitr0 Nov 2, 2023
ecfadb0
chore: Enhanced data transformation and validation in movie-request.dto
mdwitr0 Nov 2, 2023
9ad4d30
chore: added decorators to MovieRequestDto to better handle data vali…
mdwitr0 Nov 3, 2023
5ab7b27
chore: add not-null filter to query builder
mdwitr0 Nov 3, 2023
b7fad95
feat: add movie request model & new query builder to find many movie
mdwitr0 Nov 3, 2023
ea23c67
chore: update dto in v1.4 routes & add movie request dto with query b…
mdwitr0 Nov 3, 2023
e35a461
Merge pull request #159 from mdwitr0/issues/158
mdwitr0 Nov 3, 2023
03a5c8b
chore: add metrika to docs
mdwitr0 Nov 3, 2023
9e514ae
chore: add default 404 page & update swagger path & docs info
mdwitr0 Nov 3, 2023
f2c1124
chore: add public routes to execute auth & add docs url
mdwitr0 Nov 4, 2023
06174f0
feat: add person request model & new query builder to find many persons
mdwitr0 Nov 4, 2023
8fc8fde
feat: add review request model & new query builder to find many review
mdwitr0 Nov 4, 2023
4b02b84
feat: add find one collection by slug
mdwitr0 Nov 4, 2023
1abef98
feat: add image request model & new query builder to find many image
mdwitr0 Nov 4, 2023
c511e67
feat: add keyword request model & new query builder to find many keyword
mdwitr0 Nov 4, 2023
08538da
feat: add season request model & new query builder to find many season
mdwitr0 Nov 4, 2023
333db73
feat: add studio request model & new query builder to find many studio
mdwitr0 Nov 4, 2023
1b2c52b
feat: add awards request model & new query builder to find many awards
mdwitr0 Nov 4, 2023
adf97d8
Merge pull request #161 from mdwitr0/issues/158
mdwitr0 Nov 4, 2023
108939e
feat: add validation id to find one methods
mdwitr0 Nov 4, 2023
8ac239c
chore: add servers url by env
mdwitr0 Nov 4, 2023
b260b34
fix: not correct request model on random method
mdwitr0 Nov 4, 2023
7d83ad0
chore: add sync to dev env
mdwitr0 Nov 4, 2023
8ae1254
refactor: remove unused tests
mdwitr0 Nov 4, 2023
a285b9b
chore: simplify server configuration in swagger.ts
mdwitr0 Nov 5, 2023
d5729cc
chore: add default selected fields & add default sorting
mdwitr0 Nov 5, 2023
bd6c849
fix: meilisearch does not support nested searchable fields
mdwitr0 Nov 5, 2023
82be407
fix: select fields conflict
mdwitr0 Nov 5, 2023
532169a
chore: update error messages
mdwitr0 Nov 5, 2023
f9f019e
fix: date params isn't transform to filter
mdwitr0 Nov 5, 2023
9d761b8
fix: boolean params isn't transform to filter
mdwitr0 Nov 5, 2023
a4b9e16
chore: update docs
mdwitr0 Nov 5, 2023
c5d9294
chore: update endpoint docs
mdwitr0 Nov 5, 2023
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
Prev Previous commit
Next Next commit
feat: add review request model & new query builder to find many review
  • Loading branch information
mdwitr0 committed Nov 4, 2023
commit 8fc8fde884dc51dac7eb78e573bcaa6e64809c0e
33 changes: 15 additions & 18 deletions src/person/dto/v1.4/person-request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,80 +193,75 @@ export class PersonRequestDtoV1_4 implements IRequestModel {
@NumberParam()
'movies.id'?: string[];

// sex
@ApiNullableProperty({ isArray: true, description: 'Поиск по гендеру (пример: `Женский, Мужской`)' })
@ApiNullableProperty({ isArray: true, description: 'Поиск по гендеру (пример: `Женский, Мужской`)', enum: PersonSexV1_4 })
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [PersonSexV1_4])
@EnumParam()
sex?: string[];

// growth
@ApiNullableProperty({ isArray: true, description: 'Поиск по росту (пример: `170-180, 180`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [1, 300])
@NumberParam()
growth?: string[];

// birthday
@ApiNullableProperty({ isArray: true, description: 'Поиск по дате рождения (пример: `01.01.2000-01.01.2001, 01.01.2000`)' })
@IsOptional()
@ToArray()
@Validate(IsDateParam)
@DateParam()
birthday?: string[];
// death

@ApiNullableProperty({ isArray: true, description: 'Поиск по дате смерти (пример: `01.01.2000-01.01.2001, 01.01.2000`)' })
@IsOptional()
@ToArray()
@Validate(IsDateParam)
@DateParam()
death?: string[];

// age
@ApiNullableProperty({ isArray: true, description: 'Поиск по возрасту (пример: `18-25, 25`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [0, 300])
@NumberParam()
age?: string[];

// birthPlace.value
@ApiNullableProperty({ isArray: true, description: 'Поиск по месту рождения (пример: `Москва, Санкт-Петербург`)' })
@IsOptional()
@ToArray()
@StringParam()
'birthPlace.value'?: string[];
// deathPlace.value

@ApiNullableProperty({ isArray: true, description: 'Поиск по месту смерти (пример: `Москва, Санкт-Петербург`)' })
@IsOptional()
@ToArray()
@StringParam()
'deathPlace.value'?: string[];
// spouses.id

@ApiNullableProperty({ isArray: true, description: 'Поиск по ID супруги(супруга) (пример: `111, 222`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [1, 9000000])
@Validate(IsNumberParam)
@NumberParam()
'spouses.id'?: string[];
// spouses.divorced

@ApiNullableProperty({ isArray: true, description: 'Поиск по статусу развода (пример: `true, false`)' })
@IsOptional()
@ToArray()
@Validate(IsBooleanParam)
@BooleanParam()
'spouses.divorced'?: string[];
// spouses.sex
@ApiNullableProperty({ isArray: true, description: 'Поиск по гендеру супруги(супруга) (пример: `Женский, Мужской`)' })

@ApiNullableProperty({ isArray: true, description: 'Поиск по гендеру супруги(супруга) (пример: `Женский, Мужской`)', enum: PersonSexV1_4 })
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [PersonSexV1_4])
@EnumParam()
'spouses.sex'?: string[];
// countAwards

@ApiNullableProperty({ isArray: true, description: 'Поиск по количеству наград (пример: `1-10, 10`)' })
@IsOptional()
@ToArray()
Expand All @@ -275,14 +270,13 @@ export class PersonRequestDtoV1_4 implements IRequestModel {
@NumberParam()
countAwards?: string[];

// profession.value
@ApiNullableProperty({ isArray: true, description: 'Поиск по профессии (пример: `Актер, Режиссер`)' })
@ApiNullableProperty({ isArray: true, description: 'Поиск по профессии (пример: `Актер, Режиссер`)', enum: PersonProfessionV1_4 })
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [PersonProfessionV1_4])
@EnumParam()
'profession.value'?: string[];
// movies.rating

@ApiNullableProperty({ isArray: true, description: 'Поиск по рейтингу фильма (пример: `1-10, 10`)' })
@IsOptional()
@ToArray()
Expand All @@ -291,8 +285,11 @@ export class PersonRequestDtoV1_4 implements IRequestModel {
@NumberParam()
'movies.rating'?: string[];

// movies.enProfession
@ApiNullableProperty({ isArray: true, description: 'Поиск по профессии в фильмах на английском (пример: `actor, director`)' })
@ApiNullableProperty({
isArray: true,
description: 'Поиск по профессии в фильмах на английском (пример: `actor, director`)',
enum: PersonEnProfessionV1_4,
})
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [PersonEnProfessionV1_4])
Expand Down
2 changes: 1 addition & 1 deletion src/person/person.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class PersonController extends BaseControllerWithFindById(Person, PersonD
description: `Этот метод предназначен для поиска персон по фильтрам. Он принимает множество параметров, которые можно комбинировать между собой. Если вам нужен только поиск по имени, используйте метод \`Полнотекстовый поиск\` (search). В этом методе также доступен выбор полей. А в ответ приходит полная модель персоны.`,
})
async findManyV1_4(@Query() request: PersonRequestDtoV1_4): Promise<PersonDocsResponseDto> {
return this.service.findManyV1_4(request);
return this.personService.findManyV1_4(request);
}

@Version('1.4')
Expand Down
8 changes: 8 additions & 0 deletions src/review/dto/v1.4/review-docs.response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ReviewDocsResponseDto } from '../review-docs-response.dto';

export class ReviewDocsResponseDtoV1_4 extends ReviewDocsResponseDto {
constructor(partial: Partial<ReviewDocsResponseDtoV1_4>) {
super(partial);
Object.assign(this, partial);
}
}
206 changes: 206 additions & 0 deletions src/review/dto/v1.4/review-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import { FilterBuilder } from '../../../common/query-builder/filter-builder';
import { SelectBuilder } from '../../../common/query-builder/select-builder';
import { SortOrder } from 'mongoose';
import { SortBuilder } from '../../../common/query-builder/sort-builder';
import { PaginationBuilder } from '../../../common/query-builder/pagination-builder';
import { IRequestModel } from '../../../common/interfaces/request-model.interface';
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsNumber, IsOptional, IsString, Min, Validate } from 'class-validator';
import { ParseNumber } from '../../../common/decorators/transform/parse-number.decorator';
import { SetDefaultValue } from '../../../common/decorators/transform/set-default-value.decorator';
import { Expose } from 'class-transformer';
import { IsValueInRange } from '../../../common/validation/is-value-in-range';
import { ToArray } from '../../../common/decorators/transform/to-array.decorator';
import { IsEnumParam } from '../../../common/validation/is-enum-param';
import { AreArrayLengthsEqual } from '../../../common/validation/are-array-lengths-equal';
import { IsValues } from '../../../common/validation/is-values';
import { ApiNullableProperty } from '../../../common/decorators/api-nullable-property.decorator';
import { IsNumberParam } from '../../../common/validation/is-number-param';
import { NumberParam } from '../../../common/decorators/types/number-param';
import { IsDateParam } from '../../../common/validation/is-date-param';
import { DateParam } from '../../../common/decorators/types/date-param';
import { EnumParam } from '../../../common/decorators/types/enum-param';

export enum ReviewFieldV1_4 {
'id' = 'id',
'movieId' = 'movieId',
'title' = 'title',
'type' = 'type',
'review' = 'review',
'date' = 'date',
'author' = 'author',
'authorId' = 'authorId',
}

export enum ReviewSelectFieldV1_4 {
'id' = 'id',
'movieId' = 'movieId',
'title' = 'title',
'type' = 'type',
'review' = 'review',
'date' = 'date',
'author' = 'author',
'authorId' = 'authorId',
}

enum ReviewTypeV1_4 {
'Негативный' = 'Негативный',
'Нейтральный' = 'Нейтральный',
'Позитивный' = 'Позитивный',
}

export class ReviewRequestDtoV1_4 implements IRequestModel {
@ApiPropertyOptional({ description: 'Номер страницы', minimum: 1, default: 1 })
@IsOptional()
@IsNumber()
@Min(1)
@ParseNumber()
@SetDefaultValue(1)
@Expose()
page: number;

@ApiPropertyOptional({ description: 'Количество элементов на странице', minimum: 1, maximum: 250, default: 10 })
@IsOptional()
@Validate(IsValueInRange, [1, 250])
@ParseNumber()
@SetDefaultValue(10)
@Expose()
limit: number;

@ApiPropertyOptional({
description: 'Список полей требуемых в ответе из модели',
isArray: true,
enum: ReviewSelectFieldV1_4,
})
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [ReviewSelectFieldV1_4])
@Expose()
selectFields?: string[];

@ApiPropertyOptional({
isArray: true,
description: 'Список полей которые не должны быть null или пусты',
enum: ReviewFieldV1_4,
})
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [ReviewFieldV1_4])
@Expose()
notNullFields?: string[];

@ApiPropertyOptional({ description: 'Сортировка по полям из модели', isArray: true, enum: ReviewFieldV1_4 })
@IsOptional()
@Validate(IsEnumParam, [ReviewFieldV1_4])
@Validate(AreArrayLengthsEqual, ['sortType'])
@ToArray()
@Expose()
sortField?: string[];

@ApiPropertyOptional({ description: 'Тип сортировки применительно к полям из sortField (пример: `"1", "-1"`)' })
@IsOptional()
@Validate(IsValues, ['1', '-1'])
@Validate(AreArrayLengthsEqual, ['sortField'])
@ToArray()
@Expose()
sortType?: string[];

@ApiNullableProperty({ isArray: true, description: 'Поиск по ID отзыва (пример: `"111", "222", "!666"`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [4000, 5000000])
@Validate(IsNumberParam)
@NumberParam()
id?: string[];

@ApiNullableProperty({ isArray: true, description: 'Поиск по ID фильма (пример: `"666", "555", "!666"`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [1, 7000000])
@Validate(IsNumberParam)
@NumberParam()
'movies.id'?: string[];

@ApiNullableProperty({ isArray: true, description: 'Поиск отзывов по ID автора (пример: `"666", "555", "!666"`)' })
@IsOptional()
@ToArray()
@Validate(IsValueInRange, [1, 200000000])
@Validate(IsNumberParam)
@NumberParam()
'authorId'?: string[];

@ApiNullableProperty({ isArray: true, description: 'Поиск по имени автора отзыва (пример: `"КиноПоиск", "!КиноПоиск"`)' })
@IsOptional()
@ToArray()
@Validate(IsString)
author?: string[];

@ApiNullableProperty({
isArray: true,
description: 'Поиск по типу отзыва (пример: `"!Негативный", "Нейтральный", "Позитивный"`)',
enum: ReviewTypeV1_4,
})
@IsOptional()
@ToArray()
@Validate(IsEnumParam, [ReviewTypeV1_4])
@EnumParam()
type?: string[];

@ApiNullableProperty({ isArray: true, description: 'Поиск по дате создания отзыва (пример: `"01.01.2021-01.01.2022", "01.01.2021"`)' })
@IsOptional()
@ToArray()
@Validate(IsDateParam)
@DateParam()
date?: string[];

public model2Where() {
const filter = new FilterBuilder();
for (const key of Object.keys(this)) {
const type = Reflect.getMetadata('type', this, key);

switch (type) {
case 'string':
filter.setString(key, this[key]);
break;
case 'number':
filter.setNumber(key, this[key]);
break;
case 'boolean':
filter.setBoolean(key, this[key]);
break;
case 'date':
filter.setDate(key, this[key]);
break;
case 'enum':
filter.setEnum(key, this[key]);
break;
default:
break;
}
}

if (this.notNullFields?.length) {
filter.setNotNull(this.notNullFields);
}

return filter.build();
}

public model2Select() {
const select = new SelectBuilder();

return select.build(this.selectFields);
}

public model2Sort(): { [key: string]: SortOrder } {
const sort = new SortBuilder().build(this.sortField, this.sortType);

return Object.keys(sort)?.length ? { ...sort, _id: -1 } : { 'votes.kp': -1, _id: -1 };
}

public model2Pagination() {
const pagination = new PaginationBuilder();

return pagination.build(this.page, this.limit);
}
}
15 changes: 15 additions & 0 deletions src/review/review.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,25 @@ import { ReviewDocsResponseDto } from './dto/review-docs-response.dto';

import { BaseController } from 'src/common/base/base.controller';
import { Controller } from 'src/common/decorators/controller.decorator';
import { CacheInterceptor, Get, Query, UseInterceptors, Version } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';
import { ReviewRequestDtoV1_4 } from './dto/v1.4/review-request.dto';
import { ReviewDocsResponseDtoV1_4 } from './dto/v1.4/review-docs.response';

@Controller('review', 'Отзывы пользователей')
export class ReviewController extends BaseController(Review, ReviewDocsResponseDto, 'Поиск отзывов') {
constructor(private readonly reviewService: ReviewService) {
super(reviewService);
}

@Version('1.4')
@Get()
@UseInterceptors(CacheInterceptor)
@ApiOperation({
summary: 'Универсальный поиск с фильтрами',
description: `Этот метод предназначен для поиска персон по фильтрам. Он принимает множество параметров, которые можно комбинировать между собой. Если вам нужен только поиск по имени, используйте метод \`Полнотекстовый поиск\` (search). В этом методе также доступен выбор полей. А в ответ приходит полная модель персоны.`,
})
async findManyV1_4(@Query() request: ReviewRequestDtoV1_4): Promise<ReviewDocsResponseDtoV1_4> {
return this.reviewService.findManyV1_4(request);
}
}
Loading