Skip to content

Commit 593fa31

Browse files
authored
Merge pull request #62 from techknowledge-blog/feature/add-estimated-time-column
Estimated Time
2 parents b046d51 + d674bae commit 593fa31

File tree

6 files changed

+106
-56
lines changed

6 files changed

+106
-56
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Post" ADD COLUMN "estimated_time" INTEGER NOT NULL DEFAULT 0;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Post" ADD COLUMN "views" INTEGER NOT NULL DEFAULT 0;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `views` on the `Post` table. All the data in the column will be lost.
5+
6+
*/
7+
-- AlterTable
8+
ALTER TABLE "Post" DROP COLUMN "views";

prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ model Post {
4343
coverImageLink String?
4444
slug String @unique
4545
previewImageLink String?
46+
estimated_time Int @default(0)
4647
authorId Int
4748
categoryId Int
4849
createdAt DateTime @default(now())
Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,43 @@
1-
import { Controller, Get, Param } from '@nestjs/common';
1+
import {
2+
Body,
3+
Controller,
4+
Delete,
5+
Get,
6+
Param,
7+
Patch,
8+
Post,
9+
} from '@nestjs/common';
210
import { PostsService } from './posts.service';
311
import { Post as PostModel } from '@prisma/client';
12+
import { CreatePostDto } from './dto/create-post.dto';
13+
import { UpdatePostDto } from './dto/update-post.dto';
414

515
@Controller('posts')
616
export class PostsController {
717
constructor(private readonly postService: PostsService) {}
818

9-
@Get('published')
10-
async findPublishedPosts(): Promise<PostModel[]> {
11-
return this.postService.posts({
12-
where: { isPublished: true },
13-
});
19+
@Post()
20+
async create(@Body() dto: CreatePostDto) {
21+
return this.postService.createPost(dto);
1422
}
1523

16-
@Get('filtered-posts/:searchString')
17-
async findFilteredPosts(
18-
@Param('searchString') searchString: string,
19-
): Promise<PostModel[]> {
20-
return this.postService.posts({
21-
where: {
22-
OR: [
23-
{
24-
title: { contains: searchString },
25-
},
26-
{
27-
content: { contains: searchString },
28-
},
29-
],
30-
},
31-
});
24+
@Get('published')
25+
async findPublishedPosts(): Promise<PostModel[]> {
26+
return this.postService.findPublishedPosts();
3227
}
3328

3429
@Get(':slug')
3530
async findPostBySlug(@Param('slug') slug: string): Promise<PostModel> {
3631
return this.postService.findPostBySlug(slug);
3732
}
33+
34+
@Patch(':slug')
35+
update(@Param('slug') slug: string, @Body() dto: UpdatePostDto) {
36+
return this.postService.updatePost(slug, dto);
37+
}
38+
39+
@Delete(':slug')
40+
remove(@Param('slug') slug: string) {
41+
return this.postService.removePost(slug);
42+
}
3843
}

src/modules/posts/posts.service.ts

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,43 @@
11
import { Injectable, NotFoundException } from '@nestjs/common';
22
import { PrismaService } from '../../prisma.service';
3-
import { Post, Prisma } from '@prisma/client';
3+
import { Post } from '@prisma/client';
4+
import { CreatePostDto } from './dto/create-post.dto';
5+
import { UpdatePostDto } from './dto/update-post.dto';
46

57
@Injectable()
68
export class PostsService {
79
constructor(private prisma: PrismaService) {}
810

11+
private calculateEstimatedTime(content: string): number {
12+
if (!content) {
13+
new NotFoundException('Conteúdo não encontrado!');
14+
return 0;
15+
}
16+
17+
const countWords = content.trim().split(/\s+/).length;
18+
19+
return Math.ceil(countWords / 200);
20+
}
21+
22+
async createPost(data: CreatePostDto): Promise<Post> {
23+
const estimated_time = this.calculateEstimatedTime(data.content as string);
24+
25+
return this.prisma.post.create({
26+
data: {
27+
title: data.title,
28+
previewContent: data.previewContent,
29+
content: data.content,
30+
slug: data.slug,
31+
isPublished: data.isPublished,
32+
coverImageLink: data.coverImageLink,
33+
previewImageLink: data.previewImageLink,
34+
estimated_time,
35+
author: { connect: { id: data.authorId } },
36+
category: { connect: { id: data.categoryId } },
37+
},
38+
});
39+
}
40+
941
async findPostBySlug(slug: string): Promise<Post | null> {
1042
const post = await this.prisma.post.findUnique({
1143
where: { slug },
@@ -24,26 +56,17 @@ export class PostsService {
2456
});
2557

2658
if (!post) {
27-
throw new NotFoundException('Post not found!');
59+
throw new NotFoundException('Artigo não encontrado!');
2860
}
2961

3062
return post;
3163
}
3264

33-
async posts(params: {
34-
skip?: number;
35-
take?: number;
36-
cursor?: Prisma.PostWhereUniqueInput;
37-
where?: Prisma.PostWhereInput;
38-
orderBy?: Prisma.PostOrderByWithRelationInput;
39-
}): Promise<Post[]> {
40-
const { skip, take, cursor, where, orderBy } = params;
41-
return this.prisma.post.findMany({
42-
skip,
43-
take,
44-
cursor,
45-
where,
46-
orderBy,
65+
async findPublishedPosts(): Promise<Post[]> {
66+
const posts = await this.prisma.post.findMany({
67+
where: {
68+
isPublished: true,
69+
},
4770
include: {
4871
category: {
4972
select: {
@@ -57,28 +80,37 @@ export class PostsService {
5780
},
5881
},
5982
});
60-
}
6183

62-
async createPost(data: Prisma.PostCreateInput): Promise<Post> {
63-
return this.prisma.post.create({
64-
data,
65-
});
84+
if (!posts) {
85+
throw new NotFoundException('Artigos não encontrados!');
86+
}
87+
88+
return posts;
6689
}
6790

68-
async updatePost(params: {
69-
where: Prisma.PostWhereUniqueInput;
70-
data: Prisma.PostUpdateInput;
71-
}): Promise<Post> {
72-
const { data, where } = params;
73-
return this.prisma.post.update({
74-
data,
75-
where,
76-
});
91+
async updatePost(slug: string, data: UpdatePostDto) {
92+
const findPost = await this.findPostBySlug(slug);
93+
94+
if (!findPost) {
95+
throw new NotFoundException(
96+
`Não foi encontrado o artigo com o slug "${slug}"`,
97+
);
98+
}
99+
100+
return this.prisma.post.update({ where: { slug }, data });
77101
}
78102

79-
async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
80-
return this.prisma.post.delete({
81-
where,
82-
});
103+
async removePost(slug: string) {
104+
const findPost = await this.findPostBySlug(slug);
105+
106+
if (!findPost) {
107+
throw new NotFoundException(
108+
`Não foi encontrado o artigo com o slug "${slug}"`,
109+
);
110+
}
111+
112+
await this.prisma.post.delete({ where: { slug } });
113+
114+
return { message: 'Artigo removido com sucesso!' };
83115
}
84116
}

0 commit comments

Comments
 (0)