@startuml
skinparam BoxPadding 10
skinparam SequenceTitleFontSize 25
skinparam SequenceGroupHeaderFontSize 15
skinparam SequenceGroupFontSize 15
skinparam SequenceGroupBodyBackgroundColor transparent
skinparam Padding 4


title: Update Owner Command UML

participant Cloudfront
box "API Gateway" #goldenrod
	participant "Administration REST API" as Api
end box
box "Lambda" #darkorange
	participant "Update Owner Command" as Command
end box
box "DynamoDB" #royalblue
	participant "Owner Table" as OwnerTable
end box


Cloudfront ++

    Cloudfront -> Api ++: PATCH /owners/{owner-id}
    note right Cloudfront
        2 optional body parameters:
            EmailDistributionList
            OwnerName
    endnote
        Api -> Api ++: Request Integration
            Api --

        Api -> Command ++: Invoke
            Command -> Command ++: Session Decorator
                Command --
            Command -> Command ++: Command Wrapper
                Command --

            Command -> Command ++: Authorize
                Command -> OwnerTable ++: GET Owner By owner-id
                    Command <<-- OwnerTable
                OwnerTable --

                opt if owner-id does not exist
                    Api <<-- Command: raise NoSuchOwner (404)
                end

                opt if not authorized
                    Api <<-- Command: raise NotAuthorizedError (403)
                end
            Command --

            Command -> Command ++: Validate Request Operation \n Is Replace
                opt validation failure
                    Api <<-- Command: raise InvalidRequestProperyValue (400)
                end
            Command --

             Command -> Command ++: Generate JSON Response Dict
                    Command --

            Command -> Command ++: Compare Existing Owner \n with Response Dict
                opt if no changes to owner
                    Api <<-- Command: raise SemanticError (422)
                end
            Command --

            'TODO: Code Improvement - Currently, we do a lot of this validation
            ' against the response dict. I think we should validate against the request
            Command -> Command ++: Validate Response Dict owner-name Is Valid
                opt validation failure
                    Api <<-- Command: raise InvalidRequestPropertyValue (400)
                end
            Command --

            Command -> Command ++: Validate Response Dict email-distribution Is Valid
                opt validation failure
                    Api <<-- Command: InvalidRequestPropertyValue (400)
                end
            Command --

            Command -> Command ++: Validate Response Dict Contains \n No More Than One Collection Prefix
                opt validation failure
                    Api <<-- Command: raise InvalidRequestPropertyValue (400)
                end
            Command --

            Command -> Command ++: Validate Owner Does \n Not Already Exist For \n Response Dict owner-name \n and email-distribution-list
            'TODO: Code Improvement - We query by owner-id twice when we don't need to
                Command -> OwnerTable ++: Query Owner By owner-id
                    Command <<-- OwnerTable
                OwnerTable --

                    opt validation failure
                        Api <<-- Command: raise NoSuchOwner (404)
                    end
            Command --

            Command -> Command ++: Generate Owner::Update Event Store Dict
               Command --

            Command -> Command ++: Command Wrapper
                note right Command: PUT Owner::Update Event to EventStoreTable
            Command --

            Api <<-- Command: JSON Response (Success)
        Command --

        Api -> Api ++: Response Integration
            Api --
        note right Api
            Response Integration Status Codes
                Success: 202 (OK)
                Exception:
                    Invalid 400
                    NotAuthorized 403
                    NoSuchOwner 404
                    ForbiddenStateTransitionError 409
                    SemanticError 422
                    InternalError 500
        endnote
        Cloudfront <<-- Api: <Status Code> Location Header
    Api --

Cloudfront --
@enduml