243 lines
8.0 KiB
Plaintext
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"
|
|
} |