Skip to content

Commit

Permalink
Merge pull request #31 from kir-dev/feature/17-group-validation
Browse files Browse the repository at this point in the history
Feature/17 group validation
  • Loading branch information
csiszaralex authored Sep 2, 2024
2 parents 6f73e67 + 07515dc commit 689003d
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 28 deletions.
3 changes: 3 additions & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
"@nestjs/core": "^10.3.9",
"@nestjs/mapped-types": "^2.0.5",
"@nestjs/platform-express": "^10.3.9",
"@nestjs/swagger": "^7.4.0",
"@prisma/client": "^5.14.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"nestjs-prisma": "^0.23.0",
"reflect-metadata": "^0.2.2",
"rimraf": "^5.0.7",
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/src/groups/dto/create-group.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { OmitType } from '@nestjs/swagger';

import { Group } from '../entities/group.entity';

export class CreateGroupDto extends OmitType(Group, ['id']) {}
5 changes: 5 additions & 0 deletions apps/backend/src/groups/dto/update-group.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PartialType } from '@nestjs/swagger';

import { CreateGroupDto } from './create-group.dto';

export class UpdateGroupDto extends PartialType(CreateGroupDto) {}
15 changes: 15 additions & 0 deletions apps/backend/src/groups/entities/group.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { IsInt, IsNotEmpty, IsOptional, IsString, Min } from 'class-validator';

export class Group {
@IsInt()
@Min(1)
id: number;

@IsString()
@IsNotEmpty()
name: string;

@IsString()
@IsOptional()
description: string;
}
40 changes: 23 additions & 17 deletions apps/backend/src/groups/groups.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
import { Prisma, Role } from '@prisma/client';
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common';
import { Role } from '@prisma/client';

import { CreateGroupDto } from './dto/create-group.dto';
import { UpdateGroupDto } from './dto/update-group.dto';
import { GroupsService } from './groups.service';

