diff --git a/.assets/db.puml b/.assets/db.puml new file mode 100644 index 0000000..924750b --- /dev/null +++ b/.assets/db.puml @@ -0,0 +1,218 @@ +@startuml pivot_multitenancy_erd + +!define TABLE(name) entity name << (T,#FFAAAA) >> +!define PK(x) x +!define FK(x) x + +skinparam linetype ortho +skinparam entity { + BackgroundColor<> LightBlue + BackgroundColor<> LightGreen + BackgroundColor<> LightYellow + BackgroundColor<> Plum + BackgroundColor<> LightCoral +} + +' ========================================== +' METADATA TABLES +' ========================================== + +entity "organizations" as org <> { + PK(org_id) : INTEGER + -- + org_name : VARCHAR(100) + display_name : VARCHAR(255) + is_active : BOOLEAN + created_at : TIMESTAMPTZ + modified_at : TIMESTAMPTZ +} + +entity "mt_objects" as obj <> { + PK(obj_id) : INTEGER + -- + FK(org_id) : INTEGER + obj_name : VARCHAR(100) + label : VARCHAR(255) + plural_label : VARCHAR(255) + description : TEXT + is_custom : BOOLEAN + is_active : BOOLEAN + created_at : TIMESTAMPTZ + created_by : UUID + modified_at : TIMESTAMPTZ + modified_by : UUID +} + +entity "mt_fields" as fld <> { + PK(field_id) : INTEGER + -- + FK(org_id) : INTEGER + FK(obj_id) : INTEGER + field_name : VARCHAR(100) + label : VARCHAR(255) + data_type : VARCHAR(50) + field_num : INTEGER + is_indexed : BOOLEAN + is_unique : BOOLEAN + is_required : BOOLEAN + is_external_id : BOOLEAN + FK(reference_obj_id) : INTEGER + relationship_type : VARCHAR(50) + relationship_name : VARCHAR(100) + delete_constraint : VARCHAR(50) + formula_expression : TEXT + formula_return_type : VARCHAR(50) + length : INTEGER + precision : INTEGER + scale : INTEGER + created_at : TIMESTAMPTZ + modified_at : TIMESTAMPTZ +} + +' ========================================== +' DATA TABLES +' ========================================== + +entity "mt_data" as data <> { + PK(org_id) : INTEGER + PK(guid) : UUID + -- + FK(obj_id) : INTEGER + name : VARCHAR(255) + -- + value0 : VARCHAR(4000) + value1 : VARCHAR(4000) + value2 : VARCHAR(4000) + ... : ... + value49 : VARCHAR(4000) + -- + is_deleted : BOOLEAN + deleted_at : TIMESTAMPTZ + deleted_by : UUID + created_at : TIMESTAMPTZ + created_by : UUID + modified_at : TIMESTAMPTZ + modified_by : UUID +} + +entity "mt_clobs" as clob <> { + PK(org_id) : INTEGER + PK(clob_id) : UUID + -- + FK(data_guid) : UUID + field_num : INTEGER + clob_value : TEXT + created_at : TIMESTAMPTZ + modified_at : TIMESTAMPTZ +} + +' ========================================== +' INDEX TABLES +' ========================================== + +entity "mt_indexes" as idx <> { + PK(idx_id) : BIGINT + -- + FK(org_id) : INTEGER + FK(obj_id) : INTEGER + field_num : INTEGER + FK(guid) : UUID + string_value : VARCHAR(255) + num_value : DECIMAL(18,6) + date_value : TIMESTAMPTZ +} + +entity "mt_unique_fields" as uniq <> { + PK(idx_id) : BIGINT + -- + FK(org_id) : INTEGER + FK(obj_id) : INTEGER + field_num : INTEGER + FK(guid) : UUID + string_value : VARCHAR(255) + num_value : DECIMAL(18,6) + date_value : TIMESTAMPTZ +} + +entity "mt_fallback_index" as fallback <> { + PK(org_id) : INTEGER + PK(guid) : UUID + -- + FK(obj_id) : INTEGER + name : VARCHAR(255) + name_lower : VARCHAR(255) + modified_at : TIMESTAMPTZ +} + +entity "mt_name_denorm" as denorm <> { + PK(org_id) : INTEGER + PK(guid) : UUID + -- + FK(obj_id) : INTEGER + name : VARCHAR(255) +} + +' ========================================== +' RELATIONSHIP TABLE +' ========================================== + +entity "mt_relationships" as rel <> { + PK(rel_id) : BIGINT + -- + FK(org_id) : INTEGER + relationship_id : INTEGER + FK(parent_obj_id) : INTEGER + FK(parent_guid) : UUID + FK(child_obj_id) : INTEGER + FK(child_guid) : UUID +} + +' ========================================== +' AUDIT TABLE +' ========================================== + +entity "mt_field_history" as hist <> { + PK(history_id) : BIGINT + -- + FK(org_id) : INTEGER + FK(obj_id) : INTEGER + FK(guid) : UUID + field_num : INTEGER + old_value : TEXT + new_value : TEXT + data_type : VARCHAR(50) + changed_at : TIMESTAMPTZ + changed_by : UUID +} + +' ========================================== +' RELATIONSHIPS +' ========================================== + +' Metadata relationships +org ||--o{ obj : "contains" +org ||--o{ fld : "owns" +obj ||--o{ fld : "has" +fld }o--o| obj : "references" + +' Data relationships +org ||--o{ data : "partitioned by" +obj ||--o{ data : "instances of" +data ||--o{ clob : "large text" + +' Index relationships +data ||--o{ idx : "indexed in" +data ||--o{ uniq : "unique fields" +data ||--|| fallback : "name search" +data ||--|| denorm : "name display" + +' Relationship table +data }o--o{ rel : "parent" +data }o--o{ rel : "child" +obj ||--o{ rel : "parent type" +obj ||--o{ rel : "child type" + +' History +data ||--o{ hist : "audit trail" + +@enduml