This commit is contained in:
2025-12-16 18:17:48 +01:00
parent 362894d1a5
commit ec7c0b8f2a
94 changed files with 4240 additions and 983 deletions

View File

@@ -1,3 +1,30 @@
/**
* Async Use Case interface for queries.
*
* Queries do not change system state and return data directly.
* The output is most often a Result<T, E> where T is the data and E is a domain error code,
* to handle business rejections explicitly. Use cases do not throw errors; they use error codes in Result.
*
* Example:
* ```typescript
* export type YourUseCaseError =
* | 'SPONSOR_NOT_FOUND'
* | 'PRICING_NOT_CONFIGURED'
* | 'APPLICATIONS_CLOSED'
* | 'NO_SLOTS_AVAILABLE'
* | 'DUPLICATE_PENDING_REQUEST'
* | 'OFFER_BELOW_MINIMUM';
*
* export class ApplyForSponsorshipUseCase implements AsyncUseCase<Input, Result<SuccessDTO, YourUseCaseError>> {
* async execute(input: Input): Promise<Result<SuccessDTO, YourUseCaseError>> {
* // implementation
* }
* }
* ```
*
* @template Input - The input type for the use case
* @template Output - The output type returned by the use case, often Result<T, DomainErrorCode>
*/
export interface AsyncUseCase<Input, Output> {
execute(input: Input): Promise<Output>;
}

View File

@@ -1,5 +1,34 @@
import type { Presenter } from '../presentation';
/**
* Use Case interface for commands.
*
* Use cases represent application-level business logic. They coordinate domain objects and repositories,
* but contain no infrastructure or framework concerns.
*
* Commands change system state and return nothing on success. They use a presenter to handle the output.
* If a business rejection is possible, the output may be a Result<void, E> handled by the presenter.
* Use cases do not throw errors; they use error codes in Result.
*
* Example:
* ```typescript
* export type CreateRaceError =
* | 'INSUFFICIENT_PERMISSIONS'
* | 'RACE_ALREADY_EXISTS'
* | 'INVALID_RACE_CONFIG';
*
* export class CreateRaceUseCase implements UseCase<CreateRaceInput, Result<void, CreateRaceError>, ViewModel, Presenter<Result<void, CreateRaceError>, ViewModel>> {
* execute(input: CreateRaceInput, presenter: Presenter<Result<void, CreateRaceError>, ViewModel>): Promise<void> {
* // implementation
* }
* }
* ```
*
* @template Input - The input type for the use case
* @template OutputDTO - The output DTO type, often Result<void, DomainErrorCode>
* @template ViewModel - The view model type
* @template P - The presenter type, extending Presenter<OutputDTO, ViewModel>
*/
export interface UseCase<Input, OutputDTO, ViewModel, P extends Presenter<OutputDTO, ViewModel>> {
execute(input: Input, presenter: P): Promise<void> | void;
}

View File

@@ -1,3 +1,6 @@
/**
* @deprecated Use error codes in Result instead of throwing ApplicationError.
*/
export type CommonApplicationErrorKind =
| 'not_found'
| 'forbidden'