add posts, categories entity, module

This commit is contained in:
2025-05-15 15:28:19 +07:00
parent 301501dbac
commit d97dfd25e2
16 changed files with 306 additions and 85 deletions

View File

@@ -7,6 +7,7 @@ import * as Joi from 'joi';
import {UsersModule} from "./users/user.module";
import {AuthenticationModule} from "./authentication/authentication.module";
import { PostsModule } from './posts/posts.module';
import { CategoriesModule } from './categories/categories.module';
@Module({
imports: [
@@ -35,7 +36,8 @@ import { PostsModule } from './posts/posts.module';
}),
UsersModule,
AuthenticationModule,
PostsModule
PostsModule,
CategoriesModule
],
controllers: [AppController],
providers: [AppService],

View File

@@ -0,0 +1,34 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { CategoriesService } from './categories.service';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
@Controller('categories')
export class CategoriesController {
constructor(private readonly categoriesService: CategoriesService) {}
@Post()
create(@Body() createCategoryDto: CreateCategoryDto) {
return this.categoriesService.create(createCategoryDto);
}
@Get()
findAll() {
return this.categoriesService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.categoriesService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateCategoryDto: UpdateCategoryDto) {
return this.categoriesService.update(+id, updateCategoryDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.categoriesService.remove(+id);
}
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { CategoriesService } from './categories.service';
import { CategoriesController } from './categories.controller';
@Module({
controllers: [CategoriesController],
providers: [CategoriesService],
})
export class CategoriesModule {}

View File

@@ -0,0 +1,70 @@
import { Injectable } from '@nestjs/common';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
import {InjectRepository} from "@nestjs/typeorm";
import Post from "../posts/entities/post.entity";
import {Repository} from "typeorm";
import Category from "./entities/category.entity";
import {CategoryNotFoundException} from "./exception/categoryNotFound.exception";
@Injectable()
export class CategoriesService {
constructor(
@InjectRepository(Category) private repo: Repository<Category>,
) {
}
getAllCategories() {
return this.repo.find({ relations: ['posts'] });
}
async getCategoryById(id: number) {
const category = await this.repo.findOne({
where: { id },
relations: {
posts: true,
}
});
if (category) {
return category;
}
throw new CategoryNotFoundException(id);
}
async updateCategory(id: number, category: UpdateCategoryDto) {
await this.repo.update(id, category);
const updatedCategory = await this.repo.findOne({
where: { id },
relations: {
posts: true,
}
});
if (updatedCategory) {
return updatedCategory
}
throw new CategoryNotFoundException(id);
}
create(createCategoryDto: CreateCategoryDto) {
return 'This action adds a new category';
}
findAll() {
return `This action returns all categories`;
}
findOne(id: number) {
return `This action returns a #${id} category`;
}
update(id: number, updateCategoryDto: UpdateCategoryDto) {
return `This action updates a #${id} category`;
}
remove(id: number) {
return `This action removes a #${id} category`;
}
}

View File

@@ -0,0 +1 @@
export class CreateCategoryDto {}

View File

@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger';
import { CreateCategoryDto } from './create-category.dto';
export class UpdateCategoryDto extends PartialType(CreateCategoryDto) {}

View File

@@ -0,0 +1,16 @@
import {Column, Entity, ManyToMany, PrimaryGeneratedColumn} from 'typeorm';
import Post from "../../posts/entities/post.entity";
@Entity()
class Category {
@PrimaryGeneratedColumn()
public id: number;
@Column()
public name: string;
@ManyToMany(() => Post, (post: Post) => post.categories)
public posts: Post[];
}
export default Category;

View File

@@ -0,0 +1,7 @@
import { NotFoundException } from '@nestjs/common';
export class CategoryNotFoundException extends NotFoundException {
constructor(categoryId: number) {
super(`Category with id ${categoryId} not found`);
}
}

View File

@@ -1 +1,29 @@
export class Post {}
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn, ManyToMany, JoinTable} from 'typeorm';
import User from "../../users/user.entity";
import Category from "../../categories/entities/category.entity";
@Entity()
class Post {
@PrimaryGeneratedColumn()
public id: number;
@Column()
public title: string;
@Column()
public content: string;
@Column({nullable: true})
public category?: string;
@ManyToOne(() => User, (author: User) => author.posts)
public author: User;
@ManyToMany(() => Category, (category: Category) => category.posts)
@JoinTable()
public categories: Category[];
}
export default Post;

View File

@@ -1,6 +1,6 @@
import { NotFoundException } from '@nestjs/common';
class PostNotFoundException extends NotFoundException {
export class PostNotFoundException extends NotFoundException {
constructor(postId: number) {
super(`Post with id ${postId} not found`);
}

View File

@@ -1,20 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PostsController } from './posts.controller';
import { PostsService } from './posts.service';
describe('PostsController', () => {
let controller: PostsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [PostsController],
providers: [PostsService],
}).compile();
controller = module.get<PostsController>(PostsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@@ -1,34 +1,38 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { PostsService } from './posts.service';
import { CreatePostDto } from './dto/create-post.dto';
import { UpdatePostDto } from './dto/update-post.dto';
import {Controller, Get, Post, Body, Patch, Param, Delete, UseGuards, Req} from '@nestjs/common';
import {PostsService} from './posts.service';
import {CreatePostDto} from './dto/create-post.dto';
import {UpdatePostDto} from './dto/update-post.dto';
import JwtAuthenticationGuard from "../authentication/jwt-authentication.guard";
import RequestWithUser from "../authentication/requestWithUser.interface";
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
constructor(private readonly postsService: PostsService) {
}
@Post()
create(@Body() createPostDto: CreatePostDto) {
return this.postsService.create(createPostDto);
}
@Post()
@UseGuards(JwtAuthenticationGuard)
async createPost(@Body() post: CreatePostDto, @Req() req: RequestWithUser) {
return this.postsService.createPost(post, req.user);
}
@Get()
findAll() {
return this.postsService.findAll();
}
@Get()
findAll() {
return this.postsService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.postsService.findOne(+id);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.postsService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updatePostDto: UpdatePostDto) {
return this.postsService.update(+id, updatePostDto);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updatePostDto: UpdatePostDto) {
return this.postsService.update(+id, updatePostDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.postsService.remove(+id);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.postsService.remove(+id);
}
}

View File

@@ -1,18 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PostsService } from './posts.service';
describe('PostsService', () => {
let service: PostsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [PostsService],
}).compile();
service = module.get<PostsService>(PostsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@@ -1,26 +1,74 @@
import { Injectable } from '@nestjs/common';
import { CreatePostDto } from './dto/create-post.dto';
import { UpdatePostDto } from './dto/update-post.dto';
import {Injectable} from '@nestjs/common';
import {CreatePostDto} from './dto/create-post.dto';
import {UpdatePostDto} from './dto/update-post.dto';
import User from "../users/user.entity";
import {InjectRepository} from "@nestjs/typeorm";
import {Repository} from "typeorm";
import Post from './entities/post.entity';
import {PostNotFoundException} from "./exception/postNotFound.exception";
@Injectable()
export class PostsService {
create(createPostDto: CreatePostDto) {
return 'This action adds a new post';
}
findAll() {
return `This action returns all posts`;
}
constructor(
@InjectRepository(Post) private repo: Repository<Post>,
) {
}
findOne(id: number) {
return `This action returns a #${id} post`;
}
async createPost(post: CreatePostDto, user: User) {
const newPost = this.repo.create({
...post,
author: user
});
await this.repo.save(newPost);
return newPost;
}
update(id: number, updatePostDto: UpdatePostDto) {
return `This action updates a #${id} post`;
}
remove(id: number) {
return `This action removes a #${id} post`;
}
getAllPosts() {
return this.repo.find({relations: ['author']});
}
async getPostById(id: number) {
const post = await this.repo.findOne(
{
where: {id},
relations: {author: true}
}
);
if (post) {
return post;
}
throw new PostNotFoundException(id);
}
async updatePost(id: number, post: UpdatePostDto) {
await this.repo.update(id, post);
const updatedPost = await this.repo.findOne({
where: {id},
relations: {author: true}
});
if (updatedPost) {
return updatedPost
}
throw new PostNotFoundException(id);
}
findAll() {
return `This action returns all posts`;
}
findOne(id: number) {
return `This action returns a #${id} post`;
}
update(id: number, updatePostDto: UpdatePostDto) {
return `This action updates a #${id} post`;
}
remove(id: number) {
return `This action removes a #${id} post`;
}
}

View File

@@ -0,0 +1,22 @@
import {Column, Entity, OneToOne, PrimaryGeneratedColumn} from 'typeorm';
import User from "./user.entity";
@Entity()
class Address {
@PrimaryGeneratedColumn()
public id: number;
@Column()
public street: string;
@Column()
public city: string;
@Column()
public country: string;
@OneToOne(() => User, (user: User) => user.address)
public user: User;
}
export default Address;

View File

@@ -1,5 +1,7 @@
import {Column, Entity, PrimaryGeneratedColumn} from 'typeorm';
import {Column, Entity, PrimaryGeneratedColumn, OneToOne, JoinColumn, OneToMany} from 'typeorm';
import {Exclude, Expose} from 'class-transformer';
import Address from "./address.entity";
import Post from "../posts/entities/post.entity";
@Entity()
class User {
@@ -17,6 +19,18 @@ class User {
@Column()
public password: string;
@OneToOne(() => Address, {
eager: true,
cascade: true
})
@JoinColumn()
public address: Address;
@OneToMany(() => Post, (post: Post) => post.author)
public posts: Post[];
@Column({
nullable: true,
})