chore: add new access log module

This commit is contained in:
mahyargdz
2025-09-02 16:14:36 +03:30
parent 60deb8937d
commit 672fe9b783
36 changed files with 2066 additions and 41 deletions
+7 -1
View File
@@ -1,5 +1,5 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { ArrayMinSize, IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength } from "class-validator";
import { ArrayMinSize, IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString, IsUUID, IsUrl, MaxLength } from "class-validator";
import { BlogMessage } from "../../../common/enums/message.enum";
@@ -69,4 +69,10 @@ export class CreateBlogDto {
@IsOptional()
@IsBoolean({ message: BlogMessage.IS_PINNED_SHOULD_BE_A_BOOLEAN })
isPinned?: boolean;
@IsOptional()
@IsNotEmpty({ message: BlogMessage.AUDIO_URL_REQUIRED })
@IsUrl({ protocols: ["http", "https"], require_protocol: true }, { message: BlogMessage.AUDIO_URL_STRING })
@ApiPropertyOptional({ description: "Audio URL of the blog", example: "https://example.com/audio.mp3" })
audioUrl?: string;
}
+2 -2
View File
@@ -108,8 +108,8 @@ export class BlogsController {
@Patch(":id")
@AdminRoute()
@PermissionsDec(PermissionEnum.BLOGS)
updateBlog(@Param() paramDto: ParamDto, @Body() updateBlogDto: UpdateBlogDto) {
return this.blogsService.updateBlog(paramDto.id, updateBlogDto);
updateBlog(@Param() paramDto: ParamDto, @Body() updateBlogDto: UpdateBlogDto, @UserDec("id") userId: string) {
return this.blogsService.updateBlog(paramDto.id, updateBlogDto, userId);
}
@ApiOperation({ summary: "Delete a blog (admin route) " })
+7 -2
View File
@@ -12,11 +12,16 @@ import { BlogCategoriesRepository } from "./repositories/blog-categories.reposit
import { BlogCommentReplyRepository } from "./repositories/blog-comment-reply.repository";
import { BlogCommentsRepository } from "./repositories/blog-comments.repository";
import { BlogsRepository } from "./repositories/blogs.repository";
import { AccessLogsModule } from "../access-logs/access-logs.module";
import { NotificationModule } from "../notifications/notifications.module";
import { UsersModule } from "../users/users.module";
@Module({
imports: [TypeOrmModule.forFeature([Blog, BlogComment, BlogCommentReply, BlogCategory]), UsersModule, NotificationModule],
imports: [
TypeOrmModule.forFeature([Blog, BlogComment, BlogCommentReply, BlogCategory]),
UsersModule,
NotificationModule,
AccessLogsModule,
],
controllers: [BlogsController],
providers: [
BlogsService,
@@ -45,6 +45,9 @@ export class Blog extends BaseEntity {
@Index()
isPinned: boolean;
@Column({ type: "varchar", length: 255, nullable: true })
audioUrl: string;
@ManyToOne(() => User, (user) => user.blogs, { onDelete: "CASCADE", nullable: false })
@Index()
author: User;
+49 -1
View File
@@ -2,6 +2,8 @@ import { BadRequestException, Injectable } from "@nestjs/common";
import { Not } from "typeorm";
import { AdminMessage, BlogMessage, CommonMessage } from "../../../common/enums/message.enum";
import { UserType } from "../../access-logs/enums/user-type.enum";
import { AccessLogService } from "../../access-logs/providers/access-log.service";
import { CategoryListSearchQueryDto } from "../../danak-services/DTO/category-search-query.dto";
import { UsersService } from "../../users/providers/users.service";
import { CreateBlogDto } from "../DTO/create-blog.dto";
@@ -19,6 +21,7 @@ export class BlogsService {
private readonly blogCommentsRepository: BlogCommentsRepository,
private readonly blogCategoriesRepository: BlogCategoriesRepository,
private readonly usersService: UsersService,
private readonly accessLogService: AccessLogService,
) {}
//*********************************** */
@@ -121,6 +124,22 @@ export class BlogsService {
await this.blogsRepository.save(blog);
await this.accessLogService.logCreate(
"Blog",
blog.id,
{ blog: createBlogDto.title },
{
user: { id: authorId },
userType: UserType.ADMIN,
actionDescription: `Admin created blog: ${createBlogDto.title}`,
metadata: {
categoryId: createBlogDto.categoryId,
slug: slug,
authorId: authorId,
},
},
);
return {
message: CommonMessage.CREATED,
blog,
@@ -129,7 +148,7 @@ export class BlogsService {
//*********************************** */
async updateBlog(id: string, updateBlogDto: UpdateBlogDto) {
async updateBlog(id: string, updateBlogDto: UpdateBlogDto, userId: string) {
const blog = await this.findBlogById(id);
if (updateBlogDto.title) {
@@ -153,6 +172,21 @@ export class BlogsService {
slug: this.generateSlug(updateBlogDto.slug ?? blog.slug),
});
await this.accessLogService.logUpdate(
"Blog",
blog.id,
{ blog: blog.title },
{ blog: updateBlogDto.title },
{
user: { id: userId },
userType: UserType.ADMIN,
actionDescription: `Admin updated blog: ${blog.title}`,
metadata: {
categoryId: updateBlogDto.categoryId,
},
},
);
return {
message: CommonMessage.UPDATE_SUCCESS,
blog,
@@ -168,6 +202,20 @@ export class BlogsService {
if (!blog) throw new BadRequestException(BlogMessage.BLOG_NOT_FOUND);
await this.blogsRepository.softDelete({ id });
await this.accessLogService.logDelete(
"Blog",
blog.id,
{ blog: blog.title },
{
user: { id: userId },
userType: UserType.ADMIN,
actionDescription: `Admin deleted blog: ${blog.title}`,
metadata: {
categoryId: blog.category.id,
},
},
);
return {
message: CommonMessage.DELETED,
};