@startuml Tanabata File Manager entity relationship diagram ' skinparam linetype ortho ' ========== SYSTEM ========== entity "system.users" as usr { * id : uuid <> -- * name : varchar(32) * password : text * is_admin : boolean } entity "system.mime" as mime { * name : varchar(127) -- * extension : varchar(16) } ' ========== DATA ========== entity "data.categories" as cty { * id : uuid <> -- * name : varchar(256) notes : text color : char(6) * created_at : timestamptz <> * creator_id : uuid ' * is_private : boolean } cty::creator_id }o--|| usr::id entity "data.files" as fle { * id : uuid <> -- name : varchar(256) * mime : varchar(127) * datetime : timestamptz notes : text * metadata : jsonb * created_at : timestamptz <> * creator_id : uuid ' * is_private : boolean } fle::mime }o--|| mime::name fle::creator_id }o--|| usr::id entity "data.tags" as tag { * id : uuid <> -- * name : varchar(256) notes : text color : char(6) category_id : uuid * created_at : timestamptz <> * creator_id : uuid ' * is_private : boolean } tag::category_id }o--o| cty::id tag::creator_id }o--|| usr::id entity "data.file_tag" as ft { * file_id : uuid * tag_id : uuid } ft::file_id }o--|| fle::id ft::tag_id }o--|| tag::id entity "data.autotags" as atg { * trigger_tag_id : uuid * add_tag_id : uuid -- * is_active : boolean } atg::trigger_tag_id }o--|| tag::id atg::add_tag_id }o--|| tag::id entity "data.pools" as pool { * id : uuid <> -- * name : varchar(256) notes : text ' parent_id : uuid * created_at : timestamptz * creator_id : uuid ' * is_private : boolean } pool::creator_id }o--|| usr::id ' pool::parent_id }o--o| pool::id entity "data.file_pool" as fp { * file_id : uuid * pool_id : uuid * number : integer } fp::file_id }o--|| fle::id fp::pool_id }o--|| pool::id ' ========== ACCESS ========== entity "access.files" as acl_f { * user_id : uuid * file_id : uuid -- * read : boolean * write : boolean } acl_f::user_id }o--|| usr::id acl_f::file_id }o--|| fle::id entity "access.tags" as acl_t { * user_id : uuid * tag_id : uuid -- * read : boolean * write : boolean ' * files_read : boolean ' * files_write : boolean } acl_t::user_id }o--|| usr::id acl_t::tag_id }o--|| tag::id entity "access.categories" as acl_c { * user_id : uuid * category_id : uuid -- * read : boolean * write : boolean ' * tags_read : boolean ' * tags_write : boolean } acl_c::user_id }o--|| usr::id acl_c::category_id }o--|| cty::id entity "access.pools" as acl_p { * user_id : uuid * pool_id : uuid -- * read : boolean * write : boolean ' * files_read : boolean ' * files_write : boolean } acl_p::user_id }o--|| usr::id acl_p::pool_id }o--|| pool::id ' ========== ACTIVITY ========== entity "activity.sessions" as ssn { * id : uuid <> -- * user_id : uuid * user_agent : varchar(512) * started_at : timestamptz expires_at : timestamptz * last_activity : timestamptz } ssn::user_id }o--|| usr::id entity "activity.file_views" as fv { * file_id : uuid * timestamp : timestamptz * user_id : uuid } fv::file_id }o--|| fle::id fv::user_id }o--|| usr::id entity "activity.tag_uses" as tu { * tag_id : uuid * timestamp : timestamptz * user_id : uuid -- * included : boolean } tu::tag_id }o--|| tag::id tu::user_id }o--|| usr::id entity "activity.pool_views" as pv { * pool_id : uuid * timestamp : timestamptz * user_id : uuid } pv::pool_id }o--|| pool::id pv::user_id }o--|| usr::id @enduml