@startuml !define table(ename, dbname) entity "ename" !define pkey(x) {field} <&key> x !define fkey(x) {field} <&key> x !define column(x) {field} <&media-record> x hide stereotypes hide methods hide circle top to bottom direction skinparam roundcorner 5 skinparam linetype ortho skinparam shadowing false skinparam handwritten false skinparam class { BackgroundColor white ArrowColor seagreen BorderColor seagreen } table( Address, address ) as address { pkey( id ): INTEGER column( street ): CHARACTER VARYING column( zip ): CHARACTER VARYING column( city ): CHARACTER VARYING column( country ): CHARACTER VARYING column( state ): CHARACTER VARYING } table( Person, person ) as person { pkey( id ): INTEGER column( name ): CHARACTER VARYING } table( Contact, contact ) as contact { pkey( id ): INTEGER column( email ): CHARACTER VARYING column( phone ): CHARACTER VARYING column( note ): CHARACTER VARYING fkey( personId ): INTEGER <> fkey( addressId ): INTEGER <> } table( Group, group ) as group { pkey( id ): INTEGER column( name ): CHARACTER VARYING column( permissions ): ENUM fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) } table( RefreshToken, refresh_token ) as refresh_token { pkey( id ): INTEGER column( token ): CHARACTER VARYING column( ip ): CHARACTER VARYING fkey( userId ): INTEGER <> fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) } table( WorkLog, work_log ) as work_log { pkey( id ): INTEGER column( from ): TIMESTAMP WITH TIME ZONE(6) column( to ): TIMESTAMP WITH TIME ZONE(6) column( description ): CHARACTER VARYING fkey( userId ): INTEGER <> fkey( contractId ): INTEGER <> fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) } table( User, user ) as user { pkey( id ): INTEGER column( username ): CHARACTER VARYING column( passwordHash ): CHARACTER VARYING fkey( personId ): INTEGER <> fkey( avatarId ): INTEGER <> } table( File, file ) as file { pkey( id ): INTEGER column( hash ): CHARACTER VARYING column( filename ): CHARACTER VARYING column( url ): CHARACTER VARYING column( mimeType ): CHARACTER VARYING fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) } table( ContractAttachment, contract_attachment ) as contract_attachment { pkey( id ): INTEGER column( note ): CHARACTER VARYING fkey( fileId ): INTEGER <> fkey( contractId ): INTEGER <> fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) } table( Phase, phase ) as phase { pkey( id ): INTEGER column( name ): CHARACTER VARYING } table( ContractPhase, contract_phase ) as contract_phase { pkey( contractId ): INTEGER pkey( phaseId ): INTEGER column( deadlineAt ): TIMESTAMP WITH TIME ZONE(6) column( isDone ): BOOLEAN } table( Customer, customer ) as customer { pkey( id ): INTEGER fkey( personId ): INTEGER <> } table( Contract, contract ) as contract { pkey( id ): INTEGER column( code ): CHARACTER VARYING column( name ): CHARACTER VARYING column( description ): CHARACTER VARYING column( startAt ): TIMESTAMP WITH TIME ZONE(6) column( deadlineAt ): TIMESTAMP WITH TIME ZONE(6) column( isDone ): BOOLEAN fkey( customerId ): INTEGER <> fkey( createdById ): INTEGER <> column( metadataCreatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataUpdatedat ): TIMESTAMP WITH TIME ZONE(6) column( metadataDeletedat ): TIMESTAMP WITH TIME ZONE(6) column( priceAmount ): NUMERIC column( priceCurrency ): ENUM } table( group_users_user, group_users_user ) as group_users_user { pkey( groupId ): INTEGER pkey( userId ): INTEGER } contact }|--|| person contact ||--|| address group }|--|| user refresh_token }o--|| user refresh_token }|--|| user work_log }|--|| user work_log }o--|| contract work_log }|--|| user user ||--|| person user }o--|| file file }|--|| user contract_attachment ||--|| file contract_attachment }o--|| contract contract_attachment }|--|| user contract_phase }|--|| contract contract_phase }|--|| phase customer ||--|| person contract }|--|| customer contract }|--|| user group_users_user }|--|| group group_users_user }|--|| user @enduml