Showing
18 changed files
with
356 additions
and
21 deletions
No preview for this file type
... | @@ -8,7 +8,6 @@ import { MypageModule } from './mypage/mypage.module' | ... | @@ -8,7 +8,6 @@ import { MypageModule } from './mypage/mypage.module' |
8 | import { PostModule } from './post/post.module' | 8 | import { PostModule } from './post/post.module' |
9 | import { CommentModule } from './comment/comment.module' | 9 | import { CommentModule } from './comment/comment.module' |
10 | import { UserModule } from './user/user.module' | 10 | import { UserModule } from './user/user.module' |
11 | -import { LikeableService } from './likeable/likeable.service' | ||
12 | import { LikeableModule } from './likeable/likeable.module' | 11 | import { LikeableModule } from './likeable/likeable.module' |
13 | 12 | ||
14 | @Module({ | 13 | @Module({ |
... | @@ -31,6 +30,6 @@ import { LikeableModule } from './likeable/likeable.module' | ... | @@ -31,6 +30,6 @@ import { LikeableModule } from './likeable/likeable.module' |
31 | LikeableModule, | 30 | LikeableModule, |
32 | ], | 31 | ], |
33 | controllers: [AppController], | 32 | controllers: [AppController], |
34 | - providers: [AppService, LikeableService], | 33 | + providers: [AppService], |
35 | }) | 34 | }) |
36 | export class AppModule {} | 35 | export class AppModule {} | ... | ... |
File mode changed
1 | import { Module } from '@nestjs/common' | 1 | import { Module } from '@nestjs/common' |
2 | import { CommentService } from './comment.service' | 2 | import { CommentService } from './comment.service' |
3 | import { CommentResolver } from './comment.resolver' | 3 | import { CommentResolver } from './comment.resolver' |
4 | +import { TypeOrmModule } from '@nestjs/typeorm' | ||
5 | +import { Comment } from './model/comment.entity' | ||
4 | 6 | ||
5 | @Module({ | 7 | @Module({ |
8 | + imports: [TypeOrmModule.forFeature([Comment])], | ||
6 | providers: [CommentService, CommentResolver], | 9 | providers: [CommentService, CommentResolver], |
7 | }) | 10 | }) |
8 | export class CommentModule {} | 11 | export class CommentModule {} | ... | ... |
1 | -import { Resolver } from '@nestjs/graphql' | 1 | +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' |
2 | +import { CommentService } from './comment.service' | ||
3 | +import { Comment } from './model/comment.entity' | ||
4 | +import { CreateCommentInput, GetCommentInput } from './dto/comment.input' | ||
2 | 5 | ||
3 | -@Resolver() | 6 | +@Resolver((of) => Comment) |
4 | -export class CommentResolver {} | 7 | +export class CommentResolver { |
8 | + constructor(private commentService: CommentService) {} | ||
9 | + | ||
10 | + @Query((returns) => [Comment]) | ||
11 | + getAllComments(): Promise<Comment[]> { | ||
12 | + return this.commentService.findAll() | ||
13 | + } | ||
14 | + | ||
15 | + @Query((returns) => [Comment]) | ||
16 | + getSomeComments(@Args('input') input: GetCommentInput): Promise<Comment[]> { | ||
17 | + return this.commentService.findSome(input) | ||
18 | + } | ||
19 | + | ||
20 | + @Query((returns) => Comment) | ||
21 | + getComment(@Args('id') id: number): Promise<Comment> { | ||
22 | + return this.commentService.findOne(id) | ||
23 | + } | ||
24 | + | ||
25 | + @Mutation(() => Comment, { name: 'createComment' }) | ||
26 | + createComment(@Args('input') input: CreateCommentInput): Promise<Comment> { | ||
27 | + return this.commentService.createOne(input) | ||
28 | + } | ||
29 | +} | ... | ... |
1 | import { Injectable } from '@nestjs/common' | 1 | import { Injectable } from '@nestjs/common' |
2 | +import { InjectRepository } from '@nestjs/typeorm' | ||
3 | +import { QueryRunner, Repository, getConnection } from 'typeorm' | ||
4 | +import { Comment } from './model/comment.entity' | ||
5 | +import { getCurrentDate } from '../shared/utils' | ||
6 | +import { CreateCommentInput, GetCommentInput } from './dto/comment.input' | ||
7 | +import { MASTER_TEST } from 'src/shared/const' | ||
2 | 8 | ||
3 | @Injectable() | 9 | @Injectable() |
4 | -export class CommentService {} | 10 | +export class CommentService { |
11 | + constructor( | ||
12 | + @InjectRepository(Comment) private commentRepository: Repository<Comment>, | ||
13 | + ) {} | ||
14 | + private connection = getConnection() | ||
15 | + | ||
16 | + async findAll(): Promise<Comment[]> { | ||
17 | + return this.commentRepository.find() | ||
18 | + } | ||
19 | + | ||
20 | + async findOne(id: number): Promise<Comment> { | ||
21 | + return this.commentRepository.findOne(id) | ||
22 | + } | ||
23 | + | ||
24 | + async findSome(input: Partial<GetCommentInput>): Promise<Comment[]> { | ||
25 | + return this.commentRepository | ||
26 | + .createQueryBuilder('comment') | ||
27 | + .where('comment.post_id = :post_id', { post_id: input.post_id }) | ||
28 | + .orWhere('comment.author = :author', { author: input.author }) | ||
29 | + .orWhere('comment.parent = :parent', { parent: input.parent }) | ||
30 | + .getMany() | ||
31 | + } | ||
32 | + | ||
33 | + async createOne(input: CreateCommentInput): Promise<Comment> { | ||
34 | + let result | ||
35 | + const queryRunner: QueryRunner = this.connection.createQueryRunner() | ||
36 | + await queryRunner.connect() | ||
37 | + await queryRunner.startTransaction() | ||
38 | + | ||
39 | + try { | ||
40 | + const newInput = { | ||
41 | + ...input, | ||
42 | + created_date: getCurrentDate(), | ||
43 | + author: MASTER_TEST, | ||
44 | + } | ||
45 | + result = await queryRunner.manager.save( | ||
46 | + this.commentRepository.create(newInput), | ||
47 | + ) | ||
48 | + await queryRunner.commitTransaction() | ||
49 | + } catch (err) { | ||
50 | + await queryRunner.rollbackTransaction() | ||
51 | + throw err | ||
52 | + } finally { | ||
53 | + await queryRunner.release() | ||
54 | + } | ||
55 | + | ||
56 | + return result | ||
57 | + } | ||
58 | +} | ... | ... |
1 | +import { Field, InputType, PickType } from '@nestjs/graphql' | ||
2 | +import { Comment } from '../model/comment.entity' | ||
3 | + | ||
4 | +@InputType() | ||
5 | +export class GetCommentInput { | ||
6 | + @Field({ nullable: true }) | ||
7 | + post_id?: number | ||
8 | + | ||
9 | + @Field({ nullable: true }) | ||
10 | + author?: string | ||
11 | + | ||
12 | + @Field({ nullable: true }) | ||
13 | + parent?: string | ||
14 | +} | ||
15 | + | ||
16 | +@InputType() | ||
17 | +export class CreateCommentInput extends PickType( | ||
18 | + Comment, | ||
19 | + ['post_id', 'content'], | ||
20 | + InputType, | ||
21 | +) { | ||
22 | + @Field({ nullable: true }) | ||
23 | + parent?: number | ||
24 | +} | ... | ... |
1 | +/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
2 | +import { ObjectType, Field, Int } from '@nestjs/graphql' | ||
3 | +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm' | ||
4 | + | ||
5 | +@Entity({ name: 'comment' }) | ||
6 | +@ObjectType() | ||
7 | +export class Comment { | ||
8 | + @PrimaryGeneratedColumn() | ||
9 | + @Field((type) => Int) | ||
10 | + id: number | ||
11 | + | ||
12 | + @Column() | ||
13 | + @Field() | ||
14 | + author: string | ||
15 | + | ||
16 | + @Column() | ||
17 | + @Field((type) => Int) | ||
18 | + post_id: number | ||
19 | + | ||
20 | + @Column() | ||
21 | + @Field((type) => Int) | ||
22 | + parent: number | ||
23 | + | ||
24 | + @Column() | ||
25 | + @Field() | ||
26 | + content: string | ||
27 | + | ||
28 | + @Column() | ||
29 | + @Field() | ||
30 | + created_date: string | ||
31 | + | ||
32 | + @Column({ nullable: true }) | ||
33 | + @Field({ nullable: true }) | ||
34 | + updated_date?: string | ||
35 | +} |
1 | +import { Field, InputType, PickType } from '@nestjs/graphql' | ||
2 | +import { Likeable } from '../model/likeable.entity' | ||
3 | + | ||
4 | +@InputType() | ||
5 | +export class GetLikeableInput { | ||
6 | + @Field({ nullable: true }) | ||
7 | + likeable_id?: number | ||
8 | + | ||
9 | + @Field({ nullable: true }) | ||
10 | + user_id?: string | ||
11 | + | ||
12 | + @Field() | ||
13 | + likeable_type: string | ||
14 | +} | ||
15 | + | ||
16 | +@InputType() | ||
17 | +export class CreateLikeableInput extends PickType( | ||
18 | + Likeable, | ||
19 | + ['likeable_id', 'like_dislike', 'likeable_type'], | ||
20 | + InputType, | ||
21 | +) {} | ... | ... |
File mode changed
1 | import { Module } from '@nestjs/common' | 1 | import { Module } from '@nestjs/common' |
2 | import { LikeableResolver } from './likeable.resolver' | 2 | import { LikeableResolver } from './likeable.resolver' |
3 | +import { LikeableService } from './likeable.service' | ||
4 | +import { TypeOrmModule } from '@nestjs/typeorm' | ||
5 | +import { Likeable } from './model/likeable.entity' | ||
3 | 6 | ||
4 | @Module({ | 7 | @Module({ |
5 | - providers: [LikeableResolver], | 8 | + imports: [TypeOrmModule.forFeature([Likeable])], |
9 | + providers: [LikeableService, LikeableResolver], | ||
6 | }) | 10 | }) |
7 | export class LikeableModule {} | 11 | export class LikeableModule {} | ... | ... |
1 | -import { Resolver } from '@nestjs/graphql' | 1 | +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' |
2 | +import { CreateLikeableInput, GetLikeableInput } from './dto/likeable.input' | ||
3 | +import { LikeableService } from './likeable.service' | ||
4 | +import { Likeable } from './model/likeable.entity' | ||
2 | 5 | ||
3 | -@Resolver() | 6 | +@Resolver((of) => Likeable) |
4 | -export class LikeableResolver {} | 7 | +export class LikeableResolver { |
8 | + constructor(private likeableService: LikeableService) {} | ||
9 | + | ||
10 | + @Query((returns) => [Likeable]) | ||
11 | + getAllLikes(): Promise<Likeable[]> { | ||
12 | + return this.likeableService.findAll() | ||
13 | + } | ||
14 | + | ||
15 | + @Query((returns) => Number) | ||
16 | + getTotalLikes(@Args('input') input: GetLikeableInput): Promise<number> { | ||
17 | + return this.likeableService.findSome(input).then((res) => res.length) | ||
18 | + } | ||
19 | + | ||
20 | + @Query((returns) => Likeable) | ||
21 | + getLikeable(@Args('id') id: number): Promise<Likeable> { | ||
22 | + return this.likeableService.findOne(id) | ||
23 | + } | ||
24 | + | ||
25 | + @Mutation(() => Likeable, { name: 'createLikeable' }) | ||
26 | + createLikeable(@Args('input') input: CreateLikeableInput): Promise<Likeable> { | ||
27 | + return this.likeableService.createOne(input) | ||
28 | + } | ||
29 | +} | ... | ... |
1 | -import { Test, TestingModule } from '@nestjs/testing'; | 1 | +import { Test, TestingModule } from '@nestjs/testing' |
2 | -import { LikeableService } from './likeable.service'; | 2 | +import { LikeableService } from './likeable.service' |
3 | 3 | ||
4 | describe('LikeableService', () => { | 4 | describe('LikeableService', () => { |
5 | - let service: LikeableService; | 5 | + let service: LikeableService |
6 | 6 | ||
7 | beforeEach(async () => { | 7 | beforeEach(async () => { |
8 | const module: TestingModule = await Test.createTestingModule({ | 8 | const module: TestingModule = await Test.createTestingModule({ |
9 | providers: [LikeableService], | 9 | providers: [LikeableService], |
10 | - }).compile(); | 10 | + }).compile() |
11 | 11 | ||
12 | - service = module.get<LikeableService>(LikeableService); | 12 | + service = module.get<LikeableService>(LikeableService) |
13 | - }); | 13 | + }) |
14 | 14 | ||
15 | it('should be defined', () => { | 15 | it('should be defined', () => { |
16 | - expect(service).toBeDefined(); | 16 | + expect(service).toBeDefined() |
17 | - }); | 17 | + }) |
18 | -}); | 18 | +}) | ... | ... |
1 | import { Injectable } from '@nestjs/common' | 1 | import { Injectable } from '@nestjs/common' |
2 | +import { InjectRepository } from '@nestjs/typeorm' | ||
3 | +import { QueryRunner, Repository, getConnection } from 'typeorm' | ||
4 | +import { Likeable } from './model/likeable.entity' | ||
5 | +import { getCurrentDate } from '../shared/utils' | ||
6 | +import { GetLikeableInput, CreateLikeableInput } from './dto/likeable.input' | ||
7 | +import { MASTER_TEST } from 'src/shared/const' | ||
2 | 8 | ||
3 | @Injectable() | 9 | @Injectable() |
4 | -export class LikeableService {} | 10 | +export class LikeableService { |
11 | + constructor( | ||
12 | + @InjectRepository(Likeable) | ||
13 | + private likeableRepository: Repository<Likeable>, | ||
14 | + ) {} | ||
15 | + private connection = getConnection() | ||
16 | + | ||
17 | + async findAll(): Promise<Likeable[]> { | ||
18 | + return this.likeableRepository.find() | ||
19 | + } | ||
20 | + | ||
21 | + async findOne(id: number): Promise<Likeable> { | ||
22 | + return this.likeableRepository.findOne(id) | ||
23 | + } | ||
24 | + | ||
25 | + async findSome(input: Partial<GetLikeableInput>): Promise<Likeable[]> { | ||
26 | + return this.likeableRepository | ||
27 | + .createQueryBuilder('likeable') | ||
28 | + .where('likeable.user_id = :user_id', { user_id: input.user_id }) | ||
29 | + .orWhere('likeable.likeable_id = :likeable_id', { | ||
30 | + likeable_id: input.likeable_id, | ||
31 | + }) | ||
32 | + .andWhere('likeable.likeable_type = :likeable_type', { | ||
33 | + likeable_type: input.likeable_type, | ||
34 | + }) | ||
35 | + .getMany() | ||
36 | + } | ||
37 | + | ||
38 | + async createOne(input: CreateLikeableInput): Promise<Likeable> { | ||
39 | + let result | ||
40 | + const queryRunner: QueryRunner = this.connection.createQueryRunner() | ||
41 | + await queryRunner.connect() | ||
42 | + await queryRunner.startTransaction() | ||
43 | + | ||
44 | + try { | ||
45 | + const newInput = { | ||
46 | + ...input, | ||
47 | + like_dislike: input.like_dislike > 0 ? 1 : -1, | ||
48 | + user_id: MASTER_TEST, | ||
49 | + created_date: getCurrentDate(), | ||
50 | + } | ||
51 | + result = await queryRunner.manager.save( | ||
52 | + this.likeableRepository.create(newInput), | ||
53 | + ) | ||
54 | + await queryRunner.commitTransaction() | ||
55 | + } catch (err) { | ||
56 | + await queryRunner.rollbackTransaction() | ||
57 | + throw err | ||
58 | + } finally { | ||
59 | + await queryRunner.release() | ||
60 | + } | ||
61 | + | ||
62 | + return result | ||
63 | + } | ||
64 | +} | ... | ... |
1 | +/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
2 | +import { ObjectType, Field, Int } from '@nestjs/graphql' | ||
3 | +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm' | ||
4 | + | ||
5 | +@Entity({ name: 'likeable' }) | ||
6 | +@ObjectType() | ||
7 | +export class Likeable { | ||
8 | + @PrimaryGeneratedColumn() | ||
9 | + @Field((type) => Int) | ||
10 | + id: number | ||
11 | + | ||
12 | + @Column() | ||
13 | + @Field() | ||
14 | + user_id: string | ||
15 | + | ||
16 | + @Column() | ||
17 | + @Field((type) => Int) | ||
18 | + likeable_id: number | ||
19 | + | ||
20 | + @Column() | ||
21 | + @Field((type) => Int) | ||
22 | + like_dislike: number | ||
23 | + | ||
24 | + @Column() | ||
25 | + @Field() | ||
26 | + created_date: string | ||
27 | + | ||
28 | + @Column() | ||
29 | + @Field() | ||
30 | + likeable_type: string | ||
31 | +} |
... | @@ -8,6 +8,7 @@ import { | ... | @@ -8,6 +8,7 @@ import { |
8 | } from './dto/post.input' | 8 | } from './dto/post.input' |
9 | import { Post } from './model/post.entity' | 9 | import { Post } from './model/post.entity' |
10 | import { getCurrentDate } from '../shared/utils' | 10 | import { getCurrentDate } from '../shared/utils' |
11 | +import { MASTER_TEST } from 'src/shared/const' | ||
11 | 12 | ||
12 | @Injectable() | 13 | @Injectable() |
13 | export class PostService { | 14 | export class PostService { |
... | @@ -43,7 +44,7 @@ export class PostService { | ... | @@ -43,7 +44,7 @@ export class PostService { |
43 | const newInput = { | 44 | const newInput = { |
44 | ...input, | 45 | ...input, |
45 | created_date: getCurrentDate(), | 46 | created_date: getCurrentDate(), |
46 | - author: 'test', | 47 | + author: MASTER_TEST, |
47 | } | 48 | } |
48 | result = await queryRunner.manager.save( | 49 | result = await queryRunner.manager.save( |
49 | this.postRepository.create(newInput), | 50 | this.postRepository.create(newInput), | ... | ... |
... | @@ -2,6 +2,28 @@ | ... | @@ -2,6 +2,28 @@ |
2 | # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) | 2 | # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) |
3 | # ------------------------------------------------------ | 3 | # ------------------------------------------------------ |
4 | 4 | ||
5 | +type Comment { | ||
6 | + author: String! | ||
7 | + content: String! | ||
8 | + created_date: String! | ||
9 | + id: Int! | ||
10 | + parent: Int! | ||
11 | + post_id: Int! | ||
12 | + updated_date: String | ||
13 | +} | ||
14 | + | ||
15 | +input CreateCommentInput { | ||
16 | + content: String! | ||
17 | + parent: Float | ||
18 | + post_id: Int! | ||
19 | +} | ||
20 | + | ||
21 | +input CreateLikeableInput { | ||
22 | + like_dislike: Int! | ||
23 | + likeable_id: Int! | ||
24 | + likeable_type: String! | ||
25 | +} | ||
26 | + | ||
5 | input CreateMyInput { | 27 | input CreateMyInput { |
6 | name: String! | 28 | name: String! |
7 | type: String | 29 | type: String |
... | @@ -13,13 +35,36 @@ input CreatePostInput { | ... | @@ -13,13 +35,36 @@ input CreatePostInput { |
13 | title: String! | 35 | title: String! |
14 | } | 36 | } |
15 | 37 | ||
38 | +input GetCommentInput { | ||
39 | + author: String | ||
40 | + parent: String | ||
41 | + post_id: Float | ||
42 | +} | ||
43 | + | ||
44 | +input GetLikeableInput { | ||
45 | + likeable_id: Float | ||
46 | + likeable_type: String! | ||
47 | + user_id: String | ||
48 | +} | ||
49 | + | ||
16 | input GetPostInput { | 50 | input GetPostInput { |
17 | author: String | 51 | author: String |
18 | category: String | 52 | category: String |
19 | id: Float | 53 | id: Float |
20 | } | 54 | } |
21 | 55 | ||
56 | +type Likeable { | ||
57 | + created_date: String! | ||
58 | + id: Int! | ||
59 | + like_dislike: Int! | ||
60 | + likeable_id: Int! | ||
61 | + likeable_type: String! | ||
62 | + user_id: String! | ||
63 | +} | ||
64 | + | ||
22 | type Mutation { | 65 | type Mutation { |
66 | + createComment(input: CreateCommentInput!): Comment! | ||
67 | + createLikeable(input: CreateLikeableInput!): Likeable! | ||
23 | createMyPage(createMyInput: CreateMyInput!): MyPage! | 68 | createMyPage(createMyInput: CreateMyInput!): MyPage! |
24 | createPost(input: CreatePostInput!): Post! | 69 | createPost(input: CreatePostInput!): Post! |
25 | } | 70 | } |
... | @@ -41,8 +86,14 @@ type Post { | ... | @@ -41,8 +86,14 @@ type Post { |
41 | } | 86 | } |
42 | 87 | ||
43 | type Query { | 88 | type Query { |
89 | + getAllComments: [Comment!]! | ||
90 | + getAllLikes: [Likeable!]! | ||
44 | getAllPosts: [Post!]! | 91 | getAllPosts: [Post!]! |
92 | + getComment(id: Float!): Comment! | ||
93 | + getLikeable(id: Float!): Likeable! | ||
45 | getPost(id: Float!): Post! | 94 | getPost(id: Float!): Post! |
95 | + getSomeComments(input: GetCommentInput!): [Comment!]! | ||
46 | getSomePosts(input: GetPostInput!): [Post!]! | 96 | getSomePosts(input: GetPostInput!): [Post!]! |
97 | + getTotalLikes(input: GetLikeableInput!): Float! | ||
47 | myPage: [MyPage!]! | 98 | myPage: [MyPage!]! |
48 | } | 99 | } | ... | ... |
-
Please register or login to post a comment