Add blog post admin CRUD API.
Expose JWT-protected /blog-posts endpoints for draft creation, listing, update, and delete.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import type { PaginatedResponse } from '../../../types/PaginatedResponse';
|
||||
import type { ListBlogPostsQueryDto } from '../dto/ListBlogPostsQueryDto';
|
||||
import { UpdateBlogPostDto } from '../dto/UpdateBlogPostDto';
|
||||
import { BlogPost } from '../entities/BlogPost';
|
||||
|
||||
@Injectable()
|
||||
export class BlogPostsService {
|
||||
constructor(
|
||||
@InjectRepository(BlogPost)
|
||||
private readonly blogPostRepo: Repository<BlogPost>
|
||||
) {}
|
||||
|
||||
async findAll({ page = 1, limit = 20 }: ListBlogPostsQueryDto): Promise<PaginatedResponse<BlogPost>> {
|
||||
const [items, total] = await this.blogPostRepo.findAndCount({
|
||||
order: { createdAt: 'DESC' },
|
||||
skip: (page - 1) * limit,
|
||||
take: limit
|
||||
});
|
||||
|
||||
return { items, total, page, limit };
|
||||
}
|
||||
|
||||
async createDraft(): Promise<BlogPost> {
|
||||
const entity = this.blogPostRepo.create({
|
||||
title: '',
|
||||
contentHtml: '',
|
||||
isDraft: true
|
||||
});
|
||||
|
||||
await this.blogPostRepo.insert(entity);
|
||||
|
||||
return this.findOne(entity.id);
|
||||
}
|
||||
|
||||
async findOne(id: string): Promise<BlogPost> {
|
||||
const entity = await this.blogPostRepo.findOne({ where: { id } });
|
||||
|
||||
if (!entity) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
async update(id: string, { title, contentHtml, isDraft }: UpdateBlogPostDto): Promise<BlogPost> {
|
||||
const exists = await this.blogPostRepo.exists({ where: { id } });
|
||||
|
||||
if (!exists) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await this.blogPostRepo.update(id, {
|
||||
title: title.trim(),
|
||||
contentHtml,
|
||||
isDraft
|
||||
});
|
||||
|
||||
return this.findOne(id);
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
const exists = await this.blogPostRepo.exists({ where: { id } });
|
||||
|
||||
if (!exists) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
await this.blogPostRepo.delete(id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user