2025-11-23 22:49:46 +07:00

243 lines
8.0 KiB
Plaintext

erDiagram
%% ========================================
%% CORE ENTITIES dengan RBAC
%% ========================================
ROLES ||--o{ USERS : "defines"
USERS ||--o{ ITEMS : "reports_found"
USERS ||--o{ LOST_ITEMS : "reports_lost"
USERS ||--o{ CLAIMS : "submits"
USERS ||--o{ CLAIMS : "verifies_as"
USERS ||--o{ REVISION_LOGS : "creates"
USERS ||--o{ NOTIFICATIONS : "receives"
USERS ||--o{ AUDIT_LOGS : "performs"
USERS ||--o{ ARCHIVES : "claims_item"
%% ========================================
%% CATEGORY & ATTACHMENT RELATIONS
%% ========================================
CATEGORIES ||--o{ ITEMS : "categorizes"
CATEGORIES ||--o{ LOST_ITEMS : "categorizes"
CATEGORIES ||--o{ ARCHIVES : "categorizes"
ITEMS ||--o{ ATTACHMENTS : "has_photos"
LOST_ITEMS ||--o{ ATTACHMENTS : "has_photos"
%% ========================================
%% CORE MATCHING & CLAIM LOGIC
%% ========================================
ITEMS ||--o{ CLAIMS : "receives"
ITEMS ||--o{ REVISION_LOGS : "tracks_changes"
ITEMS ||--|{ ARCHIVES : "becomes_archived"
LOST_ITEMS ||--o{ MATCH_RESULTS : "matched_to"
ITEMS ||--o{ MATCH_RESULTS : "matched_with"
%% ========================================
%% VERIFICATION PIPELINE (ETL)
%% ========================================
CLAIMS ||--|| CLAIM_VERIFICATIONS : "verified_by"
CLAIM_VERIFICATIONS ||--o{ VERIFICATION_LOGS : "tracks_verification"
%% ========================================
%% TABLE DEFINITIONS WITH DETAILED SPECS
%% ========================================
ROLES {
int id PK "AUTO_INCREMENT"
string name UK "UNIQUE, NOT NULL"
text description
json permissions "RBAC permissions"
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE"
}
USERS {
int id PK "AUTO_INCREMENT"
string name "NOT NULL"
string email UK "UNIQUE, INDEXED"
string password "ENCRYPTED (bcrypt)"
string nrp UK "UNIQUE, INDEXED"
string phone
int role_id FK "→ ROLES, INDEXED"
string status "INDEXED, DEFAULT: active"
datetime last_login
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
CATEGORIES {
int id PK "AUTO_INCREMENT"
string name "NOT NULL"
string slug UK "UNIQUE, INDEXED"
text description
string icon_url
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
ITEMS {
int id PK "AUTO_INCREMENT"
string name "INDEXED, NOT NULL"
int category_id FK "→ CATEGORIES, INDEXED"
string location "INDEXED, NOT NULL"
text description "SECRET (for verification)"
text secret_details "Only for owner/admin"
date date_found "INDEXED"
string status "INDEXED, DEFAULT: unclaimed"
int reporter_id FK "→ USERS, INDEXED"
string reporter_name
string reporter_contact
int view_count "Default: 0"
datetime expires_at "INDEXED, TRIGGER"
timestamp created_at
timestamp updated_at
timestamp deleted_at "INDEXED"
}
LOST_ITEMS {
int id PK "AUTO_INCREMENT"
int user_id FK "→ USERS, CASCADE"
string name "NOT NULL"
int category_id FK "→ CATEGORIES, INDEXED"
string color
string location "INDEXED"
text description "For auto-matching"
date date_lost "INDEXED"
string status "INDEXED, DEFAULT: active"
datetime resolved_at
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
ATTACHMENTS {
int id PK "AUTO_INCREMENT"
int item_id FK "nullable, → ITEMS"
int lost_item_id FK "nullable, → LOST_ITEMS"
string file_url "NOT NULL"
string file_type "jpg, png, etc"
int file_size "in bytes"
string upload_by_user_id FK "→ USERS"
int display_order "for ordering"
boolean is_primary "DEFAULT: FALSE"
timestamp created_at
timestamp updated_at
}
CLAIMS {
int id PK "AUTO_INCREMENT"
int item_id FK "→ ITEMS, CASCADE, INDEXED"
int user_id FK "→ USERS, CASCADE, INDEXED"
text description "User's verification desc"
string proof_url
string contact "NOT NULL"
string status "INDEXED, DEFAULT: pending"
text notes "Admin notes"
datetime verified_at
int verified_by FK "→ USERS, nullable"
string rejection_reason
int attempt_count "Default: 1"
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
CLAIM_VERIFICATIONS {
int id PK "AUTO_INCREMENT"
int claim_id FK "UNIQUE, → CLAIMS"
decimal similarity_score "0-100, INDEXED"
text matched_keywords "JSON format"
text verification_notes
boolean is_auto_matched "DEFAULT: FALSE"
string verification_method "manual/auto"
json metadata "Additional verification data"
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE"
}
VERIFICATION_LOGS {
int id PK "AUTO_INCREMENT"
int verification_id FK "→ CLAIM_VERIFICATIONS"
int verified_by_user_id FK "→ USERS"
string action "approve/reject/pending"
text reason
timestamp created_at
}
MATCH_RESULTS {
int id PK "AUTO_INCREMENT"
int lost_item_id FK "→ LOST_ITEMS, INDEXED"
int item_id FK "→ ITEMS, INDEXED"
decimal similarity_score "0-100, threshold: 70"
text matched_fields "JSON format"
string match_reason "color/location/description"
datetime matched_at
boolean is_notified "INDEXED, DEFAULT: FALSE"
datetime notified_at
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
ARCHIVES {
int id PK "AUTO_INCREMENT"
int item_id FK "UNIQUE, Original ID"
string name
int category_id FK "→ CATEGORIES, INDEXED"
string photo_url
string location
text description
date date_found
string status
string reporter_name
string reporter_contact
string archived_reason "expired/closed/claimed"
int claimed_by FK "→ USERS, SET NULL"
datetime archived_at "INDEXED"
timestamp created_at
timestamp updated_at
timestamp deleted_at "SOFT DELETE, INDEXED"
}
REVISION_LOGS {
int id PK "AUTO_INCREMENT"
int item_id FK "→ ITEMS, CASCADE, INDEXED"
int user_id FK "→ USERS, CASCADE, INDEXED"
string field_name "changed field"
text old_value
text new_value
text reason
timestamp created_at "INDEXED"
timestamp deleted_at "SOFT DELETE"
}
AUDIT_LOGS {
int id PK "AUTO_INCREMENT"
int user_id FK "nullable, → USERS, INDEXED"
string action "INDEXED (CREATE/READ/UPDATE/DELETE)"
string entity_type "INDEXED (table name)"
int entity_id "INDEXED"
json details "Change details"
string ip_address
string user_agent
timestamp created_at "INDEXED"
timestamp deleted_at "SOFT DELETE"
}
NOTIFICATIONS {
int id PK "AUTO_INCREMENT"
int user_id FK "→ USERS, CASCADE, INDEXED"
string type "INDEXED (match/claim/update)"
string title
text message
string entity_type "INDEXED"
int entity_id
string channel "email/sms/push"
boolean is_read "INDEXED, DEFAULT: FALSE"
datetime read_at
timestamp created_at "INDEXED"
timestamp updated_at
timestamp deleted_at "SOFT DELETE"
}