From f424d6ffe60cb71097003e6244e9aa092c772091 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Sun, 19 Nov 2023 19:59:40 +0300 Subject: [PATCH 01/26] Added docker compose with postgres db --- .vscode/settings.json | 11 +++++++++++ docker-compose.yml | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 docker-compose.yml diff --git a/.vscode/settings.json b/.vscode/settings.json index 2b07ebc..c4f402b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,4 +11,15 @@ }, "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", + "[dockercompose]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + "editor.autoIndent": "advanced", + "editor.quickSuggestions": { + "other": true, + "comments": false, + "strings": true + }, + "editor.defaultFormatter": "ms-azuretools.vscode-docker" + } } \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5fa018d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.9' + +services: + db: + container_name: neuro_db + image: postgres:alpine + environment: + - POSTGRES_USER=${DATABASE_USER} + - POSTGRES_PASSWORD=${DATABASE_PASSWORD} + - POSTGRES_DB=${DATABASE_NAME} + - PGDATA=/var/lib/postgresql/data/pgdata + ports: + - "${DATABASE_PORT}:5432" + env_file: + - ./backend/.env + volumes: + - neuro_postgres_db:/var/lib/postgresql/data +volumes: + neuro_postgres_db: + driver: local From c53b37590a4b6031c95229bbdabc312f42934dfa Mon Sep 17 00:00:00 2001 From: Errormacr Date: Mon, 20 Nov 2023 11:45:25 +0300 Subject: [PATCH 02/26] Add Admin module and entity --- backend/libs/database/admin.entity.ts | 11 ++++++ backend/libs/libs.module.ts | 3 +- backend/src/app.module.ts | 3 +- backend/src/modules/admin/admin.controller.ts | 22 ++++++++++++ backend/src/modules/admin/admin.module.ts | 11 ++++++ backend/src/modules/admin/admin.service.ts | 34 +++++++++++++++++++ .../initialization/app.init.service.ts | 6 +++- 7 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 backend/libs/database/admin.entity.ts create mode 100644 backend/src/modules/admin/admin.controller.ts create mode 100644 backend/src/modules/admin/admin.module.ts create mode 100644 backend/src/modules/admin/admin.service.ts diff --git a/backend/libs/database/admin.entity.ts b/backend/libs/database/admin.entity.ts new file mode 100644 index 0000000..66a86f5 --- /dev/null +++ b/backend/libs/database/admin.entity.ts @@ -0,0 +1,11 @@ +import { Entity, PrimaryColumn } from 'typeorm'; + +@Entity() +export class Admin { + constructor(props?: Partial) { + Object.assign(this, props); + } + + @PrimaryColumn() + public id!: string; +} diff --git a/backend/libs/libs.module.ts b/backend/libs/libs.module.ts index 6761b66..db10c9c 100644 --- a/backend/libs/libs.module.ts +++ b/backend/libs/libs.module.ts @@ -1,8 +1,9 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from './database/user.entity'; +import { Admin } from './database/admin.entity'; @Module({ - imports: [TypeOrmModule.forFeature([User])], + imports: [TypeOrmModule.forFeature([User, Admin])], exports: [TypeOrmModule], }) export class LibsModule {} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 52a881e..8e1ff9d 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -4,9 +4,10 @@ import { config } from 'config'; import { LibsModule } from 'libs/libs.module'; import { AppInitService } from './modules/initialization/app.init.service'; import { UserModule } from './modules/user/user.module'; +import { AdminModule } from './modules/admin/admin.module'; @Module({ - imports: [LibsModule, UserModule, TypeOrmModule.forRoot(config.database)], + imports: [AdminModule, LibsModule, UserModule, TypeOrmModule.forRoot(config.database)], controllers: [], providers: [AppInitService], }) diff --git a/backend/src/modules/admin/admin.controller.ts b/backend/src/modules/admin/admin.controller.ts new file mode 100644 index 0000000..6b643e5 --- /dev/null +++ b/backend/src/modules/admin/admin.controller.ts @@ -0,0 +1,22 @@ +import { Controller, Get, Param } from '@nestjs/common'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { AdminService } from './admin.service'; + +@ApiTags('Admin') +@Controller('Admin') +export class AdminController { + constructor(private adminService: AdminService) {} + + @ApiOperation({ + description: 'Get admins from db', + }) + @Get('get') + async getAdmin() { + return await this.adminService.getAdmins(); + } + @ApiOperation({ description: 'Check admin is or not' }) + @Get('is_admin/:id') + async isAdmin(@Param('id') id: string) { + return await this.adminService.checkIsAdmin(id); + } +} diff --git a/backend/src/modules/admin/admin.module.ts b/backend/src/modules/admin/admin.module.ts new file mode 100644 index 0000000..44faa1e --- /dev/null +++ b/backend/src/modules/admin/admin.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { LibsModule } from 'libs/libs.module'; +import { AdminController } from './admin.controller'; +import { AdminService } from './admin.service'; + +@Module({ + imports: [LibsModule], + controllers: [AdminController], + providers: [AdminService], +}) +export class AdminModule {} diff --git a/backend/src/modules/admin/admin.service.ts b/backend/src/modules/admin/admin.service.ts new file mode 100644 index 0000000..5001fb0 --- /dev/null +++ b/backend/src/modules/admin/admin.service.ts @@ -0,0 +1,34 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; +import { Admin } from 'libs/database/admin.entity'; + +@Injectable() +export class AdminService { + private readonly logger: Logger = new Logger(AdminService.name); + constructor(@InjectRepository(Admin) private adminRepository: Repository) {} + + async getAdmins() { + try { + this.logger.debug(`[admin.getAdmins]`); + const admins = await this.adminRepository.find(); + return admins; + } catch (error) { + this.logger.log(`[getAdmin] ${JSON.stringify({ error })}`); + } + } + async checkIsAdmin(id: string) { + try { + this.logger.debug(`[admin.checkIsAdmin]`); + const admins = await this.adminRepository.findOne({ + where: { id: id }, + }); + if (!admins) { + return false; + } + return true; + } catch (error) { + this.logger.log(`[checkIsAdmin] ${JSON.stringify({ error })}`); + } + } +} diff --git a/backend/src/modules/initialization/app.init.service.ts b/backend/src/modules/initialization/app.init.service.ts index e22de72..8f7d27f 100644 --- a/backend/src/modules/initialization/app.init.service.ts +++ b/backend/src/modules/initialization/app.init.service.ts @@ -1,11 +1,15 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import { Admin } from 'libs/database/admin.entity'; import { User } from 'libs/database/user.entity'; import { Repository } from 'typeorm'; @Injectable() export class AppInitService implements OnModuleInit { - constructor(@InjectRepository(User) private userRepository: Repository) {} + constructor( + @InjectRepository(User) private userRepository: Repository, + @InjectRepository(Admin) private adminRepository: Repository, + ) {} async onModuleInit() {} } From 35e72a2134c87a86cecf6684e7a6d95d2230df79 Mon Sep 17 00:00:00 2001 From: Errormacr Date: Mon, 20 Nov 2023 14:59:51 +0300 Subject: [PATCH 03/26] Update Admin entity and AdminService to use user_id instead of id --- backend/libs/database/admin.entity.ts | 14 +++++++++++--- backend/src/modules/admin/admin.service.ts | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/backend/libs/database/admin.entity.ts b/backend/libs/database/admin.entity.ts index 66a86f5..022d660 100644 --- a/backend/libs/database/admin.entity.ts +++ b/backend/libs/database/admin.entity.ts @@ -1,4 +1,5 @@ -import { Entity, PrimaryColumn } from 'typeorm'; +import { Entity, OneToOne, JoinColumn, PrimaryGeneratedColumn, Column } from 'typeorm'; +import { User } from './user.entity'; @Entity() export class Admin { @@ -6,6 +7,13 @@ export class Admin { Object.assign(this, props); } - @PrimaryColumn() - public id!: string; + @PrimaryGeneratedColumn() + public id!: number; + + @Column() + user_id: string; + + @OneToOne(() => User) + @JoinColumn({ name: 'user_id' }) + user: User; } diff --git a/backend/src/modules/admin/admin.service.ts b/backend/src/modules/admin/admin.service.ts index 5001fb0..f732c20 100644 --- a/backend/src/modules/admin/admin.service.ts +++ b/backend/src/modules/admin/admin.service.ts @@ -21,7 +21,7 @@ export class AdminService { try { this.logger.debug(`[admin.checkIsAdmin]`); const admins = await this.adminRepository.findOne({ - where: { id: id }, + where: { user_id: id }, }); if (!admins) { return false; From c76c61c23c64fa5aa3f090998e0da76e8a8b40cc Mon Sep 17 00:00:00 2001 From: Errormacr Date: Mon, 20 Nov 2023 15:34:05 +0300 Subject: [PATCH 04/26] Added Post and Image entities to the database. --- backend/libs/database/image.entity.ts | 24 ++++++++++++++++++++++++ backend/libs/database/post.entity.ts | 27 +++++++++++++++++++++++++++ backend/libs/libs.module.ts | 4 +++- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 backend/libs/database/image.entity.ts create mode 100644 backend/libs/database/post.entity.ts diff --git a/backend/libs/database/image.entity.ts b/backend/libs/database/image.entity.ts new file mode 100644 index 0000000..b412419 --- /dev/null +++ b/backend/libs/database/image.entity.ts @@ -0,0 +1,24 @@ +import { Entity, PrimaryColumn, Column, OneToOne, JoinColumn } from 'typeorm'; +import { Post } from './post.entity'; + +@Entity() +export class Image { + constructor(props?: Partial) { + Object.assign(this, props); + } + + @PrimaryColumn() + message_id: number; + + @Column({ nullable: false }) + post_id: number; + + @Column({ nullable: false }) + file_id: string; + @Column({ default: false }) + has_spoiler: boolean; + + @OneToOne(() => Post) + @JoinColumn({ name: 'post_id' }) + user: Post; +} diff --git a/backend/libs/database/post.entity.ts b/backend/libs/database/post.entity.ts new file mode 100644 index 0000000..f58ce0b --- /dev/null +++ b/backend/libs/database/post.entity.ts @@ -0,0 +1,27 @@ +import { Entity, PrimaryGeneratedColumn, Column, Timestamp, OneToOne, JoinColumn } from 'typeorm'; +import { Admin } from './admin.entity'; +@Entity() +export class Post { + constructor(props?: Partial) { + Object.assign(this, props); + } + + @PrimaryGeneratedColumn('uuid') + uuid: string; + + @Column({ default: false }) + posted: boolean; + + @Column({ nullable: false }) + from_user_id: string; + @Column() + text: string; + @Column() + media_group_id: string; + @Column({ type: 'timestamptz' }) + timestamps: Date; + + @OneToOne(() => Admin) + @JoinColumn({ name: 'from_user_id' }) + user: Admin; +} diff --git a/backend/libs/libs.module.ts b/backend/libs/libs.module.ts index db10c9c..ef53738 100644 --- a/backend/libs/libs.module.ts +++ b/backend/libs/libs.module.ts @@ -2,8 +2,10 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from './database/user.entity'; import { Admin } from './database/admin.entity'; +import { Post } from './database/post.entity'; +import { Image } from './database/image.entity'; @Module({ - imports: [TypeOrmModule.forFeature([User, Admin])], + imports: [TypeOrmModule.forFeature([User, Admin, Post, Image])], exports: [TypeOrmModule], }) export class LibsModule {} From c4a914c0a560dd1b87fb01679018f984c562617e Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:07:08 +0300 Subject: [PATCH 05/26] Docker restarting --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 5fa018d..90b9958 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,7 @@ services: - ./backend/.env volumes: - neuro_postgres_db:/var/lib/postgresql/data + restart: always volumes: neuro_postgres_db: driver: local From 41fef28cf77efc3acd455c41e9c5538456f92b29 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:07:44 +0300 Subject: [PATCH 06/26] Some entities changes --- backend/libs/database/admin.entity.ts | 10 ++++----- backend/libs/database/image.entity.ts | 21 ++++++++++-------- backend/libs/database/post.entity.ts | 31 ++++++++++++++++----------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/backend/libs/database/admin.entity.ts b/backend/libs/database/admin.entity.ts index 022d660..8aa1a0b 100644 --- a/backend/libs/database/admin.entity.ts +++ b/backend/libs/database/admin.entity.ts @@ -1,4 +1,4 @@ -import { Entity, OneToOne, JoinColumn, PrimaryGeneratedColumn, Column } from 'typeorm'; +import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from 'typeorm'; import { User } from './user.entity'; @Entity() @@ -10,10 +10,10 @@ export class Admin { @PrimaryGeneratedColumn() public id!: number; - @Column() - user_id: string; + @Column({ nullable: false }) + public user_id!: string; - @OneToOne(() => User) + @OneToOne(() => User, (user) => user.id) @JoinColumn({ name: 'user_id' }) - user: User; + public user!: User; } diff --git a/backend/libs/database/image.entity.ts b/backend/libs/database/image.entity.ts index b412419..376e811 100644 --- a/backend/libs/database/image.entity.ts +++ b/backend/libs/database/image.entity.ts @@ -1,4 +1,5 @@ -import { Entity, PrimaryColumn, Column, OneToOne, JoinColumn } from 'typeorm'; +import { ApiProperty } from '@nestjs/swagger'; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'; import { Post } from './post.entity'; @Entity() @@ -8,17 +9,19 @@ export class Image { } @PrimaryColumn() - message_id: number; + public message_id!: number; @Column({ nullable: false }) - post_id: number; + public file_id!: string; - @Column({ nullable: false }) - file_id: string; @Column({ default: false }) - has_spoiler: boolean; + public has_spoiler!: boolean; - @OneToOne(() => Post) - @JoinColumn({ name: 'post_id' }) - user: Post; + @Column({ nullable: false }) + public post_uuid!: string; + + @ApiProperty({}) + @ManyToOne(() => Post, (post) => post.uuid) + @JoinColumn({ name: 'post_uuid' }) + public post!: Post; } diff --git a/backend/libs/database/post.entity.ts b/backend/libs/database/post.entity.ts index f58ce0b..b38978f 100644 --- a/backend/libs/database/post.entity.ts +++ b/backend/libs/database/post.entity.ts @@ -1,5 +1,6 @@ -import { Entity, PrimaryGeneratedColumn, Column, Timestamp, OneToOne, JoinColumn } from 'typeorm'; +import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn } from 'typeorm'; import { Admin } from './admin.entity'; +import { Image } from './image.entity'; @Entity() export class Post { constructor(props?: Partial) { @@ -7,21 +8,27 @@ export class Post { } @PrimaryGeneratedColumn('uuid') - uuid: string; + public uuid!: string; @Column({ default: false }) - posted: boolean; + public posted!: boolean; + + @Column() + public text: string; + + @Column({ nullable: true }) + public media_group_id: string; + + @Column({ type: 'timestamptz' }) + public timestamp!: Date; @Column({ nullable: false }) - from_user_id: string; - @Column() - text: string; - @Column() - media_group_id: string; - @Column({ type: 'timestamptz' }) - timestamps: Date; + public from_user_id!: string; - @OneToOne(() => Admin) + @OneToOne(() => Admin, (admin) => admin.user.id) @JoinColumn({ name: 'from_user_id' }) - user: Admin; + public from_user!: Admin; + + @OneToMany(() => Image, (image) => image.post) + public images: Image[]; } From dbd0fb51b79a2edf479fe537ddf47d8a5e2fb22a Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:08:16 +0300 Subject: [PATCH 07/26] Added new repos to init --- backend/src/modules/initialization/app.init.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/modules/initialization/app.init.service.ts b/backend/src/modules/initialization/app.init.service.ts index 8f7d27f..9361f3e 100644 --- a/backend/src/modules/initialization/app.init.service.ts +++ b/backend/src/modules/initialization/app.init.service.ts @@ -1,6 +1,8 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Admin } from 'libs/database/admin.entity'; +import { Image } from 'libs/database/image.entity'; +import { Post } from 'libs/database/post.entity'; import { User } from 'libs/database/user.entity'; import { Repository } from 'typeorm'; @@ -9,6 +11,8 @@ export class AppInitService implements OnModuleInit { constructor( @InjectRepository(User) private userRepository: Repository, @InjectRepository(Admin) private adminRepository: Repository, + @InjectRepository(Post) private postRepository: Repository, + @InjectRepository(Image) private ImageRepository: Repository, ) {} async onModuleInit() {} From ceedff498cbee4c85f0587647ffd5ef9414938f4 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:08:45 +0300 Subject: [PATCH 08/26] Search by user id --- backend/src/modules/admin/admin.service.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/modules/admin/admin.service.ts b/backend/src/modules/admin/admin.service.ts index f732c20..05c0faa 100644 --- a/backend/src/modules/admin/admin.service.ts +++ b/backend/src/modules/admin/admin.service.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; import { Admin } from 'libs/database/admin.entity'; +import { Repository } from 'typeorm'; @Injectable() export class AdminService { @@ -21,7 +21,8 @@ export class AdminService { try { this.logger.debug(`[admin.checkIsAdmin]`); const admins = await this.adminRepository.findOne({ - where: { user_id: id }, + relations: { user: true }, + where: { user: { id: id } }, }); if (!admins) { return false; From 266613b17ee0bab37e792e0cb22691c791f290fd Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:09:02 +0300 Subject: [PATCH 09/26] Rename to user --- backend/src/modules/user/user.controller.ts | 4 ++-- backend/src/modules/user/user.service.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/modules/user/user.controller.ts b/backend/src/modules/user/user.controller.ts index 8305e4a..7e8266f 100644 --- a/backend/src/modules/user/user.controller.ts +++ b/backend/src/modules/user/user.controller.ts @@ -6,13 +6,13 @@ import { UserService } from './user.service'; @ApiTags('User') @Controller('user') export class UserController { - constructor(private adminService: UserService) {} + constructor(private userService: UserService) {} @ApiOperation({ description: 'Create or get user from db', }) @Post('get') async getUser(@Body() data: IGetUser) { - return await this.adminService.getUser(data); + return await this.userService.getUser(data); } } diff --git a/backend/src/modules/user/user.service.ts b/backend/src/modules/user/user.service.ts index c334eb9..6854cbe 100644 --- a/backend/src/modules/user/user.service.ts +++ b/backend/src/modules/user/user.service.ts @@ -11,7 +11,7 @@ export class UserService { async getUser(data: IGetUser) { try { - this.logger.debug(`[admin.getUser] data: ${JSON.stringify(data)}`); + this.logger.debug(`[user.getUser] data: ${JSON.stringify(data)}`); let user = await this.userRepository.findOne({ where: { id: data.id }, }); @@ -21,7 +21,7 @@ export class UserService { } return user; } catch (error) { - this.logger.log(`[getUser] ${JSON.stringify({ error })}`); + this.logger.log(`[user.getUser] ${JSON.stringify({ error })}`); } } } From 489c51aac92852a18b765fd7d53cf554f557443d Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:09:53 +0300 Subject: [PATCH 10/26] Post controller --- backend/src/modules/post/post.controller.ts | 28 ++++++++++++ backend/src/modules/post/post.dto.ts | 9 ++++ backend/src/modules/post/post.module.ts | 11 +++++ backend/src/modules/post/post.service.ts | 50 +++++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 backend/src/modules/post/post.controller.ts create mode 100644 backend/src/modules/post/post.dto.ts create mode 100644 backend/src/modules/post/post.module.ts create mode 100644 backend/src/modules/post/post.service.ts diff --git a/backend/src/modules/post/post.controller.ts b/backend/src/modules/post/post.controller.ts new file mode 100644 index 0000000..d3fd697 --- /dev/null +++ b/backend/src/modules/post/post.controller.ts @@ -0,0 +1,28 @@ +import { Body, Controller, Get, Param, Post } from '@nestjs/common'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { ICreatePost } from './post.dto'; +import { PostService } from './post.service'; + +@ApiTags('Post') +@Controller('post') +export class PostController { + constructor(private postService: PostService) {} + + @ApiOperation({ description: 'Creates a new post' }) + @Post('new') + async newPost(@Body() data: ICreatePost) { + return await this.postService.newPost(data); + } + + @ApiOperation({ description: 'Getting all posts' }) + @Get('get-all') + async getAllPosts() { + return await this.postService.getAllPosts(); + } + + @ApiOperation({ description: 'Getting a post bu uuid' }) + @Get('get/:postId') + async getPost(@Param('postId') postId: string) { + return await this.postService.getPost(postId); + } +} diff --git a/backend/src/modules/post/post.dto.ts b/backend/src/modules/post/post.dto.ts new file mode 100644 index 0000000..9a794d0 --- /dev/null +++ b/backend/src/modules/post/post.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class ICreatePost { + @ApiProperty({ description: 'Post text', example: 'Post text' }) readonly text!: string; + + @ApiProperty({ description: 'An id of user that creating post', example: '1234' }) readonly from_user_id!: string; + + @ApiProperty({ description: 'Post media group id', example: '123' }) readonly media_group_id?: string; +} diff --git a/backend/src/modules/post/post.module.ts b/backend/src/modules/post/post.module.ts new file mode 100644 index 0000000..9cabfe0 --- /dev/null +++ b/backend/src/modules/post/post.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { LibsModule } from 'libs/libs.module'; +import { PostController } from './post.controller'; +import { PostService } from './post.service'; + +@Module({ + imports: [LibsModule], + controllers: [PostController], + providers: [PostService], +}) +export class PostModule {} diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts new file mode 100644 index 0000000..c3a347b --- /dev/null +++ b/backend/src/modules/post/post.service.ts @@ -0,0 +1,50 @@ +import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Admin } from 'libs/database/admin.entity'; +import { Post } from 'libs/database/post.entity'; +import { Repository } from 'typeorm'; +import { ICreatePost } from './post.dto'; + +@Injectable() +export class PostService { + private readonly logger: Logger = new Logger(PostService.name); + constructor( + @InjectRepository(Post) private postRepository: Repository, + @InjectRepository(Admin) private adminRepository: Repository, + ) {} + + async newPost(data: ICreatePost) { + try { + this.logger.log(`[post.newPost] data: ${JSON.stringify(data)}`); + const user = await this.adminRepository.findOne({ where: { user: { id: data.from_user_id } }, relations: { user: true } }); + const result = await this.postRepository.save({ + text: data.text, + media_group_id: data.media_group_id, + from_user: user, + timestamp: new Date(), + }); + this.logger.log(`Created new post: ${result.uuid}`); + return { result: 'ok' }; + } catch (error) { + this.logger.log(`[post.newPost] error: ${JSON.stringify(error)}`); + } + } + + async getAllPosts() { + try { + return await this.postRepository.find(); + } catch (error) { + this.logger.log(`[post.getAllPosts] error: ${JSON.stringify(error)}`); + } + } + + async getPost(postId: string) { + try { + this.logger.log(`[post.getPost] data: ${postId}`); + return await this.postRepository.findOne({ where: { uuid: postId } }); + } catch (error) { + this.logger.log(`[post.getPost] error: ${JSON.stringify(error)}`); + throw new HttpException('No post with this id', HttpStatus.NOT_FOUND); + } + } +} From e93ec7c8386576dc4d89019dacb7d35b701bc90f Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:10:07 +0300 Subject: [PATCH 11/26] Admin path to lowercase --- backend/src/modules/admin/admin.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/modules/admin/admin.controller.ts b/backend/src/modules/admin/admin.controller.ts index 6b643e5..780e239 100644 --- a/backend/src/modules/admin/admin.controller.ts +++ b/backend/src/modules/admin/admin.controller.ts @@ -3,7 +3,7 @@ import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { AdminService } from './admin.service'; @ApiTags('Admin') -@Controller('Admin') +@Controller('admin') export class AdminController { constructor(private adminService: AdminService) {} From fcf15d668f1b8d72c89d4af070f241aef6a2d85a Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 19:10:23 +0300 Subject: [PATCH 12/26] Added post module to app --- backend/src/app.module.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 8e1ff9d..dac3c0f 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -2,12 +2,13 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'; import { config } from 'config'; import { LibsModule } from 'libs/libs.module'; -import { AppInitService } from './modules/initialization/app.init.service'; -import { UserModule } from './modules/user/user.module'; import { AdminModule } from './modules/admin/admin.module'; +import { AppInitService } from './modules/initialization/app.init.service'; +import { PostModule } from './modules/post/post.module'; +import { UserModule } from './modules/user/user.module'; @Module({ - imports: [AdminModule, LibsModule, UserModule, TypeOrmModule.forRoot(config.database)], + imports: [LibsModule, PostModule, AdminModule, UserModule, TypeOrmModule.forRoot(config.database)], controllers: [], providers: [AppInitService], }) From 9ead1095a918a045d3cd730e05e2334d2c4d3f5f Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 21:51:29 +0300 Subject: [PATCH 13/26] Cascading entities --- backend/libs/database/admin.entity.ts | 2 +- backend/libs/database/image.entity.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/libs/database/admin.entity.ts b/backend/libs/database/admin.entity.ts index 8aa1a0b..a8d2bc7 100644 --- a/backend/libs/database/admin.entity.ts +++ b/backend/libs/database/admin.entity.ts @@ -13,7 +13,7 @@ export class Admin { @Column({ nullable: false }) public user_id!: string; - @OneToOne(() => User, (user) => user.id) + @OneToOne(() => User, (user) => user.id, { onDelete: 'CASCADE', onUpdate: 'CASCADE' }) @JoinColumn({ name: 'user_id' }) public user!: User; } diff --git a/backend/libs/database/image.entity.ts b/backend/libs/database/image.entity.ts index 376e811..14ca27d 100644 --- a/backend/libs/database/image.entity.ts +++ b/backend/libs/database/image.entity.ts @@ -1,4 +1,3 @@ -import { ApiProperty } from '@nestjs/swagger'; import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm'; import { Post } from './post.entity'; @@ -20,8 +19,7 @@ export class Image { @Column({ nullable: false }) public post_uuid!: string; - @ApiProperty({}) - @ManyToOne(() => Post, (post) => post.uuid) + @ManyToOne(() => Post, (post) => post.uuid, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'post_uuid' }) public post!: Post; } From dde2fc8994ba21f3acd23607a975819929710457 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 21:51:39 +0300 Subject: [PATCH 14/26] Changed foreign column --- backend/libs/database/post.entity.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/libs/database/post.entity.ts b/backend/libs/database/post.entity.ts index b38978f..f58dc2a 100644 --- a/backend/libs/database/post.entity.ts +++ b/backend/libs/database/post.entity.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn } from 'typeorm'; +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm'; import { Admin } from './admin.entity'; import { Image } from './image.entity'; @Entity() @@ -25,8 +25,8 @@ export class Post { @Column({ nullable: false }) public from_user_id!: string; - @OneToOne(() => Admin, (admin) => admin.user.id) - @JoinColumn({ name: 'from_user_id' }) + @ManyToOne(() => Admin, (admin) => admin.user.id) + @JoinColumn({ name: 'from_user_id', referencedColumnName: 'user_id' }) public from_user!: Admin; @OneToMany(() => Image, (image) => image.post) From 82c2ad53d6282ee2a1f5c60ae3e3b660e348b031 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 21:52:00 +0300 Subject: [PATCH 15/26] Some changes --- backend/src/modules/admin/admin.controller.ts | 2 +- backend/src/modules/admin/admin.service.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/src/modules/admin/admin.controller.ts b/backend/src/modules/admin/admin.controller.ts index 780e239..411a9b5 100644 --- a/backend/src/modules/admin/admin.controller.ts +++ b/backend/src/modules/admin/admin.controller.ts @@ -15,7 +15,7 @@ export class AdminController { return await this.adminService.getAdmins(); } @ApiOperation({ description: 'Check admin is or not' }) - @Get('is_admin/:id') + @Get('is-admin/:id') async isAdmin(@Param('id') id: string) { return await this.adminService.checkIsAdmin(id); } diff --git a/backend/src/modules/admin/admin.service.ts b/backend/src/modules/admin/admin.service.ts index 05c0faa..cfd9557 100644 --- a/backend/src/modules/admin/admin.service.ts +++ b/backend/src/modules/admin/admin.service.ts @@ -15,6 +15,7 @@ export class AdminService { return admins; } catch (error) { this.logger.log(`[getAdmin] ${JSON.stringify({ error })}`); + return []; } } async checkIsAdmin(id: string) { @@ -29,7 +30,8 @@ export class AdminService { } return true; } catch (error) { - this.logger.log(`[checkIsAdmin] ${JSON.stringify({ error })}`); + this.logger.debug(`[checkIsAdmin] ${JSON.stringify({ error })}`); + return false; } } } From ac6090824fb56ec4b750d68e32ebf7cfcfaab17f Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 21:53:00 +0300 Subject: [PATCH 16/26] Added image module --- backend/src/app.module.ts | 3 ++- backend/src/modules/image/image.controller.ts | 16 ++++++++++++ backend/src/modules/image/image.dto.ts | 8 ++++++ backend/src/modules/image/image.module.ts | 11 ++++++++ backend/src/modules/image/image.service.ts | 26 +++++++++++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 backend/src/modules/image/image.controller.ts create mode 100644 backend/src/modules/image/image.dto.ts create mode 100644 backend/src/modules/image/image.module.ts create mode 100644 backend/src/modules/image/image.service.ts diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index dac3c0f..65d3643 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -3,12 +3,13 @@ import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'; import { config } from 'config'; import { LibsModule } from 'libs/libs.module'; import { AdminModule } from './modules/admin/admin.module'; +import { ImageModule } from './modules/image/image.module'; import { AppInitService } from './modules/initialization/app.init.service'; import { PostModule } from './modules/post/post.module'; import { UserModule } from './modules/user/user.module'; @Module({ - imports: [LibsModule, PostModule, AdminModule, UserModule, TypeOrmModule.forRoot(config.database)], + imports: [LibsModule, PostModule, AdminModule, UserModule, ImageModule, TypeOrmModule.forRoot(config.database)], controllers: [], providers: [AppInitService], }) diff --git a/backend/src/modules/image/image.controller.ts b/backend/src/modules/image/image.controller.ts new file mode 100644 index 0000000..d83fbb4 --- /dev/null +++ b/backend/src/modules/image/image.controller.ts @@ -0,0 +1,16 @@ +import { Body, Controller, Post } from '@nestjs/common'; +import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { IAddImage } from './image.dto'; +import { ImageService } from './image.service'; + +@ApiTags('Image') +@Controller('image') +export class ImageController { + constructor(private imageService: ImageService) {} + + @ApiOperation({ description: 'A method to add photo to post' }) + @Post('add') + async addImage(@Body() data: IAddImage) { + return await this.imageService.add(data); + } +} diff --git a/backend/src/modules/image/image.dto.ts b/backend/src/modules/image/image.dto.ts new file mode 100644 index 0000000..8a027b6 --- /dev/null +++ b/backend/src/modules/image/image.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class IAddImage { + @ApiProperty({ description: 'A post that contains this photo', example: '1212-4324-asdf-23432' }) readonly post_id!: string; + @ApiProperty({ description: 'A telegram file id of photo', example: '1214244' }) readonly file_id!: string; + @ApiProperty({ description: 'Has image the spoiler?', example: false }) readonly has_spoiler!: boolean; + @ApiProperty({ description: 'A photo message id', example: '123124' }) readonly message_id!: number; +} diff --git a/backend/src/modules/image/image.module.ts b/backend/src/modules/image/image.module.ts new file mode 100644 index 0000000..2c8c6c1 --- /dev/null +++ b/backend/src/modules/image/image.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { LibsModule } from 'libs/libs.module'; +import { ImageController } from './image.controller'; +import { ImageService } from './image.service'; + +@Module({ + imports: [LibsModule], + controllers: [ImageController], + providers: [ImageService], +}) +export class ImageModule {} diff --git a/backend/src/modules/image/image.service.ts b/backend/src/modules/image/image.service.ts new file mode 100644 index 0000000..b2e4818 --- /dev/null +++ b/backend/src/modules/image/image.service.ts @@ -0,0 +1,26 @@ +import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Image } from 'libs/database/image.entity'; +import { Post } from 'libs/database/post.entity'; +import { Repository } from 'typeorm'; +import { IAddImage } from './image.dto'; +@Injectable() +export class ImageService { + private readonly logger: Logger = new Logger(ImageService.name); + constructor( + @InjectRepository(Image) private imageRepository: Repository, + @InjectRepository(Post) private postRepository: Repository, + ) {} + + async add(data: IAddImage) { + try { + this.logger.log(`[image.add] data: ${JSON.stringify(data)}`); + const post = await this.postRepository.findOne({ where: { uuid: data.post_id } }); + await this.imageRepository.save({ post: post, file_id: data.file_id, has_spoiler: data.has_spoiler, message_id: data.message_id }); + return { status: 'ok' }; + } catch (error) { + this.logger.debug(`[image.add] error: ${JSON.stringify(error)}`); + throw new HttpException('No posts', HttpStatus.BAD_REQUEST); + } + } +} From 78dd2baf4f973514166a15f483860e261e75d8a7 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Mon, 20 Nov 2023 21:53:36 +0300 Subject: [PATCH 17/26] Some post module changes --- backend/src/modules/post/post.controller.ts | 11 +++++----- backend/src/modules/post/post.service.ts | 24 ++++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/backend/src/modules/post/post.controller.ts b/backend/src/modules/post/post.controller.ts index d3fd697..0bea36c 100644 --- a/backend/src/modules/post/post.controller.ts +++ b/backend/src/modules/post/post.controller.ts @@ -1,5 +1,5 @@ import { Body, Controller, Get, Param, Post } from '@nestjs/common'; -import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; import { ICreatePost } from './post.dto'; import { PostService } from './post.service'; @@ -14,10 +14,11 @@ export class PostController { return await this.postService.newPost(data); } - @ApiOperation({ description: 'Getting all posts' }) - @Get('get-all') - async getAllPosts() { - return await this.postService.getAllPosts(); + @ApiOperation({ description: 'Getting all posts. By default - all' }) + @Get('get-all/:status') + @ApiParam({ name: 'status', required: false, enum: ['will-post', 'all', 'posted'] }) + async getAllPosts(@Param('status') status?: 'will-post' | 'all' | 'posted') { + return await this.postService.getAllPosts(status || 'all'); } @ApiOperation({ description: 'Getting a post bu uuid' }) diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts index c3a347b..4f4310a 100644 --- a/backend/src/modules/post/post.service.ts +++ b/backend/src/modules/post/post.service.ts @@ -24,24 +24,38 @@ export class PostService { timestamp: new Date(), }); this.logger.log(`Created new post: ${result.uuid}`); - return { result: 'ok' }; + return { status: 'ok' }; } catch (error) { - this.logger.log(`[post.newPost] error: ${JSON.stringify(error)}`); + this.logger.debug(`[post.newPost] error: ${JSON.stringify(error)}`); + throw new HttpException('No user with this id', HttpStatus.BAD_REQUEST); } } - async getAllPosts() { + async getAllPosts(status: 'will-post' | 'all' | 'posted') { try { - return await this.postRepository.find(); + let obj: object; + switch (status) { + case 'will-post': + obj = { where: { posted: false } }; + break; + case 'all': + obj = {}; + break; + case 'posted': + obj = { where: { posted: true } }; + break; + } + return await this.postRepository.find(obj); } catch (error) { this.logger.log(`[post.getAllPosts] error: ${JSON.stringify(error)}`); + return []; } } async getPost(postId: string) { try { this.logger.log(`[post.getPost] data: ${postId}`); - return await this.postRepository.findOne({ where: { uuid: postId } }); + return await this.postRepository.findOne({ where: { uuid: postId }, relations: { images: true } }); } catch (error) { this.logger.log(`[post.getPost] error: ${JSON.stringify(error)}`); throw new HttpException('No post with this id', HttpStatus.NOT_FOUND); From d5806035f027174e2ede1c1f4aad225cf61e48fa Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 14:52:54 +0300 Subject: [PATCH 18/26] Added bot submodule --- .gitmodules | 3 +++ neuro-reply-bot-reworked | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 neuro-reply-bot-reworked diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3ddbe20 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "neuro-reply-bot-reworked"] + path = neuro-reply-bot-reworked + url = git@github.com:MrSedan/neuro-reply-bot-reworked.git diff --git a/neuro-reply-bot-reworked b/neuro-reply-bot-reworked new file mode 160000 index 0000000..18a5a2c --- /dev/null +++ b/neuro-reply-bot-reworked @@ -0,0 +1 @@ +Subproject commit 18a5a2c1e821c9a8a2056cd2a3f0351308f16f83 From 5420bd5d0583f8f0049f967f98295cd9e6a194bc Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 15:00:47 +0300 Subject: [PATCH 19/26] Changed to dev branch --- .gitmodules | 1 + neuro-reply-bot-reworked | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3ddbe20..adf5066 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "neuro-reply-bot-reworked"] path = neuro-reply-bot-reworked url = git@github.com:MrSedan/neuro-reply-bot-reworked.git + branch = dev \ No newline at end of file diff --git a/neuro-reply-bot-reworked b/neuro-reply-bot-reworked index 18a5a2c..d286da6 160000 --- a/neuro-reply-bot-reworked +++ b/neuro-reply-bot-reworked @@ -1 +1 @@ -Subproject commit 18a5a2c1e821c9a8a2056cd2a3f0351308f16f83 +Subproject commit d286da698e06a5bfa57131327db10d1fc716eea5 From bee4ffb9eba6bde9bdbd332308e1a0e778c55c76 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 19:27:42 +0300 Subject: [PATCH 20/26] Moved .env to root --- backend/.env.example => .env.example | 0 docker-compose.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename backend/.env.example => .env.example (100%) diff --git a/backend/.env.example b/.env.example similarity index 100% rename from backend/.env.example rename to .env.example diff --git a/docker-compose.yml b/docker-compose.yml index 90b9958..6da560a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: ports: - "${DATABASE_PORT}:5432" env_file: - - ./backend/.env + - .env volumes: - neuro_postgres_db:/var/lib/postgresql/data restart: always From d143d90bb0081b7320d7a99449d1f85d01b07e9b Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 19:57:15 +0300 Subject: [PATCH 21/26] Changed .env path --- backend/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/config/index.ts b/backend/config/index.ts index 280614f..c359859 100644 --- a/backend/config/index.ts +++ b/backend/config/index.ts @@ -1,6 +1,6 @@ import { config as configInit } from 'dotenv'; -configInit(); +configInit({ path: '../.env' }); export const config = { database: { From 78b7879371ef3faad8bdb69bb37cae1725d4ed85 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 19:57:32 +0300 Subject: [PATCH 22/26] Added getting post by its media group id --- backend/src/modules/post/post.controller.ts | 6 ++++++ backend/src/modules/post/post.service.ts | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/backend/src/modules/post/post.controller.ts b/backend/src/modules/post/post.controller.ts index 0bea36c..29b33f5 100644 --- a/backend/src/modules/post/post.controller.ts +++ b/backend/src/modules/post/post.controller.ts @@ -26,4 +26,10 @@ export class PostController { async getPost(@Param('postId') postId: string) { return await this.postService.getPost(postId); } + + @ApiOperation({ description: 'Getting a post by its media group id' }) + @Get('get-by-media-group-id/:mediaGroupId') + async getByMediaGroup(@Param('mediaGroupId') mediaGroupId: string) { + return await this.postService.getByMediaGroup(mediaGroupId); + } } diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts index 4f4310a..26f95ec 100644 --- a/backend/src/modules/post/post.service.ts +++ b/backend/src/modules/post/post.service.ts @@ -61,4 +61,14 @@ export class PostService { throw new HttpException('No post with this id', HttpStatus.NOT_FOUND); } } + + async getByMediaGroup(mediaGroupId: string) { + try { + this.logger.log(`[post.getByMediaGroup] data: ${mediaGroupId}`); + return await this.postRepository.findOne({ where: { media_group_id: mediaGroupId } }); + } catch (error) { + this.logger.debug(`[post.getByMediaGroup] error: ${JSON.stringify(error)}`); + throw new HttpException("Can't find post with this media group id", HttpStatus.BAD_REQUEST); + } + } } From 18669bd60816901b24864ce071e76e1c022c295d Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 19:59:15 +0300 Subject: [PATCH 23/26] Change end of file in prettier --- .prettierrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index ece7630..5368c51 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,6 @@ "semi": true, "tabWidth": 4, "printWidth": 150, - "bracketSpacing": true + "bracketSpacing": true, + "endOfLine": "lf" } From a17a06cbac5a90c25089b98d7347455d404c46aa Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 21 Nov 2023 20:06:34 +0300 Subject: [PATCH 24/26] Can't finding post error --- backend/src/modules/post/post.service.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts index 26f95ec..e1e1924 100644 --- a/backend/src/modules/post/post.service.ts +++ b/backend/src/modules/post/post.service.ts @@ -55,7 +55,9 @@ export class PostService { async getPost(postId: string) { try { this.logger.log(`[post.getPost] data: ${postId}`); - return await this.postRepository.findOne({ where: { uuid: postId }, relations: { images: true } }); + const post = await this.postRepository.findOne({ where: { uuid: postId }, relations: { images: true } }); + if (!post) throw new Error("Can't find post"); + return post; } catch (error) { this.logger.log(`[post.getPost] error: ${JSON.stringify(error)}`); throw new HttpException('No post with this id', HttpStatus.NOT_FOUND); @@ -65,7 +67,9 @@ export class PostService { async getByMediaGroup(mediaGroupId: string) { try { this.logger.log(`[post.getByMediaGroup] data: ${mediaGroupId}`); - return await this.postRepository.findOne({ where: { media_group_id: mediaGroupId } }); + const post = await this.postRepository.findOne({ where: { media_group_id: mediaGroupId } }); + if (!post) throw new Error("Can't find post"); + return post; } catch (error) { this.logger.debug(`[post.getByMediaGroup] error: ${JSON.stringify(error)}`); throw new HttpException("Can't find post with this media group id", HttpStatus.BAD_REQUEST); From ac778289d0e7f0bb219cd2fad609f1e70daefd6a Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Wed, 22 Nov 2023 17:36:05 +0300 Subject: [PATCH 25/26] Moved to use enum --- backend/libs/enums/getAll.enum.ts | 5 +++++ backend/src/modules/post/post.controller.ts | 7 ++++--- backend/src/modules/post/post.service.ts | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 backend/libs/enums/getAll.enum.ts diff --git a/backend/libs/enums/getAll.enum.ts b/backend/libs/enums/getAll.enum.ts new file mode 100644 index 0000000..814872b --- /dev/null +++ b/backend/libs/enums/getAll.enum.ts @@ -0,0 +1,5 @@ +export enum EGetAll { + all = 'all', + will_post = 'will-post', + posted = 'posted', +} diff --git a/backend/src/modules/post/post.controller.ts b/backend/src/modules/post/post.controller.ts index 29b33f5..6ed54d7 100644 --- a/backend/src/modules/post/post.controller.ts +++ b/backend/src/modules/post/post.controller.ts @@ -1,5 +1,6 @@ import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; +import { EGetAll } from 'libs/enums/getAll.enum'; import { ICreatePost } from './post.dto'; import { PostService } from './post.service'; @@ -16,9 +17,9 @@ export class PostController { @ApiOperation({ description: 'Getting all posts. By default - all' }) @Get('get-all/:status') - @ApiParam({ name: 'status', required: false, enum: ['will-post', 'all', 'posted'] }) - async getAllPosts(@Param('status') status?: 'will-post' | 'all' | 'posted') { - return await this.postService.getAllPosts(status || 'all'); + @ApiParam({ name: 'status', required: false, enum: EGetAll }) + async getAllPosts(@Param('status') status?: EGetAll) { + return await this.postService.getAllPosts(status || EGetAll.all); } @ApiOperation({ description: 'Getting a post bu uuid' }) diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts index e1e1924..394b036 100644 --- a/backend/src/modules/post/post.service.ts +++ b/backend/src/modules/post/post.service.ts @@ -2,6 +2,7 @@ import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Admin } from 'libs/database/admin.entity'; import { Post } from 'libs/database/post.entity'; +import { EGetAll } from 'libs/enums/getAll.enum'; import { Repository } from 'typeorm'; import { ICreatePost } from './post.dto'; @@ -31,17 +32,17 @@ export class PostService { } } - async getAllPosts(status: 'will-post' | 'all' | 'posted') { + async getAllPosts(status: EGetAll) { try { let obj: object; switch (status) { - case 'will-post': + case EGetAll.will_post: obj = { where: { posted: false } }; break; - case 'all': + case EGetAll.all: obj = {}; break; - case 'posted': + case EGetAll.posted: obj = { where: { posted: true } }; break; } From 11f2dd71eb97009b8f12addbd30420b5a8817d21 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Wed, 22 Nov 2023 20:59:26 +0300 Subject: [PATCH 26/26] Added post editing --- backend/src/modules/post/post.controller.ts | 10 +++++++-- backend/src/modules/post/post.dto.ts | 4 ++++ backend/src/modules/post/post.service.ts | 23 +++++++++++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/backend/src/modules/post/post.controller.ts b/backend/src/modules/post/post.controller.ts index 6ed54d7..12953f9 100644 --- a/backend/src/modules/post/post.controller.ts +++ b/backend/src/modules/post/post.controller.ts @@ -1,7 +1,7 @@ import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; import { EGetAll } from 'libs/enums/getAll.enum'; -import { ICreatePost } from './post.dto'; +import { ICreatePost, IEditPost } from './post.dto'; import { PostService } from './post.service'; @ApiTags('Post') @@ -22,7 +22,7 @@ export class PostController { return await this.postService.getAllPosts(status || EGetAll.all); } - @ApiOperation({ description: 'Getting a post bu uuid' }) + @ApiOperation({ description: 'Getting a post by uuid' }) @Get('get/:postId') async getPost(@Param('postId') postId: string) { return await this.postService.getPost(postId); @@ -33,4 +33,10 @@ export class PostController { async getByMediaGroup(@Param('mediaGroupId') mediaGroupId: string) { return await this.postService.getByMediaGroup(mediaGroupId); } + + @ApiOperation({ description: 'Editing a post by its uuid' }) + @Post('edit/:postId') + async editPost(@Param('postId') postId: string, @Body() data: IEditPost) { + return await this.postService.editPost(postId, data); + } } diff --git a/backend/src/modules/post/post.dto.ts b/backend/src/modules/post/post.dto.ts index 9a794d0..9c94994 100644 --- a/backend/src/modules/post/post.dto.ts +++ b/backend/src/modules/post/post.dto.ts @@ -7,3 +7,7 @@ export class ICreatePost { @ApiProperty({ description: 'Post media group id', example: '123' }) readonly media_group_id?: string; } + +export class IEditPost { + @ApiProperty({ description: 'Post text', example: 'Post text' }) readonly text!: string; +} diff --git a/backend/src/modules/post/post.service.ts b/backend/src/modules/post/post.service.ts index 394b036..34045e1 100644 --- a/backend/src/modules/post/post.service.ts +++ b/backend/src/modules/post/post.service.ts @@ -4,7 +4,7 @@ import { Admin } from 'libs/database/admin.entity'; import { Post } from 'libs/database/post.entity'; import { EGetAll } from 'libs/enums/getAll.enum'; import { Repository } from 'typeorm'; -import { ICreatePost } from './post.dto'; +import { ICreatePost, IEditPost } from './post.dto'; @Injectable() export class PostService { @@ -25,13 +25,32 @@ export class PostService { timestamp: new Date(), }); this.logger.log(`Created new post: ${result.uuid}`); - return { status: 'ok' }; + return result; } catch (error) { this.logger.debug(`[post.newPost] error: ${JSON.stringify(error)}`); throw new HttpException('No user with this id', HttpStatus.BAD_REQUEST); } } + async editPost(postId: string, data: IEditPost) { + try { + this.logger.log(`[post.editPost] data: ${JSON.stringify(data)}`); + const post = await this.postRepository.findOne({ where: { uuid: postId } }); + if (!post) { + throw new HttpException('Post not found', HttpStatus.NOT_FOUND); + } + if (post.text !== data.text) { + post.text = data.text; + post.timestamp = new Date(); + await this.postRepository.save(post); + } + return post; + } catch (error) { + this.logger.debug(`[post.editPost] error: ${JSON.stringify(error)}`); + throw new HttpException('Post not found', HttpStatus.NOT_FOUND); + } + } + async getAllPosts(status: EGetAll) { try { let obj: object;