xpeditis2.0/apps/backend/src/domain/entities/blog-post.entity.ts
2026-05-12 21:01:52 +02:00

133 lines
2.8 KiB
TypeScript

export enum BlogPostStatus {
DRAFT = 'draft',
PUBLISHED = 'published',
ARCHIVED = 'archived',
}
export type BlogPostCategory = 'industry' | 'technology' | 'guides' | 'news';
interface BlogPostProps {
id: string;
title: string;
slug: string;
excerpt: string;
content: string;
coverImageUrl?: string;
category: BlogPostCategory;
tags: string[];
authorName: string;
status: BlogPostStatus;
isFeatured: boolean;
publishedAt?: Date;
createdAt: Date;
updatedAt: Date;
}
export class BlogPost {
private constructor(private readonly props: BlogPostProps) {}
static create(
props: Omit<BlogPostProps, 'status' | 'isFeatured' | 'publishedAt' | 'createdAt' | 'updatedAt'>
): BlogPost {
const now = new Date();
return new BlogPost({
...props,
status: BlogPostStatus.DRAFT,
isFeatured: false,
createdAt: now,
updatedAt: now,
});
}
static fromPersistence(props: BlogPostProps): BlogPost {
return new BlogPost(props);
}
get id(): string {
return this.props.id;
}
get title(): string {
return this.props.title;
}
get slug(): string {
return this.props.slug;
}
get excerpt(): string {
return this.props.excerpt;
}
get content(): string {
return this.props.content;
}
get coverImageUrl(): string | undefined {
return this.props.coverImageUrl;
}
get category(): BlogPostCategory {
return this.props.category;
}
get tags(): string[] {
return this.props.tags;
}
get authorName(): string {
return this.props.authorName;
}
get status(): BlogPostStatus {
return this.props.status;
}
get isFeatured(): boolean {
return this.props.isFeatured;
}
get publishedAt(): Date | undefined {
return this.props.publishedAt;
}
get createdAt(): Date {
return this.props.createdAt;
}
get updatedAt(): Date {
return this.props.updatedAt;
}
update(
data: Partial<
Pick<
BlogPostProps,
| 'title'
| 'slug'
| 'excerpt'
| 'content'
| 'coverImageUrl'
| 'category'
| 'tags'
| 'authorName'
| 'isFeatured'
>
>
): BlogPost {
return new BlogPost({ ...this.props, ...data, updatedAt: new Date() });
}
publish(): BlogPost {
return new BlogPost({
...this.props,
status: BlogPostStatus.PUBLISHED,
publishedAt: this.props.publishedAt ?? new Date(),
updatedAt: new Date(),
});
}
archive(): BlogPost {
return new BlogPost({ ...this.props, status: BlogPostStatus.ARCHIVED, updatedAt: new Date() });
}
unpublish(): BlogPost {
return new BlogPost({ ...this.props, status: BlogPostStatus.DRAFT, updatedAt: new Date() });
}
isPublished(): boolean {
return this.props.status === BlogPostStatus.PUBLISHED;
}
toObject(): BlogPostProps {
return { ...this.props };
}
}