@Controller('groups')
export class GroupsController {
constructor(private readonly groupsService: GroupsService) {}

@Post()
create(@Body() data: Prisma.GroupCreateInput) {
create(@Body() data: CreateGroupDto) {
return this.groupsService.create(data);
}

Expand All @@ -18,37 +20,41 @@ export class GroupsController {
}

@Get(':id')
findOne(@Param('id') id: string) {
return this.groupsService.findOne(Number(id));
findOne(@Param('id', ParseIntPipe) id: number) {
return this.groupsService.findOne(id);
}

@Get(':id/members')
findMembers(@Param('id') id: string) {
return this.groupsService.findMembers(Number(id));
findMembers(@Param('id', ParseIntPipe) id: number) {
return this.groupsService.findMembers(id);
}

@Patch(':id')
update(@Param('id') id: string, @Body() data: Prisma.GroupUpdateInput) {
return this.groupsService.update(Number(id), data);
update(@Param('id', ParseIntPipe) id: number, @Body() data: UpdateGroupDto) {
return this.groupsService.update(id, data);
}

@Delete(':id')
remove(@Param('id') id: string) {
return this.groupsService.remove(Number(id));
remove(@Param('id', ParseIntPipe) id: number) {
return this.groupsService.remove(id);
}

@Post(':id/members/:userId')
addMember(@Param('id') id: string, @Param('userId') userId: string) {
return this.groupsService.addMember(Number(id), Number(userId));
addMember(@Param('id', ParseIntPipe) id: number, @Param('userId') userId: number) {
return this.groupsService.addMember(id, Number(userId));
}

@Patch(':id/members/:userId')
updateRole(@Param('id') id: string, @Param('userId') userId: string, @Body() newRole: { role: Role }) {
return this.groupsService.updateMemberRole(Number(id), Number(userId), newRole);
updateRole(
@Param('id', ParseIntPipe) id: number,
@Param('userId', ParseIntPipe) userId: number,
@Body() newRole: { role: Role }
) {
return this.groupsService.updateMemberRole(id, userId, newRole);
}

@Delete(':id/members/:userId')
removeMember(@Param('id') id: string, @Param('userId') userId: string) {
return this.groupsService.removeMember(Number(id), Number(userId));
removeMember(@Param('id', ParseIntPipe) id: number, @Param('userId', ParseIntPipe) userId: number) {
return this.groupsService.removeMember(id, userId);
}
}
9 changes: 6 additions & 3 deletions apps/backend/src/groups/groups.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { Group, GroupMembers, Prisma, Role, User } from '@prisma/client';
import { Group, GroupMembers, Role, User } from '@prisma/client';
import { PrismaService } from 'nestjs-prisma';

import { CreateGroupDto } from './dto/create-group.dto';
import { UpdateGroupDto } from './dto/update-group.dto';

@Injectable()
export class GroupsService {
constructor(private readonly prisma: PrismaService) {}

async create(data: Prisma.GroupCreateInput): Promise<Group> {
async create(data: CreateGroupDto): Promise<Group> {
try {
return await this.prisma.group.create({ data });
} catch {
Expand Down Expand Up @@ -44,7 +47,7 @@ export class GroupsService {
}));
}

async update(id: number, data: Prisma.GroupUpdateInput): Promise<Group> {
async update(id: number, data: UpdateGroupDto): Promise<Group> {
try {
return await this.prisma.group.update({ where: { id }, data });
} catch {
Expand Down
104 changes: 96 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@
resolved "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz"
integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==

"@microsoft/tsdoc@^0.15.0":
version "0.15.0"
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d"
integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==

"@mole-inc/bin-wrapper@^8.0.1":
version "8.0.1"
resolved "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz"
Expand Down Expand Up @@ -298,7 +303,7 @@
path-to-regexp "3.2.0"
tslib "2.6.2"

"@nestjs/mapped-types@^2.0.5":
"@nestjs/mapped-types@2.0.5", "@nestjs/mapped-types@^2.0.5":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz#485d6b44e19779c98d04e52bd1d2bcc7001df0ea"
integrity sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==
Expand All @@ -325,6 +330,18 @@
jsonc-parser "3.2.1"
pluralize "8.0.0"

"@nestjs/swagger@^7.4.0":
version "7.4.0"
resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-7.4.0.tgz#e61dbefdfc1d4011327a256896953c74e511c850"
integrity sha512-dCiwKkRxcR7dZs5jtrGspBAe/nqJd1AYzOBTzw9iCdbq3BGrLpwokelk6lFZPe4twpTsPQqzNKBwKzVbI6AR/g==
dependencies:
"@microsoft/tsdoc" "^0.15.0"
"@nestjs/mapped-types" "2.0.5"
js-yaml "4.1.0"
lodash "4.17.21"
path-to-regexp "3.2.0"
swagger-ui-dist "5.17.14"

"@next/[email protected]":
version "14.2.2"
resolved "https://registry.npmjs.org/@next/env/-/env-14.2.2.tgz"
Expand Down Expand Up @@ -784,6 +801,11 @@
"@types/node" "*"
"@types/send" "*"

"@types/validator@^13.11.8":
version "13.12.1"
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.1.tgz#8835d22f7e25b261e624d02a42fe4ade2c689a3c"
integrity sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA==

"@typescript-eslint/eslint-plugin@^7.12.0":
version "7.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.12.0.tgz#f87a32e8972b8a60024f2f8f12205e7c8108bc41"
Expand Down Expand Up @@ -1158,6 +1180,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"

ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==

any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
Expand Down Expand Up @@ -1556,6 +1583,20 @@ chrome-trace-event@^1.0.2:
resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz"
integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==

class-transformer@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336"
integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==

class-validator@^0.14.1:
version "0.14.1"
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.1.tgz#ff2411ed8134e9d76acfeb14872884448be98110"
integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==
dependencies:
"@types/validator" "^13.11.8"
libphonenumber-js "^1.10.53"
validator "^13.9.0"

class-variance-authority@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz"
Expand Down Expand Up @@ -1920,6 +1961,11 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"

eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==

[email protected]:
version "1.1.1"
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
Expand Down Expand Up @@ -3334,7 +3380,7 @@ jiti@^1.21.0:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==

js-yaml@^4.1.0:
js-yaml@4.1.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
Expand Down Expand Up @@ -3439,6 +3485,11 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"

libphonenumber-js@^1.10.53:
version "1.11.7"
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.11.7.tgz#efe4fcf816e1982925e9c800d0013b0ee99b8283"
integrity sha512-x2xON4/Qg2bRIS11KIN9yCNYUjhtiEjNyptjX0mX+pyKHecxuJVLIpfX1lq9ZD6CrC/rB+y4GBi18c6CEcUR+A==

lilconfig@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz"
Expand Down Expand Up @@ -3471,7 +3522,7 @@ lodash.merge@^4.6.2:
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==

lodash@^4.17.21:
lodash@4.17.21, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
Expand Down Expand Up @@ -4761,7 +4812,7 @@ streamsearch@^1.1.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@4.1.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.1.2:
string-width@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff"
integrity sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==
Expand All @@ -4770,6 +4821,24 @@ [email protected], string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.
is-fullwidth-code-point "^3.0.0"
strip-ansi "^5.2.0"

string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
dependencies:
eastasianwidth "^0.2.0"
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"

string.prototype.matchall@^4.0.10:
version "4.0.11"
resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz"
Expand Down Expand Up @@ -4937,6 +5006,11 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==

[email protected]:
version "5.17.14"
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz#e2c222e5bf9e15ccf80ec4bc08b4aaac09792fd6"
integrity sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==

[email protected]:
version "4.0.0"
resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz"
Expand Down Expand Up @@ -5308,6 +5382,11 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==

validator@^13.9.0:
version "13.12.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f"
integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==

vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
Expand Down Expand Up @@ -5454,15 +5533,24 @@ which@^2.0.1:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@7.0.0, wrap-ansi@^6.0.1, wrap-ansi@^6.2.0, wrap-ansi@^8.1.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
dependencies:
ansi-styles "^6.1.0"
string-width "^5.0.1"
strip-ansi "^7.0.1"

wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
Expand Down

0 comments on commit 689003d

Please sign in to comment.