2025-11-17 12:17:44 +07:00

300 lines
13 KiB
SQL

-- Lost & Found Database Schema
-- MySQL/MariaDB Database
-- Set charset dan collation
SET NAMES utf8mb4;
SET CHARACTER SET utf8mb4;
-- Drop tables if exists (untuk clean migration)
DROP TABLE IF EXISTS notifications;
DROP TABLE IF EXISTS revision_logs;
DROP TABLE IF EXISTS match_results;
DROP TABLE IF EXISTS claim_verifications;
DROP TABLE IF EXISTS audit_logs;
DROP TABLE IF EXISTS archives;
DROP TABLE IF EXISTS claims;
DROP TABLE IF EXISTS items;
DROP TABLE IF EXISTS lost_items;
DROP TABLE IF EXISTS categories;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS roles;
-- ============================================
-- ROLES TABLE
-- ============================================
CREATE TABLE roles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
INDEX idx_roles_name (name),
INDEX idx_roles_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- USERS TABLE
-- ============================================
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
nrp VARCHAR(20) UNIQUE DEFAULT NULL,
phone VARCHAR(20) DEFAULT NULL,
role_id INT UNSIGNED NOT NULL DEFAULT 3,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE RESTRICT,
INDEX idx_users_email (email),
INDEX idx_users_nrp (nrp),
INDEX idx_users_role_id (role_id),
INDEX idx_users_status (status),
INDEX idx_users_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- CATEGORIES TABLE
-- ============================================
CREATE TABLE categories (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
INDEX idx_categories_slug (slug),
INDEX idx_categories_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- ITEMS TABLE (Barang Ditemukan)
-- ============================================
CREATE TABLE items (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
category_id INT UNSIGNED NOT NULL,
photo_url VARCHAR(255) DEFAULT NULL,
location VARCHAR(200) NOT NULL,
description TEXT NOT NULL COMMENT 'RAHASIA - untuk verifikasi',
date_found TIMESTAMP NOT NULL,
status VARCHAR(50) DEFAULT 'unclaimed',
reporter_id INT UNSIGNED NOT NULL,
reporter_name VARCHAR(100) NOT NULL,
reporter_contact VARCHAR(50) NOT NULL,
expires_at TIMESTAMP NULL DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE RESTRICT,
FOREIGN KEY (reporter_id) REFERENCES users(id) ON DELETE RESTRICT,
INDEX idx_items_category_id (category_id),
INDEX idx_items_status (status),
INDEX idx_items_reporter_id (reporter_id),
INDEX idx_items_date_found (date_found),
INDEX idx_items_expires_at (expires_at),
INDEX idx_items_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- LOST_ITEMS TABLE (Barang Hilang)
-- ============================================
CREATE TABLE lost_items (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED NOT NULL,
name VARCHAR(100) NOT NULL,
category_id INT UNSIGNED NOT NULL,
color VARCHAR(50) DEFAULT NULL,
location VARCHAR(200) DEFAULT NULL,
description TEXT NOT NULL,
date_lost TIMESTAMP NOT NULL,
status VARCHAR(50) DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE RESTRICT,
INDEX idx_lost_items_user_id (user_id),
INDEX idx_lost_items_category_id (category_id),
INDEX idx_lost_items_status (status),
INDEX idx_lost_items_date_lost (date_lost),
INDEX idx_lost_items_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- CLAIMS TABLE (Klaim Barang)
-- ============================================
CREATE TABLE claims (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
item_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
description TEXT NOT NULL COMMENT 'Deskripsi dari user untuk verifikasi',
proof_url VARCHAR(255) DEFAULT NULL,
contact VARCHAR(50) NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
notes TEXT DEFAULT NULL,
verified_at TIMESTAMP NULL DEFAULT NULL,
verified_by INT UNSIGNED DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (verified_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_claims_item_id (item_id),
INDEX idx_claims_user_id (user_id),
INDEX idx_claims_status (status),
INDEX idx_claims_verified_by (verified_by),
INDEX idx_claims_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- CLAIM_VERIFICATIONS TABLE (Data Verifikasi Klaim)
-- ============================================
CREATE TABLE claim_verifications (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
claim_id INT UNSIGNED UNIQUE NOT NULL,
similarity_score DECIMAL(5,2) DEFAULT 0.00,
matched_keywords TEXT DEFAULT NULL,
verification_notes TEXT DEFAULT NULL,
is_auto_matched BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (claim_id) REFERENCES claims(id) ON DELETE CASCADE,
INDEX idx_claim_verifications_claim_id (claim_id),
INDEX idx_claim_verifications_similarity_score (similarity_score),
INDEX idx_claim_verifications_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- MATCH_RESULTS TABLE (Hasil Auto-Matching)
-- ============================================
CREATE TABLE match_results (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
lost_item_id INT UNSIGNED NOT NULL,
item_id INT UNSIGNED NOT NULL,
similarity_score DECIMAL(5,2) NOT NULL,
matched_fields TEXT DEFAULT NULL,
matched_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
is_notified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (lost_item_id) REFERENCES lost_items(id) ON DELETE CASCADE,
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
INDEX idx_match_results_lost_item_id (lost_item_id),
INDEX idx_match_results_item_id (item_id),
INDEX idx_match_results_similarity_score (similarity_score),
INDEX idx_match_results_is_notified (is_notified),
INDEX idx_match_results_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- ARCHIVES TABLE (Barang yang Diarsipkan)
-- ============================================
CREATE TABLE archives (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
item_id INT UNSIGNED UNIQUE NOT NULL COMMENT 'Original item ID',
name VARCHAR(100) NOT NULL,
category_id INT UNSIGNED NOT NULL,
photo_url VARCHAR(255) DEFAULT NULL,
location VARCHAR(200) DEFAULT NULL,
description TEXT DEFAULT NULL,
date_found TIMESTAMP NULL DEFAULT NULL,
status VARCHAR(50) DEFAULT NULL,
reporter_name VARCHAR(100) DEFAULT NULL,
reporter_contact VARCHAR(50) DEFAULT NULL,
archived_reason VARCHAR(100) DEFAULT NULL COMMENT 'expired, case_closed',
claimed_by INT UNSIGNED DEFAULT NULL,
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE RESTRICT,
FOREIGN KEY (claimed_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_archives_item_id (item_id),
INDEX idx_archives_category_id (category_id),
INDEX idx_archives_archived_reason (archived_reason),
INDEX idx_archives_archived_at (archived_at),
INDEX idx_archives_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- REVISION_LOGS TABLE (Audit Trail Edit Barang)
-- ============================================
CREATE TABLE revision_logs (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
item_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
field_name VARCHAR(50) NOT NULL,
old_value TEXT DEFAULT NULL,
new_value TEXT DEFAULT NULL,
reason TEXT DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_revision_logs_item_id (item_id),
INDEX idx_revision_logs_user_id (user_id),
INDEX idx_revision_logs_created_at (created_at),
INDEX idx_revision_logs_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- AUDIT_LOGS TABLE (System Audit Trail)
-- ============================================
CREATE TABLE audit_logs (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED DEFAULT NULL,
action VARCHAR(50) NOT NULL,
entity_type VARCHAR(50) DEFAULT NULL,
entity_id INT UNSIGNED DEFAULT NULL,
details TEXT DEFAULT NULL,
ip_address VARCHAR(50) DEFAULT NULL,
user_agent VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
INDEX idx_audit_logs_user_id (user_id),
INDEX idx_audit_logs_action (action),
INDEX idx_audit_logs_entity_type (entity_type),
INDEX idx_audit_logs_entity_id (entity_id),
INDEX idx_audit_logs_created_at (created_at),
INDEX idx_audit_logs_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- NOTIFICATIONS TABLE (Notifikasi User)
-- ============================================
CREATE TABLE notifications (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED NOT NULL,
type VARCHAR(50) NOT NULL,
title VARCHAR(200) NOT NULL,
message TEXT NOT NULL,
entity_type VARCHAR(50) DEFAULT NULL,
entity_id INT UNSIGNED DEFAULT NULL,
is_read BOOLEAN DEFAULT FALSE,
read_at TIMESTAMP NULL DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_notifications_user_id (user_id),
INDEX idx_notifications_type (type),
INDEX idx_notifications_is_read (is_read),
INDEX idx_notifications_created_at (created_at),
INDEX idx_notifications_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ============================================
-- SUCCESS MESSAGE
-- ============================================
SELECT '✅ Database schema created successfully!' AS Status;
SELECT '📋 Total tables: 13' AS Info;
SELECT '🔑 Indexes created on all tables' AS Info;
SELECT '📝 Next step: Run seed.sql to populate initial data' AS NextStep;