website refactor
This commit is contained in:
@@ -10,4 +10,4 @@ export interface DomainEventPublisher {
|
||||
}
|
||||
|
||||
// Alias for backward compatibility
|
||||
export interface IDomainEvent<T = unknown> extends DomainEvent<T> {}
|
||||
export type IDomainEvent<T = unknown> = DomainEvent<T>;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
export interface IEntity<Id = string> {
|
||||
export interface EntityProps<Id = string> {
|
||||
readonly id: Id;
|
||||
}
|
||||
|
||||
export abstract class Entity<Id> implements IEntity<Id> {
|
||||
export abstract class Entity<Id> implements EntityProps<Id> {
|
||||
protected constructor(readonly id: Id) {}
|
||||
|
||||
equals(other?: Entity<Id>): boolean {
|
||||
return !!other && this.id === other.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alias for backward compatibility
|
||||
export type IEntity<Id = string> = EntityProps<Id>;
|
||||
|
||||
6
core/shared/domain/Logger.ts
Normal file
6
core/shared/domain/Logger.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface Logger {
|
||||
debug(message: string, context?: unknown): void;
|
||||
info(message: string, context?: unknown): void;
|
||||
warn(message: string, context?: unknown): void;
|
||||
error(message: string, error?: Error, context?: unknown): void;
|
||||
}
|
||||
89
core/shared/domain/Result.ts
Normal file
89
core/shared/domain/Result.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Result type for handling success and error cases in a type-safe way.
|
||||
*
|
||||
* This class MUST ONLY be used within use cases (AsyncUseCase and UseCase implementations).
|
||||
* It is NOT allowed to be used in domain entities, services, repositories, presenters, or any other layer.
|
||||
* Use cases are the only place where business logic decisions that can fail should be made,
|
||||
* and Result provides a way to handle those failures without throwing exceptions.
|
||||
*
|
||||
* @template T - The type of the success value
|
||||
* @template E - The type of the error value, typically ApplicationErrorCode<string>
|
||||
*/
|
||||
export class Result<T, E = Error> {
|
||||
public constructor(
|
||||
private readonly _value?: T,
|
||||
private readonly _error?: E,
|
||||
private readonly _isSuccess: boolean = true
|
||||
) {}
|
||||
|
||||
static ok<T, E = Error>(value: T): Result<T, E> {
|
||||
return new Result<T, E>(value, undefined, true);
|
||||
}
|
||||
|
||||
static err<T, E = Error>(error: E): Result<T, E> {
|
||||
return new Result<T, E>(undefined, error, false);
|
||||
}
|
||||
|
||||
isOk(): boolean {
|
||||
return this._isSuccess;
|
||||
}
|
||||
|
||||
isErr(): boolean {
|
||||
return !this._isSuccess;
|
||||
}
|
||||
|
||||
unwrap(): T {
|
||||
if (!this._isSuccess) {
|
||||
throw new Error('Called unwrap on an error result');
|
||||
}
|
||||
return this._value!;
|
||||
}
|
||||
|
||||
unwrapOr(defaultValue: T): T {
|
||||
return this._isSuccess ? this._value! : defaultValue;
|
||||
}
|
||||
|
||||
unwrapErr(): E {
|
||||
if (this._isSuccess) {
|
||||
throw new Error('Called unwrapErr on a success result');
|
||||
}
|
||||
return this._error!;
|
||||
}
|
||||
|
||||
map<U>(fn: (value: T) => U): Result<U, E> {
|
||||
if (this._isSuccess) {
|
||||
return Result.ok(fn(this._value!));
|
||||
}
|
||||
return Result.err(this._error!);
|
||||
}
|
||||
|
||||
mapErr<F>(fn: (error: E) => F): Result<T, F> {
|
||||
if (!this._isSuccess) {
|
||||
return Result.err(fn(this._error!));
|
||||
}
|
||||
return Result.ok(this._value!);
|
||||
}
|
||||
|
||||
andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E> {
|
||||
if (this._isSuccess) {
|
||||
return fn(this._value!);
|
||||
}
|
||||
return Result.err(this._error!);
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct access to the value (for testing convenience).
|
||||
* Prefer using unwrap() in production code.
|
||||
*/
|
||||
get value(): T | undefined {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direct access to the error (for testing convenience).
|
||||
* Prefer using unwrapErr() in production code.
|
||||
*/
|
||||
get error(): E | undefined {
|
||||
return this._error;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,31 @@
|
||||
import type { Result } from '../application/Result';
|
||||
import type { IDomainError } from '../errors/DomainError';
|
||||
import { Result } from './Result';
|
||||
import type { DomainErrorProps } from '../errors/DomainError';
|
||||
|
||||
export interface IDomainService {
|
||||
export interface DomainService {
|
||||
readonly serviceName?: string;
|
||||
}
|
||||
|
||||
export interface IDomainCalculationService<Input, Output> extends IDomainService {
|
||||
export interface DomainCalculationService<Input, Output> extends DomainService {
|
||||
calculate(input: Input): Output;
|
||||
}
|
||||
|
||||
export interface IResultDomainCalculationService<Input, Output, Error = IDomainError>
|
||||
extends IDomainService {
|
||||
export interface ResultDomainCalculationService<Input, Output, Error = DomainErrorProps>
|
||||
extends DomainService {
|
||||
calculate(input: Input): Result<Output, Error>;
|
||||
}
|
||||
|
||||
export interface IDomainValidationService<Input, Output, Error = IDomainError>
|
||||
extends IDomainService {
|
||||
export interface DomainValidationService<Input, Output, Error = DomainErrorProps>
|
||||
extends DomainService {
|
||||
validate(input: Input): Result<Output, Error>;
|
||||
}
|
||||
|
||||
export interface IDomainFactoryService<Input, Output> extends IDomainService {
|
||||
export interface DomainFactoryService<Input, Output> extends DomainService {
|
||||
create(input: Input): Output;
|
||||
}
|
||||
}
|
||||
|
||||
// Alias for backward compatibility
|
||||
export type IDomainService = DomainService;
|
||||
export type IDomainCalculationService<Input, Output> = DomainCalculationService<Input, Output>;
|
||||
export type IResultDomainCalculationService<Input, Output, Error = DomainErrorProps> = ResultDomainCalculationService<Input, Output, Error>;
|
||||
export type IDomainValidationService<Input, Output, Error = DomainErrorProps> = DomainValidationService<Input, Output, Error>;
|
||||
export type IDomainFactoryService<Input, Output> = DomainFactoryService<Input, Output>;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
export interface IValueObject<Props> {
|
||||
export interface ValueObjectProps<Props> {
|
||||
readonly props: Props;
|
||||
equals(other: IValueObject<Props>): boolean;
|
||||
}
|
||||
equals(other: ValueObjectProps<Props>): boolean;
|
||||
}
|
||||
|
||||
// Alias for backward compatibility
|
||||
export type IValueObject<Props> = ValueObjectProps<Props>;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from './Entity';
|
||||
export * from './ValueObject';
|
||||
export * from './Service';
|
||||
export * from './Option';
|
||||
export * from './DomainEvent';
|
||||
Reference in New Issue
Block a user