@startuml
'https://plantuml.com/class-diagram

hide empty members

title Domain Model

package "User Aggregate" {
    class User <<(E, cadetblue) Root Entity>>

    class UserEmail <<(V, lightgreen) Value Object>>
    class FirstName <<(V, lightgreen) Value Object>>
    class LastName <<(V, lightgreen) Value Object>>
    class Password <<(V, lightgreen) Value Object>>

    User -->"1" UserEmail
    User -->"1" FirstName
    User -->"1" LastName
    User -->"1" Password
}

package "Role Aggregate" {
    class Role <<(E, cadetblue) Root Entity>>

    class RoleName <<(V, lightgreen) Value Object>>

    Role -->"1" RoleName
}

package "Building Aggregate"
{
  class Building <<(E, cadetblue) Root Entity>>

  class BuildingCode <<(V, lightgreen) Value Object>>
  note right of BuildingCode
        the code is unique and max of 5 characters
  end note

  class BuildingName <<(V, lightgreen) Value Object>>
  note right of BuildingName
        the name has a max of 50 characters
  end note

  class BuildingDescription <<(V, lightgreen) Value Object>>

  class MaxFloorColumn <<(V, lightgreen) Value Object>>
  class MaxFloorLine <<(V, lightgreen) Value Object>>


  Building -->"0|1" BuildingName
  Building -->"1" BuildingCode
  Building -->"1" BuildingDescription
  Building -->"1" MaxFloorColumn
  Building -->"1" MaxFloorLine

}

package "Floor Aggregate"
{

  class Floor <<(E, cadetblue) Root Entity>>

  class FloorNumber <<(V, lightgreen) Value Object>>

  class FloorMap <<(V, lightgreen) Value Object>>

  class ColumnNumber <<(V, lightgreen) Value Object>>
  class LineNumber <<(V, lightgreen) Value Object>>

  class Cell <<(V, lightgreen) Value Object>>

  class Wall <<(V, lightgreen) Value Object>>
  class IsDoor <<(V, lightgreen) Value Object>>
  class Orientation <<(E, salmon) Enum>>
  note right of Orientation
        North, South, East, West
  end note



  class ColumnCoordinate <<(V, lightgreen) Value Object>>
  class LineCoordinate <<(V, lightgreen) Value Object>>

  Floor -->"1" FloorNumber
  Floor -->"1" FloorMap
  Floor -->"1" ColumnNumber
  Floor -->"1" LineNumber

  Floor -->"*" Cell
  Cell -->"1" ColumnCoordinate
  Cell -->"1" LineCoordinate
  Cell -->"*" Wall
  Wall -->"1" IsDoor
  note right of IsDoor
        the wall can have or not a door
  end note
  Wall -->"1" Orientation: has


}

package "Room Aggregate"{
  class Room <<(E, cadetblue) Root Entity>>
  class RoomName <<(V, lightgreen) Value Object>>

  Room -->"1" RoomName
}

class TaskType <<(E, salmon) Enum>>
    note right of TaskType
         PickupDelivery , Vigilance
    end note


package "Robot Type Aggregate"
{
  class RobotType <<(E, cadetblue) Root Entity>>

  class RobotTypeDescription <<(V, lightgreen) Value Object>>

  class Brand <<(V, lightgreen) Value Object>>

  class Model <<(V, lightgreen) Value Object>>


  RobotType -->"1" RobotTypeDescription
  RobotType -->"1" Brand
  RobotType -->"1" Model
  RobotType -->"1" TaskType: has
}

package "Robot Aggregate"
{

  class Robot <<(E, cadetblue) Root Entity>>

  class RobotName <<(V, lightgreen) Value Object>>

  class SerialNumber <<(V, lightgreen) Value Object>>

  class Status <<(V, lightgreen) Value Object>>

  Robot -->"1" RobotName
  Robot -->"1" Status
  Robot -->"1" SerialNumber

}

package "Task Aggregate"{

  class Task <<(E, cadetblue) Root Entity>>

  class TaskName <<(V, lightgreen) Value Object>>

  class TaskDescription <<(V, lightgreen) Value Object>>

  class TaskStatus <<(V, lightgreen) Value Object>>


  Task -->"1" TaskName
  Task -->"1" TaskDescription
  Task -->"1" TaskStatus

}

Task -->"1" TaskType: has

package "Vigilance Task Aggregate"{

  class VigilanceTask <<(E, cadetblue) Root Entity>>

  class EmergencyContact <<(V, lightgreen) Value Object>>

}

package "PickupDelivery Task"{

  class PickupDelivery <<(E, cadetblue) Root Entity>>

  class ConfirmationCode <<(V, lightgreen) Value Object>>

  class PickupContact  <<(V, lightgreen) Value Object>>

  class PickupName <<(V, lightgreen) Value Object>>

  class DeliveryDescription <<(V, lightgreen) Value Object>>


  PickupDelivery -->"1" ConfirmationCode
  PickupDelivery -->"1" PickupContact
  PickupDelivery -->"1"PickupName
  PickupDelivery -->"1" DeliveryDescription
}



User -->"1" Role : Has
User -->"*" Robot: Creates and Manages
User -->"*" Task: Creates and Manages


Robot -->"1" RobotType: Has
Robot -->"*"  Task : executes

Task -->"*" Building: Has

Building -->"*" Floor: Has
Cell -->"0|1" Room: Is associated to

Task <|-- VigilanceTask
Task <|-- PickupDelivery

VigilanceTask -->"*" Floor : guards floors of same building

PickupDelivery -->"2" Room


@enduml
