@startuml
title Cases GET Endpoint Sequence Diagram

actor Client
participant "AsylumCaseAdviceController" as Advice
participant "AsylumCaseController" as Controller
participant "AsylumCaseService" as Service
participant "AsylumCaseMapper" as Mapper
participant "AsylumCaseRepository" as Repository
database DynamoDB

Client -> Controller : HTTP GET
activate Controller
Controller -> Controller : generate CasesQueryParameterDto
Controller -> Service : getCasesBy(CasesQueryParameterDto)
activate Service
Service -> Service : validateRequestDto(CasesQueryParameterDto)

alt if request dto validation fails
Service --> Controller : throw BadRequestException
Controller --> Advice : throw BadRequestException
activate Advice
Advice --> Client : 400 Response, ErrorDto
deactivate Advice
else otherwise, continue
end

activate Service
Service -> Service : generate filterMap Map<String, List<String>>
Service -> Service : getListOfFilters(String, String)
Service -> Service : generate rangeMap Map<String, String[]>

Service -> Repository : find(Map<String, List<String>>, Map<String, String[]>)
activate Repository
Repository -> Repository : generateScanExpression(Map<String, List<String>>, Map<String, String[]>)
Repository -> Repository : generateFilterExpression(Map<String, List<String>>, Map<String, String[]>)
Repository -> Repository : generateValueMap(Map<String, List<String>>, Map<String, String[]>)
Repository -> DynamoDB : scan with generated scan expression
activate DynamoDB

alt if scan result is null
DynamoDB --> Repository : return null
Repository --> Service : return empty ScanResultPage
Service --> Service : validateIterableIsNotEmpty(Iterable<AsylumCase>)
Service --> Controller : throw AsylumCaseNotFoundException
Controller --> Advice : throw AsylumCaseNotFoundException

activate Advice
Advice --> Client : 404 Response, ErrorDto
deactivate Advice
else otherwise, continue
end

DynamoDB -> Repository : return AsylumCase data
deactivate DynamoDB
Repository -> Service : return populated ScanResultPage
deactivate Repository

Service -> Service : validateIterableIsNotEmpty(Iterable<AsylumCase>)
Service -> Mapper : entityToModel(AsylumCase)
activate Mapper
Mapper -> Service : return AsylumCaseModel
deactivate Mapper
Service -> Service : getTotalPages(CasesQueryParameterDto, int)
Service -> Service : getCurrentPage(CasesQueryParameterDto, List<AsylumCaseModel>)
Service -> Service : validatePageRequest(CasesQueryParameterDto, List<AsylumCaseModel>)

alt if page request validation fails
Service --> Controller : throw PageNotFoundException
Controller --> Advice : throw PageNotFoundException
activate Advice
Advice --> Client : 404 Response, ErrorDto
deactivate Advice
else otherwise, continue
end

Service -> Service : generate Page<T>(int, int, Collection<T>)
Service -> Mapper : pageToResponseDto(Page<T>)

activate Mapper
Mapper -> Service : return PageResponseDto
deactivate Mapper

Service -> Controller : return PageResponseDto
deactivate Service

Controller -> Client : 200 Response, PageResponseDto
deactivate Controller
@enduml