refactor(usecase): specify concrete Input and Output types in usecase docblocks and refine builder generic inference

This commit is contained in:
Jérémy Munsch 2026-08-18 11:34:30 +02:00
parent 1fdf7ea9cc
commit 1dcf0a8cdf
Signed by: forge-joniko
GPG key ID: D7EFE2F5CB6CC0E4
22 changed files with 31 additions and 47 deletions

View file

@ -10,7 +10,7 @@ use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\Employees\Find\Input, \Application\Arcadia\Usecase\Employees\Find\Output> */
final readonly class FindEmployee implements Usecase
{
public function __construct(

View file

@ -11,7 +11,7 @@ use Shared\DDD\Usecase\Usecase;
use Shared\Paginated;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\Employees\FindAll\Input, \Application\Arcadia\Usecase\Employees\FindAll\Output> */
final readonly class FindAllEmployees implements Usecase
{
public function __construct(

View file

@ -10,7 +10,7 @@ use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\IncoCompositions\Find\Input, \Application\Arcadia\Usecase\IncoCompositions\Find\Output> */
final readonly class FindIncoComposition implements Usecase
{
public function __construct(

View file

@ -10,7 +10,7 @@ use Shared\DDD\Usecase\Input as BaseInput;
use Shared\DDD\Usecase\Usecase;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\IncoSheets\Find\Input, \Application\Arcadia\Usecase\IncoSheets\Find\Output> */
final readonly class FindIncoSheet implements Usecase
{
public function __construct(

View file

@ -13,7 +13,7 @@ use Shared\DDD\Usecase\Usecase;
use Shared\Paginated;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\IncoSheets\FindAll\Input, \Application\Arcadia\Usecase\IncoSheets\FindAll\Output> */
final readonly class FindAllIncoSheets implements Usecase
{
public function __construct(

View file

@ -14,7 +14,7 @@ use Shared\Paginated;
use Shared\Pagination;
use Webmozart\Assert\Assert;
/** @implements Usecase<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> */
/** @implements Usecase<\Application\Arcadia\Usecase\IncoSheets\Search\Input, \Application\Arcadia\Usecase\IncoSheets\Search\Output> */
final readonly class SearchIncoSheets implements Usecase
{
public function __construct(

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class EmployeeShowController
{
/** @param UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private FindEmployee $usecase,
private UsecaseExecutor $executor,

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class EmployeesIndexController
{
/** @param UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private FindAllEmployees $usecase,
private UsecaseExecutor $executor,

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class IncoCompositionShowController
{
/** @param \Shared\DDD\Usecase\Builder\UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private FindIncoComposition $usecase,
private UsecaseExecutor $executor,

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class IncoSheetsIndexController
{
/** @param UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private FindAllIncoSheets $usecase,
private UsecaseExecutor $executor,

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class IncoSheetsSearchController
{
/** @param UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private SearchIncoSheets $usecase,
private UsecaseExecutor $executor,

View file

@ -15,7 +15,6 @@ use Shared\DDD\Usecase\Builder\UsecaseExecutor;
final readonly class IncoSheetsShowController
{
/** @param UsecaseExecutor<\Shared\DDD\Usecase\Input, \Shared\DDD\Usecase\Output> $executor */
public function __construct(
private FindIncoSheet $usecase,
private UsecaseExecutor $executor,

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, EmployeeShowView> */
/** @implements Presenter<Output, EmployeeShowView> */
final readonly class EmployeeShowPresenter implements Presenter
{
#[\Override]

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, EmployeesIndexView> */
/** @implements Presenter<Output, EmployeesIndexView> */
final readonly class EmployeesIndexPresenter implements Presenter
{
#[\Override]

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, IncoCompositionShowView> */
/** @implements Presenter<Output, IncoCompositionShowView> */
final readonly class IncoCompositionShowPresenter implements Presenter
{
#[\Override]

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, IncoSheetsIndexView> */
/** @implements Presenter<Output, IncoSheetsIndexView> */
final readonly class IncoSheetsIndexPresenter implements Presenter
{
#[\Override]

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, IncoSheetsSearchView> */
/** @implements Presenter<Output, IncoSheetsSearchView> */
final readonly class IncoSheetsSearchPresenter implements Presenter
{
#[\Override]

View file

@ -9,7 +9,7 @@ use Shared\DDD\Usecase\Output as UsecaseOutput;
use Shared\DDD\Usecase\Presenter;
use Webmozart\Assert\Assert;
/** @implements Presenter<\Shared\DDD\Usecase\Output, IncoSheetsShowView> */
/** @implements Presenter<Output, IncoSheetsShowView> */
final readonly class IncoSheetsShowPresenter implements Presenter
{
#[\Override]

View file

@ -6,13 +6,12 @@ namespace Shared\DDD\Usecase\Builder;
use Shared\DDD\Usecase\Usecase;
/**
* @template TInput of \Shared\DDD\Usecase\Input
* @template TOutput of \Shared\DDD\Usecase\Output
*/
interface BuilderStepUsecase
{
/**
* @template TInput of \Shared\DDD\Usecase\Input
* @template TOutput of \Shared\DDD\Usecase\Output
*
* @param Usecase<TInput, TOutput> $usecase
* @return BuilderStepInput<TOutput>
*/

View file

@ -6,13 +6,6 @@ namespace Shared\DDD\Usecase\Builder;
final class UsecaseBuilder
{
/**
* @template TInput of \Shared\DDD\Usecase\Input
* @template TOutput of \Shared\DDD\Usecase\Output
*
* @param UsecaseExecutor<TInput, TOutput> $executor
* @return BuilderStepUsecase<TInput, TOutput>
*/
public static function using(UsecaseExecutor $executor): BuilderStepUsecase
{
return new UsecaseExecutionBuilder($executor);

View file

@ -10,35 +10,39 @@ use Shared\DDD\Usecase\Presenter;
use Shared\DDD\Usecase\Usecase;
/**
* @template TInput of \Shared\DDD\Usecase\Input
* @template TOutput of \Shared\DDD\Usecase\Output
* @template TView of object
*
* @implements BuilderStepInput<TOutput>
* @implements BuilderStepPresenter<TOutput>
* @implements BuilderStepUsecase<TInput, TOutput>
* @implements BuilderStepBuild<TView>
*/
final class UsecaseExecutionBuilder implements BuilderStepBuild, BuilderStepInput, BuilderStepPresenter, BuilderStepUsecase
{
/** @param UsecaseExecutor<TInput, TOutput> $executor */
public function __construct(
private readonly UsecaseExecutor $executor,
) {
}
/** @var Usecase<TInput, TOutput>|null */
/** @var Usecase<Input, \Shared\DDD\Usecase\Output>|null */
private ?Usecase $usecase = null;
private ?Input $input = null;
/** @var Presenter<TOutput, object>|null */
/** @var Presenter<\Shared\DDD\Usecase\Output, object>|null */
private ?Presenter $presenter = null;
/** @param Usecase<TInput, TOutput> $usecase */
/**
* @template TIn of \Shared\DDD\Usecase\Input
* @template TOut of \Shared\DDD\Usecase\Output
*
* @param Usecase<TIn, TOut> $usecase
* @return BuilderStepInput<TOut>
*/
#[\Override]
public function do(Usecase $usecase): BuilderStepInput
{
/** @var Usecase<Input, \Shared\DDD\Usecase\Output> $usecase */
$this->usecase = $usecase;
return $this;
@ -66,11 +70,10 @@ final class UsecaseExecutionBuilder implements BuilderStepBuild, BuilderStepInpu
public function with(Presenter $presenter): BuilderStepBuild
{
if ($this->usecase === null || $this->input === null) {
throw new LogicException(
'Usecase and input must be set before presenter.'
);
throw new LogicException('Usecase and input must be set before presenter.');
}
/** @var Presenter<\Shared\DDD\Usecase\Output, object> $presenter */
$this->presenter = $presenter;
return $this;
@ -85,10 +88,6 @@ final class UsecaseExecutionBuilder implements BuilderStepBuild, BuilderStepInpu
}
/** @var TView */
return $this->executor->execute(
usecase: $this->usecase,
input: $this->input,
presenter: $this->presenter
);
return $this->executor->execute($this->usecase, $this->input, $this->presenter);
}
}

View file

@ -8,16 +8,15 @@ use Shared\DDD\Usecase\Input;
use Shared\DDD\Usecase\Presenter;
use Shared\DDD\Usecase\Usecase;
/**
* @template TInput of Input
* @template TOutput of \Shared\DDD\Usecase\Output
*/
interface UsecaseExecutor
{
/**
* @template TInput of Input
* @template TOutput of \Shared\DDD\Usecase\Output
* @template TView of object
*
* @param Usecase<TInput, TOutput> $usecase
* @param TInput $input
* @param Presenter<TOutput, TView> $presenter
* @return TView
*/