mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
feat(core): add domain layer with clean architecture
Add domain layer components: - BaseEntity with ID, timestamps and equality checks - ValueObject for immutable value objects - IRepository interface for persistence - DomainEvent system for domain events
This commit is contained in:
44
packages/core/src/domain/entities/BaseEntity.ts
Normal file
44
packages/core/src/domain/entities/BaseEntity.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
/**
|
||||
* Base entity class with ID and timestamps
|
||||
*/
|
||||
export abstract class BaseEntity {
|
||||
protected readonly _id: string;
|
||||
protected readonly _createdAt: Date;
|
||||
protected _updatedAt: Date;
|
||||
|
||||
constructor(id?: string) {
|
||||
this._id = id ?? uuidv4();
|
||||
this._createdAt = new Date();
|
||||
this._updatedAt = new Date();
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get createdAt(): Date {
|
||||
return this._createdAt;
|
||||
}
|
||||
|
||||
public get updatedAt(): Date {
|
||||
return this._updatedAt;
|
||||
}
|
||||
|
||||
protected touch(): void {
|
||||
this._updatedAt = new Date();
|
||||
}
|
||||
|
||||
public equals(entity: BaseEntity): boolean {
|
||||
if (entity === null || entity === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this === entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._id === entity._id;
|
||||
}
|
||||
}
|
||||
25
packages/core/src/domain/events/DomainEvent.ts
Normal file
25
packages/core/src/domain/events/DomainEvent.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
/**
|
||||
* Base interface for all domain events
|
||||
*/
|
||||
export interface IDomainEvent {
|
||||
readonly eventId: string;
|
||||
readonly occurredOn: Date;
|
||||
readonly eventType: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for domain events
|
||||
*/
|
||||
export abstract class DomainEvent implements IDomainEvent {
|
||||
public readonly eventId: string;
|
||||
public readonly occurredOn: Date;
|
||||
public readonly eventType: string;
|
||||
|
||||
constructor(eventType: string) {
|
||||
this.eventId = uuidv4();
|
||||
this.occurredOn = new Date();
|
||||
this.eventType = eventType;
|
||||
}
|
||||
}
|
||||
4
packages/core/src/domain/index.ts
Normal file
4
packages/core/src/domain/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './entities/BaseEntity';
|
||||
export * from './value-objects/ValueObject';
|
||||
export * from './repositories/IRepository';
|
||||
export * from './events/DomainEvent';
|
||||
14
packages/core/src/domain/repositories/IRepository.ts
Normal file
14
packages/core/src/domain/repositories/IRepository.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { BaseEntity } from '../entities/BaseEntity';
|
||||
|
||||
/**
|
||||
* Generic repository interface
|
||||
* Defines standard CRUD operations for entities
|
||||
*/
|
||||
export interface IRepository<T extends BaseEntity> {
|
||||
findById(id: string): Promise<T | null>;
|
||||
findAll(): Promise<T[]>;
|
||||
save(entity: T): Promise<T>;
|
||||
update(entity: T): Promise<T>;
|
||||
delete(id: string): Promise<boolean>;
|
||||
exists(id: string): Promise<boolean>;
|
||||
}
|
||||
23
packages/core/src/domain/value-objects/ValueObject.ts
Normal file
23
packages/core/src/domain/value-objects/ValueObject.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Base class for Value Objects
|
||||
* Value objects are immutable and compared by value, not identity
|
||||
*/
|
||||
export abstract class ValueObject<T> {
|
||||
protected readonly props: T;
|
||||
|
||||
constructor(props: T) {
|
||||
this.props = Object.freeze(props);
|
||||
}
|
||||
|
||||
public equals(vo?: ValueObject<T>): boolean {
|
||||
if (vo === null || vo === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vo.props === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JSON.stringify(this.props) === JSON.stringify(vo.props);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user