Skip to content

Commit

Permalink
Circular dependency between mappers problem has been solved -need to …
Browse files Browse the repository at this point in the history
…be optimized-
  • Loading branch information
devbenho committed May 31, 2024
1 parent 7cfac23 commit ed44ee0
Show file tree
Hide file tree
Showing 14 changed files with 288 additions and 90 deletions.
Binary file modified server/db.sqlite3
Binary file not shown.
9 changes: 8 additions & 1 deletion server/src/application/post/create/create-post.usecase.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { BaseUseCase } from '@application/shared';
import { CreatePostRequest } from './create-post.request';
import { PostDetailsResponseDto } from '@contracts/dtos/posts';
import { inject, injectable } from 'inversify';
import { TYPES } from '@infrastructure/shared/ioc/types';
import { IPostRepository } from '@domain/repositories/post.repository';
import { LOGGER } from '@/web/rest/logger';
import { PostDetailsResponseDto } from '@contracts/dtos/posts/post-details.response';
import { log } from 'console';

@injectable()
class CreatePostUseCase extends BaseUseCase<
Expand All @@ -20,8 +21,14 @@ class CreatePostUseCase extends BaseUseCase<
public async performOperation(
request: CreatePostRequest,
): Promise<PostDetailsResponseDto> {
LOGGER.info('CreatePostUseCase.performOperation');
const post = CreatePostRequest.toEntity(request);
LOGGER.info(
'mapped post is kjkhkhkhfkldhskjhdfksjahjdshajkhfdjskahfsdhjksah',
post.toString(),
);
const createdPost = await this._postRepository.createPost(post);
log('created post is', createdPost);
if (createdPost) {
return PostDetailsResponseDto.fromEntity(createdPost);
}
Expand Down
2 changes: 2 additions & 0 deletions server/src/application/post/find-all/find-all-post.usecase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PostResponseDto } from '@contracts/dtos/posts';
import { TYPES } from '@infrastructure/shared/ioc/types';
import { IPostRepository } from '@domain/repositories/post.repository';
import { inject } from 'inversify';
import { log } from 'console';

