Initial commit - Lost and Found Revisi

This commit is contained in:
bambang-code1
2025-12-20 00:01:08 +07:00
commit f4c838471c
210 changed files with 30706 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
-- database/enhancement.sql
-- ============================================
-- ENHANCEMENT FOR LOST & FOUND DATABASE (SAFE MODE)
-- Hanya Procedures, Views, dan Indexes
USE iot_db;
DELIMITER $$
-- ============================================
-- STORED PROCEDURES
-- ============================================
-- Procedure: Archive expired items
DROP PROCEDURE IF EXISTS sp_archive_expired_items$$
CREATE PROCEDURE sp_archive_expired_items(
OUT p_archived_count INT
)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_item_id INT;
DECLARE cur CURSOR FOR
SELECT id FROM items
WHERE expires_at < NOW()
AND status = 'unclaimed'
AND deleted_at IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET p_archived_count = 0;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_item_id;
IF done THEN
LEAVE read_loop;
END IF;
-- Archive the item
INSERT INTO archives (
item_id, name, category_id, photo_url, location,
description, date_found, status, reporter_name,
reporter_contact, archived_reason
)
SELECT
id, name, category_id, photo_url, location,
description, date_found, status, reporter_name,
reporter_contact, 'expired'
FROM items
WHERE id = v_item_id;
-- Update item status
UPDATE items
SET status = 'expired'
WHERE id = v_item_id;
SET p_archived_count = p_archived_count + 1;
END LOOP;
CLOSE cur;
END$$
-- Procedure: Get dashboard statistics
DROP PROCEDURE IF EXISTS sp_get_dashboard_stats$$
CREATE PROCEDURE sp_get_dashboard_stats(
OUT p_total_items INT,
OUT p_unclaimed_items INT,
OUT p_verified_items INT,
OUT p_pending_claims INT
)
BEGIN
SELECT COUNT(*) INTO p_total_items FROM items WHERE deleted_at IS NULL;
SELECT COUNT(*) INTO p_unclaimed_items FROM items WHERE status = 'unclaimed' AND deleted_at IS NULL;
SELECT COUNT(*) INTO p_verified_items FROM items WHERE status = 'verified' AND deleted_at IS NULL;
SELECT COUNT(*) INTO p_pending_claims FROM claims WHERE status = 'pending' AND deleted_at IS NULL;
END$$
DELIMITER ;
-- ============================================
-- VIEWS
-- ============================================
CREATE OR REPLACE VIEW vw_dashboard_stats AS
SELECT
(SELECT COUNT(*) FROM items WHERE status = 'unclaimed' AND deleted_at IS NULL) AS total_unclaimed,
(SELECT COUNT(*) FROM items WHERE status = 'verified' AND deleted_at IS NULL) AS total_verified,
(SELECT COUNT(*) FROM lost_items WHERE status = 'active' AND deleted_at IS NULL) AS total_lost_reports,
(SELECT COUNT(*) FROM claims WHERE status = 'pending' AND deleted_at IS NULL) AS pending_claims,
(SELECT COUNT(*) FROM match_results WHERE is_notified = FALSE AND deleted_at IS NULL) AS unnotified_matches;
CREATE OR REPLACE VIEW vw_items_detail AS
SELECT
i.id, i.name, c.name AS category_name, c.slug AS category_slug,
i.photo_url, i.location, i.date_found, i.status,
i.reporter_name, i.reporter_contact, i.expires_at,
u.name AS reporter_user_name, u.email AS reporter_email,
DATEDIFF(i.expires_at, NOW()) AS days_until_expire, i.created_at
FROM items i
JOIN categories c ON i.category_id = c.id
JOIN users u ON i.reporter_id = u.id
WHERE i.deleted_at IS NULL;
CREATE OR REPLACE VIEW vw_claims_detail AS
SELECT
c.id, c.status, i.name AS item_name, cat.name AS category_name,
u.name AS claimant_name, u.email AS claimant_email, u.phone AS claimant_phone,
c.description AS claim_description, c.contact, cv.similarity_score,
c.verified_at, v.name AS verified_by_name, c.notes, c.created_at
FROM claims c
JOIN items i ON c.item_id = i.id
JOIN categories cat ON i.category_id = cat.id
JOIN users u ON c.user_id = u.id
LEFT JOIN claim_verifications cv ON c.id = cv.claim_id
LEFT JOIN users v ON c.verified_by = v.id
WHERE c.deleted_at IS NULL;
CREATE OR REPLACE VIEW vw_match_results_detail AS
SELECT
mr.id, li.name AS lost_item_name, li.user_id AS lost_by_user_id,
u.name AS lost_by_user_name, u.email AS lost_by_email,
i.name AS found_item_name, i.reporter_name AS found_by_name,
mr.similarity_score, mr.is_notified, mr.matched_at,
i.id AS found_item_id, li.id AS lost_item_id
FROM match_results mr
JOIN lost_items li ON mr.lost_item_id = li.id
JOIN items i ON mr.item_id = i.id
JOIN users u ON li.user_id = u.id
WHERE mr.deleted_at IS NULL
ORDER BY mr.similarity_score DESC;
CREATE OR REPLACE VIEW vw_category_stats AS
SELECT
c.id, c.name, c.slug,
COUNT(DISTINCT i.id) AS total_items,
COUNT(DISTINCT CASE WHEN i.status = 'unclaimed' THEN i.id END) AS unclaimed_items,
COUNT(DISTINCT CASE WHEN i.status = 'verified' THEN i.id END) AS verified_items,
COUNT(DISTINCT li.id) AS total_lost_reports
FROM categories c
LEFT JOIN items i ON c.id = i.category_id AND i.deleted_at IS NULL
LEFT JOIN lost_items li ON c.id = li.category_id AND li.deleted_at IS NULL
WHERE c.deleted_at IS NULL
GROUP BY c.id, c.name, c.slug;
CREATE OR REPLACE VIEW vw_user_activity AS
SELECT
u.id, u.name, u.email, r.name AS role_name,
COUNT(DISTINCT i.id) AS items_reported,
COUNT(DISTINCT li.id) AS lost_items_reported,
COUNT(DISTINCT cl.id) AS claims_made,
COUNT(DISTINCT CASE WHEN cl.status = 'approved' THEN cl.id END) AS claims_approved,
u.created_at AS member_since
FROM users u
JOIN roles r ON u.role_id = r.id
LEFT JOIN items i ON u.id = i.reporter_id AND i.deleted_at IS NULL
LEFT JOIN lost_items li ON u.id = li.user_id AND li.deleted_at IS NULL
LEFT JOIN claims cl ON u.id = cl.user_id AND cl.deleted_at IS NULL
WHERE u.deleted_at IS NULL
GROUP BY u.id, u.name, u.email, r.name, u.created_at;
CREATE OR REPLACE VIEW vw_recent_activities AS
SELECT
al.id, al.action, al.entity_type, al.entity_id, al.details,
u.name AS user_name, u.email AS user_email, r.name AS user_role,
al.ip_address, al.created_at
FROM audit_logs al
LEFT JOIN users u ON al.user_id = u.id
LEFT JOIN roles r ON u.role_id = r.id
ORDER BY al.created_at DESC
LIMIT 100;
-- ============================================
-- INDEXES
-- ============================================
-- Hapus index jika exist (cara aman di MySQL lama agak ribet, jadi langsung CREATE saja biasanya OK jika belum ada)
-- Gunakan DROP INDEX jika perlu mereset index
CREATE INDEX idx_items_status_category ON items(status, category_id, deleted_at);
CREATE INDEX idx_items_date_status ON items(date_found, status, deleted_at);
CREATE INDEX idx_claims_status_item ON claims(status, item_id, deleted_at);
CREATE INDEX idx_match_results_scores ON match_results(similarity_score DESC, is_notified);
CREATE INDEX idx_audit_logs_date_user ON audit_logs(created_at DESC, user_id);
CREATE INDEX idx_lost_items_status_user ON lost_items(status, user_id, deleted_at);
CREATE INDEX idx_notifications_user_read ON notifications(user_id, is_read, created_at DESC);
-- Full-text indexes
CREATE FULLTEXT INDEX idx_items_search ON items(name, location);
CREATE FULLTEXT INDEX idx_lost_items_search ON lost_items(name, description);
-- ============================================
-- SUCCESS MESSAGE
-- ============================================
SELECT '✅ Database enhancements (Safe Mode) created!' AS Status;
SELECT '⚙️ Procedures: 2' AS Info;
SELECT '📈 Views: 7' AS Info;
SELECT '🚀 Indexes: 9' AS Info;
SELECT '⚠️ Note: Triggers & Functions dihapus untuk menghindari Error 1419' AS Note;
+31
View File
@@ -0,0 +1,31 @@
START TRANSACTION;
-- 1. Pindahkan item yang sudah kadaluarsa ke tabel archives
INSERT INTO archives (
item_id, name, category_id, photo_url, location,
description, date_found, status, reporter_name,
reporter_contact, archived_reason, archived_at
)
SELECT
id, name, category_id, photo_url, location,
description, date_found, 'expired', reporter_name,
reporter_contact, 'expired', NOW()
FROM items
WHERE expires_at < NOW()
AND status = 'unclaimed'
AND deleted_at IS NULL
-- Pastikan item ini belum ada di archives untuk mencegah duplikat
AND NOT EXISTS (SELECT 1 FROM archives WHERE archives.item_id = items.id);
-- 2. Update status di tabel items menjadi 'expired'
UPDATE items
SET status = 'expired'
WHERE expires_at < NOW()
AND status = 'unclaimed'
AND deleted_at IS NULL;
COMMIT;
-- 3. Cek Hasilnya
SELECT id, name, status, expires_at FROM items WHERE status = 'expired';
SELECT * FROM archives WHERE archived_reason = 'expired';
+16
View File
@@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS chat_messages (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED NOT NULL,
message TEXT NOT NULL,
response TEXT NOT NULL,
context_data JSON DEFAULT NULL COMMENT 'Data konteks (items, lost_items, dll)',
intent VARCHAR(50) DEFAULT NULL COMMENT 'search_item, report_lost, claim_help, general',
confidence_score DECIMAL(5,2) DEFAULT 0.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_chat_user_id (user_id),
INDEX idx_chat_intent (intent),
INDEX idx_chat_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SELECT '✅ AI Chat table created successfully!' AS Status;
+34
View File
@@ -0,0 +1,34 @@
-- ✅ ADD CASE CLOSE COLUMNS TO items TABLE
ALTER TABLE items
ADD COLUMN berita_acara_no VARCHAR(100) NULL AFTER expires_at,
ADD COLUMN bukti_serah_terima VARCHAR(255) NULL AFTER berita_acara_no,
ADD COLUMN case_closed_at DATETIME NULL AFTER bukti_serah_terima,
ADD COLUMN case_closed_by INT UNSIGNED NULL AFTER case_closed_at,
ADD COLUMN case_closed_notes TEXT NULL AFTER case_closed_by,
ADD CONSTRAINT fk_items_case_closed_by FOREIGN KEY (case_closed_by) REFERENCES users(id);
-- ✅ ADD CASE CLOSE COLUMNS TO archives TABLE
ALTER TABLE archives
ADD COLUMN berita_acara_no VARCHAR(100) NULL AFTER claimed_by,
ADD COLUMN bukti_serah_terima VARCHAR(255) NULL AFTER berita_acara_no;
ALTER TABLE lost_items ADD COLUMN matched_at DATETIME NULL;
-- ✅ ADD INDEX FOR BETTER QUERY PERFORMANCE
CREATE INDEX idx_items_case_closed ON items(case_closed_at, case_closed_by);
CREATE INDEX idx_items_berita_acara ON items(berita_acara_no);
-- ✅ VERIFY CHANGES
SELECT
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE,
COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'items'
AND COLUMN_NAME IN ('berita_acara_no', 'bukti_serah_terima', 'case_closed_at', 'case_closed_by', 'case_closed_notes')
ORDER BY ORDINAL_POSITION;
+60
View File
@@ -0,0 +1,60 @@
-- Add direct_claim_id to lost_items table
ALTER TABLE lost_items
ADD COLUMN direct_claim_id INT UNSIGNED NULL,
ADD CONSTRAINT fk_lost_items_direct_claim
FOREIGN KEY (direct_claim_id) REFERENCES claims(id)
ON DELETE SET NULL;
-- Add new claim status
ALTER TABLE claims
MODIFY COLUMN status VARCHAR(50) DEFAULT 'pending';
-- Add index for better performance
CREATE INDEX idx_lost_items_direct_claim ON lost_items(direct_claim_id);
CREATE INDEX idx_lost_items_status ON lost_items(status);
CREATE INDEX idx_claims_status ON claims(status);
-- Add direct_claim_id to lost_items table
ALTER TABLE lost_items
ADD COLUMN IF NOT EXISTS direct_claim_id INT UNSIGNED NULL,
ADD CONSTRAINT fk_lost_items_direct_claim
FOREIGN KEY (direct_claim_id) REFERENCES claims(id)
ON DELETE SET NULL;
-- Add new claim status
ALTER TABLE claims
MODIFY COLUMN status VARCHAR(50) DEFAULT 'pending';
-- Add indexes (only if they don't exist)
CREATE INDEX IF NOT EXISTS idx_lost_items_direct_claim ON lost_items(direct_claim_id);
CREATE INDEX IF NOT EXISTS idx_lost_items_status ON lost_items(status);
CREATE INDEX IF NOT EXISTS idx_claims_status ON claims(status);
ALTER TABLE lost_items
ADD COLUMN direct_claim_id INT UNSIGNED NULL;
-- Add foreign key constraint
ALTER TABLE lost_items
ADD CONSTRAINT fk_lost_items_direct_claim
FOREIGN KEY (direct_claim_id) REFERENCES claims(id)
ON DELETE SET NULL;
-- Modify claim status column
ALTER TABLE claims
MODIFY COLUMN status VARCHAR(50) DEFAULT 'pending';
-- Create index for direct_claim_id (new index, shouldn't exist)
CREATE INDEX idx_lost_items_direct_claim ON lost_items(direct_claim_id);
-- 1. Ubah kolom item_id agar boleh NULL
ALTER TABLE claims MODIFY item_id INT UNSIGNED NULL;
-- 2. Tambah kolom lost_item_id
ALTER TABLE claims
ADD COLUMN lost_item_id INT UNSIGNED NULL AFTER item_id;
-- 3. Tambah Foreign Key untuk lost_item_id
ALTER TABLE claims
ADD CONSTRAINT fk_claims_lost_item
FOREIGN KEY (lost_item_id) REFERENCES lost_items(id)
ON DELETE SET NULL;
+376
View File
@@ -0,0 +1,376 @@
-- database/schema.sql
-- 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 verification_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 attachments;
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,
permissions JSON DEFAULT NULL COMMENT 'RBAC permissions in JSON format',
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) DEFAULT NULL, -- ✅ Ubah dari 500 ke 20
phone VARCHAR(20) DEFAULT NULL, -- ✅ Ubah dari 500 ke 20
role_id INT UNSIGNED NOT NULL DEFAULT 3,
status VARCHAR(20) DEFAULT 'active',
last_login DATETIME 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 (role_id) REFERENCES roles(id) ON DELETE RESTRICT,
INDEX idx_users_email (email),
INDEX idx_users_nrp (nrp), -- ✅ Hapus (255) karena sudah tidak perlu
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,
icon_url VARCHAR(255) DEFAULT NULL COMMENT 'Category icon URL',
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 'Public description',
secret_details TEXT DEFAULT NULL COMMENT 'RAHASIA - untuk verifikasi klaim (hanya visible untuk owner/admin)',
date_found DATE NOT NULL COMMENT 'Tanggal barang ditemukan',
status VARCHAR(50) DEFAULT 'unclaimed' COMMENT 'unclaimed, claimed, expired',
reporter_id INT UNSIGNED NOT NULL,
reporter_name VARCHAR(100) NOT NULL,
reporter_contact VARCHAR(50) NOT NULL,
view_count INT DEFAULT 0 COMMENT 'Total views untuk analytics',
expires_at TIMESTAMP NULL DEFAULT NULL COMMENT 'Tanggal barang akan dihapus (3 bulan dari date_found)',
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 COMMENT 'Deskripsi untuk auto-matching',
date_lost DATE NOT NULL COMMENT 'Tanggal barang hilang',
status VARCHAR(50) DEFAULT 'active' COMMENT 'active, resolved',
resolved_at DATETIME DEFAULT NULL COMMENT 'Kapan laporan hilang ditandai sebagai selesai',
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;
-- ============================================
-- ATTACHMENTS TABLE (Foto Barang)
-- ============================================
CREATE TABLE attachments (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
item_id INT UNSIGNED DEFAULT NULL COMMENT 'FK to items, nullable for lost_items',
lost_item_id INT UNSIGNED DEFAULT NULL COMMENT 'FK to lost_items, nullable for items',
file_url VARCHAR(255) NOT NULL,
file_type VARCHAR(50) DEFAULT NULL COMMENT 'jpg, png, gif, dll',
file_size INT DEFAULT NULL COMMENT 'File size in bytes',
upload_by_user_id INT UNSIGNED DEFAULT NULL,
display_order INT DEFAULT 0 COMMENT 'Order untuk display multiple photos',
is_primary BOOLEAN DEFAULT FALSE COMMENT 'Primary photo untuk display',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
FOREIGN KEY (lost_item_id) REFERENCES lost_items(id) ON DELETE CASCADE,
FOREIGN KEY (upload_by_user_id) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_attachments_item_id (item_id),
INDEX idx_attachments_lost_item_id (lost_item_id),
INDEX idx_attachments_is_primary (is_primary)
) 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' COMMENT 'pending, approved, rejected',
notes TEXT DEFAULT NULL COMMENT 'Admin verification notes',
rejection_reason VARCHAR(255) DEFAULT NULL COMMENT 'Alasan penolakan klaim',
attempt_count INT DEFAULT 1 COMMENT 'Jumlah percobaan klaim (fraud prevention)',
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 COMMENT 'Similarity score 0-100',
matched_keywords TEXT DEFAULT NULL COMMENT 'Keywords matched (JSON format)',
verification_notes TEXT DEFAULT NULL,
is_auto_matched BOOLEAN DEFAULT FALSE,
verification_method VARCHAR(50) DEFAULT 'manual' COMMENT 'manual, auto, hybrid',
metadata JSON DEFAULT NULL COMMENT 'Additional verification data (extensible)',
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;
-- ============================================
-- VERIFICATION_LOGS TABLE (Audit Trail Verifikasi)
-- ============================================
CREATE TABLE verification_logs (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
verification_id INT UNSIGNED NOT NULL,
verified_by_user_id INT UNSIGNED NOT NULL,
action VARCHAR(50) NOT NULL COMMENT 'approve, reject, pending, review',
reason TEXT DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (verification_id) REFERENCES claim_verifications(id) ON DELETE CASCADE,
FOREIGN KEY (verified_by_user_id) REFERENCES users(id) ON DELETE RESTRICT,
INDEX idx_verification_logs_verification_id (verification_id),
INDEX idx_verification_logs_verified_by_user_id (verified_by_user_id),
INDEX idx_verification_logs_created_at (created_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 COMMENT 'JSON format: {category, description, color}',
match_reason VARCHAR(100) DEFAULT NULL COMMENT 'Reason for matching: color, location, description, etc',
matched_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
is_notified BOOLEAN DEFAULT FALSE,
notified_at DATETIME DEFAULT NULL COMMENT 'Kapan user diberitahu tentang match',
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 DATE DEFAULT NULL COMMENT 'Tanggal barang ditemukan (dari items)',
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;
-- 1. Tabel Daftar Hak Akses (Permissions)
CREATE TABLE permissions (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
slug VARCHAR(50) UNIQUE NOT NULL COMMENT 'Kode unik, misal: item:create',
name VARCHAR(100) NOT NULL COMMENT 'Nama deskriptif, misal: Create Item',
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_permissions_slug (slug)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 2. Tabel Pivot (Menghubungkan Role dengan Permission)
CREATE TABLE role_permissions (
role_id INT UNSIGNED NOT NULL,
permission_id INT UNSIGNED NOT NULL,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
) 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,
channel VARCHAR(50) DEFAULT 'push' COMMENT 'email, sms, push',
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: 15 (UPGRADED from 13)' AS Info;
SELECT '🔑 Indexes created on all tables' AS Info;
SELECT '🔗 Foreign keys with proper constraints' AS Info;
SELECT '✨ NOW SYNC with ERD diagram!' AS Info;
SELECT '📝 Next step: Run seed.sql to populate initial data' AS NextStep;
+315
View File
@@ -0,0 +1,315 @@
-- seed.sql
-- ============================================
-- 1. ROLES & CATEGORIES
-- ============================================
INSERT INTO roles (id, name, description) VALUES
(1, 'admin', 'Administrator with full access'),
(2, 'manager', 'Manager for verification and approval'),
(3, 'user', 'Regular user (student)');
INSERT INTO categories (id, name, slug, description) VALUES
(1, 'Pakaian', 'pakaian', 'Baju, celana, jaket, dll'),
(2, 'Alat Makan', 'alat-makan', 'Botol, tupperware, dll'),
(3, 'Aksesoris', 'aksesoris', 'Jam tangan, kacamata, perhiasan'),
(4, 'Elektronik', 'elektronik', 'HP, laptop, charger, dll'),
(5, 'Alat Tulis', 'alat-tulis', 'Pulpen, buku, pensil, dll'),
(6, 'Lainnya', 'lainnya', 'Barang lain yang tidak masuk kategori');
-- ============================================
-- 2. USERS (Explicit IDs 1-10)
-- ============================================
INSERT INTO users (id, name, email, password, nrp, phone, role_id, status, last_login) VALUES
(1, 'Admin', 'admin@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '0001', '081234567890', 1, 'active', NULL),
(2, 'Pak Budi', 'manager1@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567890', '081234567891', 2, 'active', NULL),
(3, 'Bu Siti', 'manager2@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567891', '081234567892', 2, 'active', NULL),
(4, 'Ahmad Rizki', 'ahmad@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211004', '081234567893', 3, 'active', '2024-02-12 09:15:00'),
(5, 'Siti Nurhaliza', 'siti@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211005', '081234567894', 3, 'active', '2024-02-11 14:20:00'),
(6, 'Budi Santoso', 'budi@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211008', '081234567895', 3, 'active', '2024-02-08 16:30:00'),
(7, 'Dewi Lestari', 'dewi@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211009', '081234567896', 3, 'active', '2024-01-15 11:00:00'),
(8, 'Pak Joko', 'manager3@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567892', '081234567898', 2, 'active', '2024-02-11 08:30:00'),
(9, 'Rina Melati', 'rina@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211006', '081234567899', 3, 'active', '2024-02-10 13:20:00'),
(10, 'Fajar Ramadhan', 'fajar@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211007', '081234567800', 3, 'active', '2024-02-09 10:45:00');
-- ============================================
-- 3. ITEMS (FOUND ITEMS) - Explicit IDs 1-19
-- ============================================
-- ============================================
-- 3. ITEMS (FOUND ITEMS) - Updated with Real Photo URLs
-- ============================================
INSERT INTO items (id, name, category_id, photo_url, location, description, secret_details, date_found, status, reporter_id, reporter_name, reporter_contact, view_count, expires_at) VALUES
(1, 'Sweater Adidas Abu-abu', 1, '/uploads/items/crewnecksweateradidasabugr170555915195375838_20251215_120350.jpg', 'Ruang Kelas A201', 'Sweater abu-abu Adidas ukuran L', 'Kancing tengah hilang', '2024-01-15', 'claimed', 2, 'Pak Budi', '081234567891', 25, '2024-04-15 10:00:00'),
(2, 'Mouse Wireless Logitech Pebble', 4, '/uploads/items/logitech-pebble-2-mouse-wireless-bluetooth-silent-_20251215_120318.jpg', 'Lab Komputer 1', 'Mouse wireless Logitech Pebble warna biru', 'Tidak ada receiver USB', '2024-01-25', 'unclaimed', 2, 'Pak Budi', '081234567891', 31, '2024-04-25 14:00:00'),
(3, 'Charger Laptop HP', 4, '/uploads/items/17213fdc51f440e20c356e0cb0daff85_20251215_120303.jpg', 'Perpustakaan', 'Charger HP 65W original', 'Kabel kusut, konektor bulat', '2024-02-01', 'unclaimed', 2, 'Pak Budi', '081234567891', 27, '2024-05-01 09:00:00'),
(4, 'Jam Tangan G-Shock', 3, '/uploads/items/71fbd7e4ed969327b4c63fd0337fa076_20251215_120248.jpg', 'Lapangan Basket', 'Jam G-Shock hitam strip orange', 'Baterai bagus, tali lentur', '2024-02-05', 'claimed', 3, 'Bu Siti', '081234567892', 42, '2024-05-05 11:00:00'),
(5, 'Powerbank Xiaomi', 4, '/uploads/items/4854ab7ea206ecf4608a421a3aae9d84_20251215_120228.jpeg', 'Ruang Kelas E102', 'Powerbank Xiaomi warna putih 10000mAh', 'Kapasitas baterai masih 80%', '2024-02-16', 'unclaimed', 2, 'Pak Budi', '081234567891', 33, '2024-05-16 15:00:00'),
(6, 'Kacamata Minus Frame Hitam', 3, '/uploads/items/images6_20251215_120215.jpeg', 'Masjid Kampus', 'Kacamata frame hitam rectangular', 'Minus tinggi, lensa tebal', '2024-02-06', 'unclaimed', 2, 'Pak Budi', '081234567891', 19, '2024-05-06 13:00:00'),
(7, 'Pensil Mekanik Rotring', 5, '/uploads/items/6361b48b1cdbce097e6c44f4-brand-new-rotring-300-bla_20251215_120202.jpg', 'Studio Gambar', 'Pensil Rotring 300 warna hitam 0.5mm', 'Ada penyok kecil di barrel', '2024-02-09', 'unclaimed', 2, 'Pak Budi', '081234567891', 15, '2024-05-09 15:00:00'),
(8, 'Tumbler Stainless', 2, '/uploads/items/sg-11134201-22120-nm8gakxbodlvf3_20251215_120151.jpeg', 'Kantin Utama', 'Tumbler stainless steel warna silver 500ml', 'Ada lecet di bagian bawah', '2024-02-12', 'unclaimed', 2, 'Pak Budi', '081234567891', 45, '2024-05-12 09:00:00'),
(9, 'Dompet Kulit Coklat', 6, '/uploads/items/9f3daf02f82abac0969c375c2e969711_20251215_120141.jpeg', 'Toilet Gedung B', 'Dompet kulit warna coklat tua branded', 'Ada foto keluarga di dalam', '2024-02-13', 'unclaimed', 3, 'Bu Siti', '081234567892', 52, '2024-05-13 10:30:00'),
(10, 'Payung Lipat Hitam', 6, '/uploads/items/08ebc54bcd3dd6a6d56e8164f825b70djpg720x720q80_20251215_120130.jpg', 'Gedung C Lantai 2', 'Payung lipat otomatis warna hitam', 'Gagang ada retak kecil', '2024-02-14', 'unclaimed', 2, 'Pak Budi', '081234567891', 38, '2024-05-14 11:00:00'),
(11, 'Tas Ransel Abu-abu', 6, '/uploads/items/5203b11f93f324a1a9eed170ef3425ecjpg720x720q80_20251215_120113.jpg', 'Perpustakaan lantai 2', 'Tas ransel warna abu-abu dengan banyak kompartemen', 'Resleting saku kecil rusak', '2024-02-15', 'unclaimed', 2, 'Pak Budi', '081234567891', 29, '2024-05-15 13:30:00'),
(12, 'Flashdisk SanDisk 32GB', 4, '/uploads/items/38f52092-5525-4684-b85c-1820b540353b169_20251215_120103.png', 'Lab Komputer 2', 'Flashdisk SanDisk Ultra 32GB warna hitam', 'Ada file kuliah di dalamnya', '2024-02-17', 'unclaimed', 3, 'Bu Siti', '081234567892', 21, '2024-05-17 08:45:00'),
(13, 'Botol Minum Sport', 2, '/uploads/items/a90e0ef7f1b7696015c444446f367073_20251215_120050.jpeg', 'Lapangan Olahraga', 'Botol minum sport warna biru 750ml', 'Ada stiker nama yang sudah pudar', '2024-02-18', 'unclaimed', 3, 'Bu Siti', '081234567892', 35, '2024-05-18 14:20:00'),
(14, 'Gelang Emas', 3, '/uploads/items/4356295123897739306453191304230020784342341n21_20251215_120038.jpg', 'Toilet Wanita Gedung C', 'Gelang emas motif bunga halus', 'Cap 22K di bagian dalam', '2024-02-19', 'unclaimed', 3, 'Bu Siti', '081234567892', 61, '2024-05-19 09:15:00'),
(15, 'Kalung Model Italy', 3, '/uploads/items/KalungRantaiModelItaly1-600x600_20251215_115944.jpg', 'Mushola Kampus', 'Kalung rantai model Italy warna gold', 'Rantai ada yang kusut sedikit', '2024-02-20', 'unclaimed', 2, 'Pak Budi', '081234567891', 17, '2024-05-20 09:15:00'),
(16, 'Buku Kalkulus Purcell', 5, '/uploads/items/productimage-1752141317_20251215_120335.jpg', 'Perpustakaan Lantai 3', 'Buku Kalkulus Purcell edisi 9 hardcover', 'Coretan nama di halaman pertama', '2024-02-08', 'claimed', 3, 'Bu Siti', '081234567892', 34, '2024-05-08 10:00:00');
-- ============================================
-- 4. LOST_ITEMS (BARANG HILANG) - Explicit IDs 1-11
-- ============================================
INSERT INTO lost_items (id, user_id, name, category_id, color, location, description, date_lost, status, resolved_at) VALUES
(1, 4, 'Charger Laptop', 4, 'Hitam', 'Perpustakaan', 'Charger laptop HP 65W dengan kabel panjang', '2024-02-01', 'active', NULL),
(2, 5, 'Lunchbox Hello Kitty', 2, 'Pink', 'Gedung B', 'Kotak makan pink dengan gambar Hello Kitty di tutup', '2024-01-22', 'active', NULL),
(3, 7, 'Sweater ITS', 1, 'Abu-abu', 'Perpustakaan', 'Sweater abu-abu dengan tulisan ITS di punggung', '2024-01-18', 'active', NULL),
(4, 7, 'Pensil Mekanik Rotring', 5, 'Silver', 'Studio Gambar', 'Pensil mekanik Rotring 0.5mm warna silver', '2024-02-10', 'active', NULL),
-- Items 5-11 match the match_results requirements
(5, 4, 'Charger Laptop', 4, 'Hitam', 'Perpustakaan', 'Charger laptop HP 65W', '2024-02-01', 'active', NULL),
(6, 6, 'Mouse Wireless', 4, 'Hitam', 'Lab Komputer 1', 'Mouse Logitech tanpa receiver', '2024-01-25', 'active', NULL),
(7, 7, 'Kacamata Minus', 3, 'Hitam', 'Masjid Kampus', 'Kacamata frame hitam', '2024-02-06', 'active', NULL),
(8, 4, 'Charger HP', 4, 'Hitam', 'Perpustakaan', 'Charger HP original', '2024-02-01', 'active', NULL),
(9, 5, 'Botol Minum', 2, 'Biru', 'Kantin', 'Botol minum biru 500ml', '2024-01-20', 'active', NULL),
(10, 7, 'Pensil Mekanik', 5, 'Silver', 'Studio Gambar', 'Pensil Rotring 0.5mm', '2024-02-10', 'active', NULL),
(11, 7, 'Topi Merah', 6, 'Merah', 'Lapangan', 'Topi baseball merah', '2024-02-15', 'active', NULL);
-- ============================================
-- 5. CLAIMS (Explicit IDs 1-10)
-- ============================================
INSERT INTO claims (id, item_id, user_id, description, proof_url, contact, status, notes, rejection_reason, attempt_count, verified_at, verified_by) VALUES
(1, 8, 5, 'Jam tangan G-Shock hitam dengan strip orange', '/proofs/claim4.jpg', '081234567894', 'approved', 'Semua detail cocok', NULL, 1, '2024-02-07 14:00:00', 2),
(2, 1, 7, 'Sweater abu-abu dengan tulisan ITS', '/proofs/claim5.jpg', '081234567896', 'approved', 'Deskripsi sangat detail', NULL, 1, '2024-02-06 11:20:00', 3),
(3, 7, 7, 'Buku Kalkulus Purcell edisi 9', '/proofs/claim6.jpg', '081234567896', 'approved', 'Buku diserahkan', NULL, 1, '2024-02-11 09:45:00', 2),
(4, 5, 5, 'Jam tangan G-Shock hitam', '/proofs/claim_gshock.jpg', '081234567894', 'approved', 'Valid', NULL, 1, '2024-02-07 14:00:00', 2),
(5, 1, 7, 'Sweater ITS', '/proofs/claim_sweater.jpg', '081234567896', 'approved', 'Valid', NULL, 1, '2024-02-06 11:20:00', 3),
(6, 7, 7, 'Buku Kalkulus', '/proofs/claim_buku.jpg', '081234567896', 'approved', 'Valid', NULL, 1, '2024-02-11 09:45:00', 2),
(7, 4, 4, 'Charger laptop HP 65W original', '/proofs/claim7.jpg', '081234567893', 'pending', NULL, NULL, 1, NULL, NULL),
(8, 2, 5, 'Botol minum biru ada stiker nama', '/proofs/claim8.jpg', '081234567894', 'pending', NULL, NULL, 1, NULL, NULL),
(9, 8, 7, 'Pensil mekanik Rotring', '/proofs/claim9.jpg', '081234567896', 'pending', NULL, NULL, 1, NULL, NULL),
(10, 3, 6, 'Mouse wireless Logitech merah', '/proofs/claim10.jpg', '081234567895', 'rejected', NULL, 'Deskripsi tidak cocok', 1, NULL, 2);
-- ============================================
-- 6. CLAIM_VERIFICATIONS (Explicit IDs)
-- ============================================
INSERT INTO claim_verifications (id, claim_id, similarity_score, matched_keywords, verification_notes, is_auto_matched, verification_method, metadata) VALUES
(1, 4, 89.40, '["jam", "tangan", "gshock"]', 'Excellent match', TRUE, 'hybrid', JSON_OBJECT('confidence', 'very_high')),
(2, 5, 93.20, '["sweater", "abu", "its"]', 'Perfect match', FALSE, 'manual', JSON_OBJECT('confidence', 'very_high')),
(3, 6, 90.10, '["buku", "kalkulus"]', 'Verified with original name', FALSE, 'manual', JSON_OBJECT('confidence', 'very_high')),
(4, 7, 86.80, '["charger", "laptop", "hp"]', 'High similarity', FALSE, 'manual', JSON_OBJECT('confidence', 'high')),
(5, 8, 91.50, '["botol", "minum", "biru"]', 'Very high match', FALSE, 'manual', JSON_OBJECT('confidence', 'very_high')),
(6, 9, 87.60, '["pensil", "mekanik"]', 'Good match', FALSE, 'manual', JSON_OBJECT('confidence', 'high')),
(7, 10, 45.30, '["mouse", "wireless"]', 'Low match', FALSE, 'manual', JSON_OBJECT('confidence', 'low'));
-- ============================================
-- 7. VERIFICATION LOGS
-- ============================================
INSERT INTO verification_logs (verification_id, verified_by_user_id, action, reason) VALUES
(1, 2, 'approve', 'Semua detail cocok.'),
(2, 3, 'approve', 'Detail kancing hilang cocok.'),
(3, 2, 'approve', 'Nama asli di buku cocok.'),
(4, 2, 'pending', 'Menunggu konfirmasi SN.'),
(5, 3, 'pending', 'Dalam proses scheduling.'),
(6, 2, 'pending', 'Menunggu cek fisik.'),
(7, 2, 'reject', 'Deskripsi receiver tidak cocok.');
-- ============================================
-- 8. MATCH RESULTS (Explicit Foreign Keys)
-- ============================================
INSERT INTO match_results (lost_item_id, item_id, similarity_score, matched_fields, match_reason, matched_at, is_notified, notified_at) VALUES
(6, 3, 88.90, '{"name": 87}', 'Mouse match', '2024-02-08 10:30:00', TRUE, '2024-02-08 11:00:00'),
(7, 6, 85.70, '{"name": 83}', 'Kacamata match', '2024-02-05 15:00:00', TRUE, '2024-02-05 15:30:00'),
(8, 4, 87.30, '{"name": 85}', 'Charger match', '2024-02-01 11:00:00', TRUE, '2024-02-01 11:45:00'),
(9, 2, 90.50, '{"name": 89}', 'Botol match', '2024-01-18 14:30:00', TRUE, '2024-01-18 15:00:00'),
(10, 8, 86.20, '{"name": 84}', 'Pensil match', '2024-02-10 16:00:00', TRUE, '2024-02-10 16:30:00');
-- ============================================
-- 9. NOTIFICATIONS
-- ============================================
INSERT INTO notifications (user_id, type, title, message, entity_type, entity_id, channel, is_read, read_at) VALUES
(5, 'match_found', 'Barang Mirip', 'Item found: Jam Tangan', 'match', 4, 'push', TRUE, '2024-02-03 14:30:00'),
(7, 'match_found', 'Barang Mirip', 'Item found: Buku Kalkulus', 'match', 6, 'push', TRUE, '2024-02-08 11:15:00'),
(7, 'match_found', 'Barang Mirip', 'Item found: Kacamata', 'match', 7, 'push', FALSE, NULL),
(4, 'match_found', 'Barang Mirip', 'Item found: Charger', 'match', 8, 'push', FALSE, NULL),
(5, 'claim_approved', 'Klaim Disetujui', 'Klaim G-Shock disetujui', 'claim', 4, 'email', TRUE, '2024-02-07 14:30:00'),
(7, 'claim_approved', 'Klaim Disetujui', 'Klaim Sweater disetujui', 'claim', 5, 'email', TRUE, '2024-02-06 12:00:00'),
(2, 'new_claim', 'Klaim Baru', 'Klaim: Charger Laptop', 'claim', 7, 'push', FALSE, NULL);
-- ============================================
-- 10. AUDIT LOGS
-- ============================================
INSERT INTO audit_logs (user_id, action, entity_type, entity_id, details) VALUES
(4, 'create', 'lost_item', 1, 'Lost item report created'),
(5, 'create', 'lost_item', 2, 'Lost item report created'),
(7, 'create', 'lost_item', 3, 'Lost item report created'),
(5, 'create', 'claim', 4, 'Claim created for item'),
(7, 'create', 'claim', 5, 'Claim created for item'),
(2, 'approve', 'claim', 4, 'Claim approved'),
(3, 'approve', 'claim', 5, 'Claim approved');
-- ============================================
-- 11. ARCHIVES (Target: 10 Data)
-- Menambahkan data barang lama yang sudah diarsipkan
-- ============================================
INSERT INTO archives (item_id, name, category_id, photo_url, location, description, date_found, status, reporter_name, reporter_contact, archived_reason, claimed_by, archived_at) VALUES
(101, 'Jaket Denim', 1, '/photos/archive1.jpg', 'Kantin', 'Jaket denim pudar', '2023-12-01', 'claimed', 'Pak Budi', '081234567891', 'case_closed', 4, '2023-12-05 10:00:00'),
(102, 'Kunci Motor Honda', 6, '/photos/archive2.jpg', 'Parkiran', 'Kunci motor gantungan boneka', '2023-12-02', 'claimed', 'Satpam', '081234567777', 'case_closed', 5, '2023-12-03 14:00:00'),
(103, 'Payung Kuning', 6, '/photos/archive3.jpg', 'Lobi Utama', 'Payung panjang kuning', '2023-11-15', 'expired', 'Bu Siti', '081234567892', 'expired', NULL, '2024-02-15 00:00:00'),
(104, 'Tumblr Starbucks', 2, '/photos/archive4.jpg', 'Perpustakaan', 'Tumblr hitam logo hijau', '2023-12-10', 'claimed', 'Pak Budi', '081234567891', 'case_closed', 6, '2023-12-12 09:00:00'),
(105, 'Buku Catatan Fisika', 5, '/photos/archive5.jpg', 'Kelas B201', 'Buku spiral biru', '2023-12-05', 'expired', 'Cleaning Service', '081234567888', 'expired', NULL, '2024-03-05 00:00:00'),
(106, 'Topi Rimba', 1, '/photos/archive6.jpg', 'Mushola', 'Topi rimba warna krem', '2023-12-20', 'claimed', 'Pak Joko', '081234567898', 'case_closed', 7, '2023-12-21 16:00:00'),
(107, 'Headset Sony', 4, '/photos/archive7.jpg', 'Lab Komputer', 'Headset kabel hitam', '2023-11-20', 'claimed', 'Admin', '081234567890', 'case_closed', 4, '2023-11-25 11:30:00'),
(108, 'Syal Batik', 1, '/photos/archive8.jpg', 'Gedung Rektorat', 'Syal motif batik coklat', '2023-12-25', 'expired', 'Resepsionis', '081234567000', 'expired', NULL, '2024-03-25 00:00:00'),
(109, 'Kalkulator Casio', 4, '/photos/archive9.jpg', 'Meja Piket', 'Kalkulator scientific', '2023-12-15', 'claimed', 'Bu Siti', '081234567892', 'case_closed', 8, '2023-12-16 08:00:00'),
(110, 'Earphone Bluetooth', 4, '/photos/archive10.jpg', 'Taman Alumni', 'Case putih sebelah kiri saja', '2023-11-30', 'expired', 'Mahasiswa', '081xxx', 'expired', NULL, '2024-02-28 00:00:00');
-- ============================================
-- 12. ATTACHMENTS (Target: 10 Data)
-- Menambahkan foto tambahan untuk barang yang ada
-- ============================================
INSERT INTO attachments (item_id, lost_item_id, file_url, file_type, file_size, upload_by_user_id, is_primary) VALUES
(1, NULL, '/photos/item2_detail1.jpg', 'jpg', 204800, 2, TRUE),
(1, NULL, '/photos/item2_detail2.jpg', 'jpg', 150300, 2, FALSE),
(2, NULL, '/photos/item4_zoom.jpg', 'jpg', 180500, 3, TRUE),
(3, NULL, '/photos/item6_back.jpg', 'jpg', 220100, 2, TRUE),
(4, NULL, '/photos/item7_plug.jpg', 'jpg', 190000, 2, TRUE),
(NULL, 1, '/photos/lost_item1_ref.jpg', 'jpg', 300000, 4, TRUE),
(NULL, 2, '/photos/lost_item2_ref.jpg', 'jpg', 250000, 5, TRUE),
(5, NULL, '/photos/item8_strap.jpg', 'jpg', 120000, 3, FALSE),
(6, NULL, '/photos/item9_case.jpg', 'jpg', 140000, 2, FALSE),
(10, NULL, '/photos/item13_inside.jpg', 'jpg', 210000, 3, FALSE);
-- ============================================
-- 13. REVISION LOGS (Target: 10 Data)
-- Simulasi edit data barang
-- ============================================
INSERT INTO revision_logs (item_id, user_id, field_name, old_value, new_value, reason, created_at) VALUES
(1, 2, 'location', 'Kelas A200', 'Ruang Kelas A201', 'Koreksi nomor ruangan', '2024-01-16 09:00:00'),
(2, 3, 'description', 'Botol minum biru', 'Botol minum biru 500ml', 'Menambah detail ukuran', '2024-01-21 10:00:00'),
(3, 2, 'status', 'unclaimed', 'process', 'Ada yang bertanya', '2024-01-26 14:00:00'),
(3, 2, 'status', 'process', 'unclaimed', 'Bukan pemiliknya', '2024-01-27 09:00:00'),
(4, 2, 'location', 'Perpus', 'Perpustakaan', 'Typo', '2024-02-02 08:30:00'),
(5, 3, 'name', 'Jam Tangan', 'Jam Tangan G-Shock', 'Spesifikasi merk', '2024-02-05 12:00:00'),
(8, 2, 'description', 'Pensil mekanik', 'Pensil Mekanik Rotring 0.5mm silver', 'Detail tambahan', '2024-02-09 16:00:00'),
(10, 3, 'secret_details', 'Ada uang', 'Ada foto keluarga di dalam', 'Update info rahasia', '2024-02-13 11:00:00'),
(11, 2, 'photo_url', NULL, '/photos/item14.jpg', 'Foto baru diupload', '2024-02-14 12:00:00'),
(1, 2, 'status', 'unclaimed', 'claimed', 'Barang diambil pemilik', '2024-02-15 10:00:00');
-- ============================================
-- 14. AUDIT LOGS (Tambahan 3 Data -> Total 10)
-- Menambah log aktivitas sistem
-- ============================================
INSERT INTO audit_logs (user_id, action, entity_type, entity_id, details) VALUES
(1, 'login', 'user', 1, 'Admin login via web'),
(2, 'update', 'item', 1, 'Manager updated item location'),
(3, 'delete', 'comment', 45, 'Manager removed spam comment');
-- ============================================
-- 15. CLAIM VERIFICATIONS (Tambahan 3 Data -> Total 10)
-- Melengkapi verifikasi untuk Claim ID 1, 2, 3
-- ============================================
INSERT INTO claim_verifications (claim_id, similarity_score, matched_keywords, verification_notes, is_auto_matched, verification_method, metadata) VALUES
(1, 95.50, '["jam", "tangan", "hitam"]', 'Bukti foto sangat jelas dan cocok', TRUE, 'hybrid', JSON_OBJECT('confidence', 'very_high')),
(2, 88.00, '["sweater", "abu", "its"]', 'Ciri-ciri fisik sesuai deskripsi', FALSE, 'manual', JSON_OBJECT('confidence', 'high')),
(3, 92.10, '["buku", "kalkulus", "purcell"]', 'Nama di halaman depan sesuai KTM', FALSE, 'manual', JSON_OBJECT('confidence', 'very_high'));
-- ============================================
-- 16. NOTIFICATIONS (Tambahan 3 Data -> Total 10)
-- Notifikasi tambahan
-- ============================================
INSERT INTO notifications (user_id, type, title, message, entity_type, entity_id, channel, is_read) VALUES
(4, 'claim_update', 'Status Klaim', 'Klaim Anda sedang diverifikasi', 'claim', 7, 'email', TRUE),
(6, 'system_info', 'Maintenance', 'Sistem akan maintenance jam 12 malam', NULL, NULL, 'push', FALSE),
(8, 'new_task', 'Verifikasi Baru', 'Ada 3 klaim baru menunggu verifikasi', 'claim', NULL, 'push', FALSE);
-- ============================================
-- 17. MATCH RESULTS (Tambahan 5 Data -> Total 10)
-- Matching untuk Lost Items 1, 2, 3, 5, 11
-- ============================================
INSERT INTO match_results (lost_item_id, item_id, similarity_score, matched_fields, match_reason, matched_at, is_notified) VALUES
(1, 4, 91.20, '{"name": 90, "category": 100}', 'Charger HP match', '2024-02-02 08:00:00', TRUE),
(2, 2, 65.50, '{"category": 100, "color": 50}', 'Possible bottle match', '2024-01-23 09:00:00', FALSE),
(3, 1, 89.80, '{"name": 88, "color": 100}', 'Sweater match confirmed', '2024-01-19 10:00:00', TRUE),
(5, 13, 75.40, '{"category": 100}', 'Powerbank similar category', '2024-02-16 16:00:00', TRUE),
(11, 12, 95.00, '{"name": 95, "color": 100}', 'Topi merah exact match', '2024-02-15 14:00:00', TRUE);
-- 1. Insert Permissions
INSERT INTO permissions (id, slug, name, description) VALUES
(1, 'item:read', 'View Items', 'Melihat daftar barang (public/dashboard)'),
(2, 'item:create', 'Create Item', 'Melaporkan barang temuan/hilang'),
(3, 'item:update', 'Update Item', 'Mengedit data barang'),
(4, 'item:delete', 'Delete Item', 'Menghapus data barang'),
(5, 'item:verify', 'Verify Item', 'Verifikasi detail barang (lihat detail rahasia)'),
(6, 'claim:read', 'View Claims', 'Melihat daftar klaim'),
(7, 'claim:create', 'Create Claim', 'Mengajukan klaim barang'),
(8, 'claim:approve', 'Approve Claim', 'Menyetujui klaim (verifikasi fisik)'),
(9, 'claim:reject', 'Reject Claim', 'Menolak klaim'),
(10, 'user:read', 'View Users', 'Melihat daftar pengguna'),
(11, 'user:update', 'Update User Role', 'Mengubah role pengguna'),
(12, 'user:block', 'Block/Unblock User', 'Memblokir atau membuka blokir user'),
(13, 'report:export', 'Export Report', 'Export laporan ke PDF/Excel'),
(14, 'audit:read', 'View Audit Log', 'Melihat log aktivitas sistem'),
(15, 'category:manage', 'Manage Categories', 'Membuat, edit, hapus kategori');
-- 2. Assign Permissions to Roles
-- Role ID 1: Admin (All Permissions)
-- A. ADMIN (Role ID: 1) - Punya SEMUA (1-15)
INSERT INTO role_permissions (role_id, permission_id)
SELECT 1, id FROM permissions;
-- B. MANAGER (Role ID: 2) - Operasional
INSERT INTO role_permissions (role_id, permission_id) VALUES
(2, 1), (2, 3), (2, 5), (2, 6), (2, 8), (2, 9), (2, 10), (2, 13);
-- C. USER (Role ID: 3) - Dasar
INSERT INTO role_permissions (role_id, permission_id) VALUES
(3, 1), (3, 2), (3, 6), (3, 7);
-- 1. Tambahkan permission baru khusus untuk Laporan Kehilangan (Lost Item)
-- Melanjutkan ID terakhir dari seed2.sql (ID 15)
INSERT INTO permissions (id, slug, name, description) VALUES
(16, 'lost_item:update', 'Update Lost Item', 'Mengedit laporan kehilangan (Admin/Manager)'),
(17, 'lost_item:delete', 'Delete Lost Item', 'Menghapus laporan kehilangan (Admin/Manager)');
-- 2. Berikan akses ke ADMIN (Role ID: 1)
-- Admin harus punya semua akses
INSERT INTO role_permissions (role_id, permission_id) VALUES
(1, 16),
(1, 17);
-- 3. Berikan akses ke MANAGER (Role ID: 2)
-- Sesuai permintaan: akses edit dan hapus laporan barang hilang
INSERT INTO role_permissions (role_id, permission_id) VALUES
(2, 16), -- Akses Edit Lost Item
(2, 17); -- Akses Hapus Lost Item
-- ============================================
-- SUCCESS MESSAGE - UPDATED
-- ============================================
SELECT '✅ Extended database seed completed!' AS Status;
SELECT '🎭 Roles: 3 roles (admin, manager, user) - NO CHANGES' AS Info;
SELECT '📂 Categories: 6 categories (Pakaian, Alat Makan, Aksesoris, Elektronik, Alat Tulis, Lainnya) - NO CHANGES' AS Info;
SELECT '👥 Users: 10 total (1 admin, 3 managers, 6 students) (EXTENDED ✓)' AS Info;
SELECT '📦 Items: 19 found items (EXTENDED ✓)' AS Info;
SELECT '📝 Lost items: 11 reports (EXTENDED ✓)' AS Info;
SELECT '🎫 Claims: 11 claims - 4 approved, 4 pending, 1 rejected (EXTENDED ✓)' AS Info;
SELECT '✔️ Claim verifications: 10 records (EXTENDED ✓)' AS Info;
SELECT '🔗 Match results: 10 matches (EXTENDED ✓)' AS Info;
SELECT '🔔 Notifications: 17 notifications (EXTENDED ✓)' AS Info;
SELECT '📋 Audit logs: 28+ records (EXTENDED ✓)' AS Info;
SELECT 'Additional information' AS Info;
SELECT '✨ All main tables now have 10+ meaningful records!' AS Complete;
SELECT '🚀 Database is fully populated and ready!' AS Ready;
+71
View File
@@ -0,0 +1,71 @@
-- seed2.sql
-- 1. ROLES & CATEGORIES
INSERT INTO roles (id, name, description) VALUES
(1, 'admin', 'Administrator with full access'),
(2, 'manager', 'Manager for verification and approval'),
(3, 'user', 'Regular user (student)');
INSERT INTO categories (id, name, slug, description) VALUES
(1, 'Pakaian', 'pakaian', 'Baju, celana, jaket, dll'),
(2, 'Alat Makan', 'alat-makan', 'Botol, tupperware, dll'),
(3, 'Aksesoris', 'aksesoris', 'Jam tangan, kacamata, perhiasan'),
(4, 'Elektronik', 'elektronik', 'HP, laptop, charger, dll'),
(5, 'Alat Tulis', 'alat-tulis', 'Pulpen, buku, pensil, dll'),
(6, 'Lainnya', 'lainnya', 'Barang lain yang tidak masuk kategori');
-- 2. USERS (Explicit IDs 1-10)
INSERT INTO users (id, name, email, password, nrp, phone, role_id, status, last_login) VALUES
(1, 'Admin', 'admin@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '0001', '081234567890', 1, 'active', NULL),
(2, 'Pak Budi', 'manager1@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567890', '081234567891', 2, 'active', NULL),
(3, 'Bu Siti', 'manager2@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567891', '081234567892', 2, 'active', NULL),
(4, 'Ahmad Rizki', 'ahmad@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211004', '081234567893', 3, 'active', '2024-02-12 09:15:00'),
(5, 'Siti Nurhaliza', 'siti@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211005', '081234567894', 3, 'active', '2024-02-11 14:20:00'),
(6, 'Budi Santoso', 'budi@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211008', '081234567895', 3, 'active', '2024-02-08 16:30:00'),
(7, 'Dewi Lestari', 'dewi@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211009', '081234567896', 3, 'active', '2024-01-15 11:00:00'),
(8, 'Pak Joko', 'manager3@lostandfound.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '2234567892', '081234567898', 2, 'active', '2024-02-11 08:30:00'),
(9, 'Rina Melati', 'rina@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211006', '081234567899', 3, 'active', '2024-02-10 13:20:00'),
(10, 'Fajar Ramadhan', 'fajar@student.com', '$2a$10$zhRlU9e1v6T2x4/bPwOZNOAqSktHjj6QFgXV3i2/0pITlKasUpv4G', '5025211007', '081234567800', 3, 'active', '2024-02-09 10:45:00');
-- 1. Insert Permissions
INSERT INTO permissions (id, slug, name, description) VALUES
(1, 'item:read', 'View Items', 'Melihat daftar barang (public/dashboard)'),
(2, 'item:create', 'Create Item', 'Melaporkan barang temuan/hilang'),
(3, 'item:update', 'Update Item', 'Mengedit data barang'),
(4, 'item:delete', 'Delete Item', 'Menghapus data barang'),
(5, 'item:verify', 'Verify Item', 'Verifikasi detail barang (lihat detail rahasia)'),
(6, 'claim:read', 'View Claims', 'Melihat daftar klaim'),
(7, 'claim:create', 'Create Claim', 'Mengajukan klaim barang'),
(8, 'claim:approve', 'Approve Claim', 'Menyetujui klaim (verifikasi fisik)'),
(9, 'claim:reject', 'Reject Claim', 'Menolak klaim'),
(10, 'user:read', 'View Users', 'Melihat daftar pengguna'),
(11, 'user:update', 'Update User Role', 'Mengubah role pengguna'),
(12, 'user:block', 'Block/Unblock User', 'Memblokir atau membuka blokir user'),
(13, 'report:export', 'Export Report', 'Export laporan ke PDF/Excel'),
(14, 'audit:read', 'View Audit Log', 'Melihat log aktivitas sistem'),
(15, 'category:manage', 'Manage Categories', 'Membuat, edit, hapus kategori');
-- 2. Assign Permissions to Roles
-- Role ID 1: Admin (All Permissions)
-- A. ADMIN (Role ID: 1) - Punya SEMUA (1-15)
INSERT INTO role_permissions (role_id, permission_id)
SELECT 1, id FROM permissions;
-- B. MANAGER (Role ID: 2) - Operasional
INSERT INTO role_permissions (role_id, permission_id) VALUES
(2, 1), (2, 3), (2, 5), (2, 6), (2, 8), (2, 9), (2, 10), (2, 13);
-- C. USER (Role ID: 3) - Dasar
INSERT INTO role_permissions (role_id, permission_id) VALUES
(3, 1), (3, 2), (3, 6), (3, 7);
-- 1. Tambahkan permission baru khusus untuk Laporan Kehilangan (Lost Item)
-- Melanjutkan ID terakhir dari seed2.sql (ID 15)
INSERT INTO permissions (id, slug, name, description) VALUES
(16, 'lost_item:update', 'Update Lost Item', 'Mengedit laporan kehilangan (Admin/Manager)'),
(17, 'lost_item:delete', 'Delete Lost Item', 'Menghapus laporan kehilangan (Admin/Manager)');
-- 2. Berikan akses ke ADMIN (Role ID: 1)
-- Admin harus punya semua akses
INSERT INTO role_permissions (role_id, permission_id) VALUES
(1, 16),
(1, 17);
-- 3. Berikan akses ke MANAGER (Role ID: 2)
-- Sesuai permintaan: akses edit dan hapus laporan barang hilang
INSERT INTO role_permissions (role_id, permission_id) VALUES
(2, 16), -- Akses Edit Lost Item
(2, 17); -- Akses Hapus Lost Item