class FindAllPostUseCase extends BaseUseCase<
FindAllPostRequest,
Expand All @@ -21,6 +22,7 @@ class FindAllPostUseCase extends BaseUseCase<
): Promise<PostResponseDto[]> {
const { pageSize, pageNumber } = request;
const posts = await this._postRepository.findAll(pageSize, pageNumber);
log('posts from use-case', posts);
const postDtos = await Promise.all(
posts.map(async post => {
return await PostResponseDto.fromEntity(post);
Expand Down
2 changes: 2 additions & 0 deletions server/src/contracts/dtos/posts/post-details.response.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { LOGGER } from '@/web/rest/logger';
import { Post } from '@domain/entities';
import { Nullable } from '@domain/shared/types';
import { UserResponseDto } from '@dtos/users';
import { log } from 'console';

export class PostDetailsResponseDto {
constructor(
Expand Down
6 changes: 3 additions & 3 deletions server/src/contracts/dtos/posts/post.response.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Nullable } from '@domain/shared/types';
import { CommentResponseDto } from '@dtos/comments';
import { UserResponseDto } from '@dtos/users';
import { Comment, Post } from '@domain/entities';
import { Post } from '@domain/entities';

export class PostResponseDto {
constructor(
Expand All @@ -12,15 +12,15 @@ export class PostResponseDto {
public comments: CommentResponseDto[],
public createdAt: Date,
public lastModifiedAt: Nullable<Date>,
) { }
) {}

public static async fromEntity(entity: Post): Promise<PostResponseDto> {
return new PostResponseDto(
entity.id,
entity.title,
entity.content,
UserResponseDto.fromEntity(entity.author),
entity.comments ? (await entity.comments).map(CommentResponseDto.fromEntity) : [],
entity.comments ? entity.comments.map(CommentResponseDto.fromEntity) : [],
entity.createdAt,
entity.updatedAt,
);
Expand Down
2 changes: 1 addition & 1 deletion server/src/contracts/dtos/users/user.response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class UserResponseDto {
public username: string,
public email: string,
public pictureProfile?: string,
) { }
) {}

public static fromEntity(entity: User): UserResponseDto {
return new UserResponseDto(
Expand Down
56 changes: 38 additions & 18 deletions server/src/infrastructure/posts/post.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ import { Post } from '@domain/entities';
import { UserMapper } from '@infrastructure/users';
import { CommentMapper } from '@infrastructure/comments';
import { LikePostMapper } from '@infrastructure/like-posts';
import { log } from 'console';
import { MapperConfig } from '@infrastructure/shared/persistence/mapper.config';

class PostMapper {
public static async toDomain(persistence: PostPersistence): Promise<Post> {
log(`Post Persistence after loading : `, await persistence.likes);
const likes = await persistence.likes;
const comments = await persistence.comments;
public static async toDomain(
persistence: PostPersistence,
config: MapperConfig = {},
): Promise<Post> {
const likes = config.includeLikes
? await (persistence.likes ?? Promise.resolve([]))
: [];
const comments = config.includeComments
? await (persistence.comments ?? Promise.resolve([]))
: [];
const author = config.includeAuthor
? await UserMapper.toDomain(await persistence.author)
: null;

return Post.create(
persistence.id,
persistence.title,
persistence.content,
persistence.authorId,
await UserMapper.toDomain(persistence.author),
author as any,
await Promise.all(likes.map(like => LikePostMapper.toDomain(like))),
await Promise.all(
comments.map(comment => CommentMapper.toDomain(comment)),
Expand All @@ -29,7 +38,10 @@ class PostMapper {
);
}

public static async toPersistence(domain: Post): Promise<PostPersistence> {
public static async toPersistence(
domain: Post,
config: MapperConfig = {},
): Promise<PostPersistence> {
const postPersistence = new PostPersistence();
if (domain.id) {
postPersistence.id = domain.id;
Expand All @@ -38,18 +50,26 @@ class PostMapper {
postPersistence.title = domain.title;
postPersistence.content = domain.content;
postPersistence.authorId = domain.authorId;
postPersistence.author = await UserMapper.toPersistence(domain.author);
postPersistence.likes = Promise.resolve(
await Promise.all(
domain.likes.map(like => LikePostMapper.toPersistence(like)),
),
);

postPersistence.comments = Promise.resolve(
await Promise.all(
domain.comments.map(comment => CommentMapper.toPersistence(comment)),
),
);
if (config.includeAuthor) {
postPersistence.author = UserMapper.toPersistence(domain.author);
}

if (config.includeLikes) {
postPersistence.likes = Promise.resolve(
await Promise.all(
domain.likes.map(like => LikePostMapper.toPersistence(like)),
),
);
}

if (config.includeComments) {
postPersistence.comments = Promise.resolve(
await Promise.all(
domain.comments.map(comment => CommentMapper.toPersistence(comment)),
),
);
}

postPersistence.status = domain.status.toLowerCase();
postPersistence.createdAt = domain.createdAt;
Expand Down
8 changes: 6 additions & 2 deletions server/src/infrastructure/posts/post.persistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
UpdateDateColumn,
CreateDateColumn,
PrimaryGeneratedColumn,
JoinTable,
} from 'typeorm';
import { CommentPersistence } from '@infrastructure/comments/';
import { UserPersistence } from '@infrastructure/users';
Expand Down Expand Up @@ -36,15 +37,18 @@ class PostPersistence {
@Column()
authorId: string;

@ManyToOne(() => UserPersistence, user => user.posts, { eager: true })
author: UserPersistence;
@ManyToOne(() => UserPersistence, user => user.posts)
@JoinTable()
author: Promise<UserPersistence>;

@OneToMany(() => CommentPersistence, comment => comment.post, { lazy: true })
@JoinTable()
comments: Promise<CommentPersistence[]>;

@OneToMany(() => LikePostPersistence, likePost => likePost.post, {
lazy: true,
})
@JoinTable()
likes: Promise<LikePostPersistence[]>;

// add status column enum ['draft', 'published', 'deleted']
Expand Down
7 changes: 4 additions & 3 deletions server/src/infrastructure/posts/post.repository.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Post } from '@domain/entities';
import { IPostRepository } from '@domain/repositories/post.repository';
import { PostPersistence } from './post.persistence';
import { PostMapper } from './post.mapper';
import { LOGGER } from '@/web/rest/logger';
import { log } from 'console';

@injectable()
Expand All @@ -23,7 +22,7 @@ export class PostRepository implements IPostRepository {
async createPost(post: Post): Promise<Post> {
const postPersistence = await PostMapper.toPersistence(post);
const createdPost = await this._repository.save(postPersistence);
return PostMapper.toDomain(createdPost);
return PostMapper.toDomain(createdPost, { includeAuthor: true });
}

async findPostById(postId: string): Promise<Post | null> {
Expand All @@ -48,7 +47,9 @@ export class PostRepository implements IPostRepository {

async findAll(limit: number, page: number): Promise<Post[]> {
const [posts, count] = await this._repository.findAndCount();
const postPromises = posts.map(post => PostMapper.toDomain(post));
const postPromises = posts.map(post =>
PostMapper.toDomain(post, { includeAuthor: true }),
);
return Promise.all(postPromises);
}

Expand Down
12 changes: 12 additions & 0 deletions server/src/infrastructure/shared/persistence/mapper.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
interface MapperConfig {
includeComments?: boolean;
includePosts?: boolean;
includeLikedPosts?: boolean;
includeLikedReplies?: boolean;
includeReplies?: boolean;
includeLikedComments?: boolean;
includeLikes?: boolean;
includeAuthor?: boolean;
}

export { MapperConfig };
97 changes: 97 additions & 0 deletions server/src/infrastructure/shared/persistence/mapper.facade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { LikeReply, Reply, User } from '@domain/entities/';
import { Post } from '@domain/entities/';
import { Comment } from '@domain/entities';
import { LikePost } from '@domain/entities/';
import { UserPersistence, UserMapper } from '@infrastructure/users/';
import { PostPersistence, PostMapper } from '@infrastructure/posts/';
import { CommentPersistence, CommentMapper } from '@infrastructure/comments/';
import {
LikePostPersistence,
LikePostMapper,
} from '@infrastructure/like-posts/';
import { ReplyMapper, ReplyPersistence } from '@infrastructure/replies';
import {
LikeReplyMapper,
LikeReplyPersistence,
} from '@infrastructure/like-replies';
import {
LikeCommentMapper,
LikeCommentPersistence,
} from '@infrastructure/like-comments';
import { LikeComment } from '@domain/entities/like-comment';

class MapperFacade {
static async toUserDomain(persistence: UserPersistence): Promise<User> {
return await UserMapper.toDomain(persistence);
}

static async toUserPersistence(domain: User): Promise<UserPersistence> {
return await UserMapper.toPersistence(domain);
}

static async toPostDomain(persistence: PostPersistence): Promise<Post> {
return await PostMapper.toDomain(persistence);
}

static async toPostPersistence(domain: Post): Promise<PostPersistence> {
return await PostMapper.toPersistence(domain);
}

static async toCommentDomain(
persistence: CommentPersistence,
): Promise<Comment> {
return await CommentMapper.toDomain(persistence);
}

static async toCommentPersistence(
domain: Comment,
): Promise<CommentPersistence> {
return await CommentMapper.toPersistence(domain);
}

static async toLikePostDomain(
persistence: LikePostPersistence,
): Promise<LikePost> {
return await LikePostMapper.toDomain(persistence);
}

static async toLikePostPersistence(
domain: LikePost,
): Promise<LikePostPersistence> {
return await LikePostMapper.toPersistence(domain);
}

static async toLikeCommentDomain(
persistence: LikeCommentPersistence,
): Promise<LikeComment> {
return await LikeCommentMapper.toDomain(persistence);
}

static async toLikeCommentPersistence(
domain: LikeComment,
): Promise<LikeCommentPersistence> {
return await LikeCommentMapper.toPersistence(domain);
}

static async toLikeReplyDomain(
persistence: LikeReplyPersistence,
): Promise<LikeReply> {
return await LikeReplyMapper.toDomain(persistence);
}

static async toLikeReplyPersistence(
domain: LikeReply,
): Promise<LikeReplyPersistence> {
return await LikeReplyMapper.toPersistence(domain);
}

static async toReplyDomain(persistence: ReplyPersistence): Promise<Reply> {
return await ReplyMapper.toDomain(persistence);
}

static async toReplyPersistence(domain: Reply): Promise<ReplyPersistence> {
return await ReplyMapper.toPersistence(domain);
}
}

export { MapperFacade };
Loading

0 comments on commit ed44ee0

Please sign in to comment.