-- Ported from backend/src/main/resources/db/migration/V1__init.sql CREATE TABLE users ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, username VARCHAR(50) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(80) NOT NULL, email VARCHAR(120), department VARCHAR(80), must_change_password BOOLEAN NOT NULL, enabled BOOLEAN NOT NULL, locked BOOLEAN NOT NULL ); CREATE TABLE user_roles ( user_id BIGINT NOT NULL REFERENCES users (id), role VARCHAR(20) NOT NULL ); CREATE INDEX idx_user_roles_user ON user_roles (user_id); CREATE TABLE zones ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, code VARCHAR(30) NOT NULL UNIQUE, name VARCHAR(80) NOT NULL, description VARCHAR(255), security_level INTEGER NOT NULL, active BOOLEAN NOT NULL ); CREATE TABLE visitors ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, name VARCHAR(80) NOT NULL, company VARCHAR(120), contact VARCHAR(40), email VARCHAR(120), vehicle_no VARCHAR(20) ); CREATE INDEX idx_visitor_name ON visitors (name); CREATE INDEX idx_visitor_contact ON visitors (contact); CREATE TABLE visit_requests ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, visitor_id BIGINT NOT NULL REFERENCES visitors (id), host_id BIGINT NOT NULL REFERENCES users (id), zone_name VARCHAR(80), purpose VARCHAR(255) NOT NULL, visit_from TIMESTAMP NOT NULL, visit_to TIMESTAMP NOT NULL, status VARCHAR(20) NOT NULL, qr_token VARCHAR(64) ); CREATE INDEX idx_vr_status ON visit_requests (status); CREATE INDEX idx_vr_visit_from ON visit_requests (visit_from); CREATE INDEX idx_vr_qr_token ON visit_requests (qr_token); CREATE TABLE approvals ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, visit_request_id BIGINT NOT NULL REFERENCES visit_requests (id), approver_id BIGINT NOT NULL REFERENCES users (id), decision VARCHAR(20) NOT NULL, comment VARCHAR(500), decided_at TIMESTAMP NOT NULL ); CREATE TABLE access_events ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, visit_request_id BIGINT NOT NULL REFERENCES visit_requests (id), direction VARCHAR(8) NOT NULL, gate_id VARCHAR(40), operator_id BIGINT REFERENCES users (id), event_at TIMESTAMP NOT NULL ); CREATE INDEX idx_ae_visit_request ON access_events (visit_request_id); CREATE INDEX idx_ae_event_at ON access_events (event_at); CREATE INDEX idx_ae_direction ON access_events (direction); CREATE TABLE blacklist ( id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, name VARCHAR(80) NOT NULL, company VARCHAR(120), contact VARCHAR(40), reason VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, created_by BIGINT REFERENCES users (id) ); CREATE INDEX idx_bl_name ON blacklist (name); CREATE INDEX idx_bl_contact ON blacklist (contact); INSERT INTO zones (created_at, updated_at, code, name, description, security_level, active) VALUES (now(), now(), 'LOBBY', '로비', NULL, 1, TRUE), (now(), now(), 'OFFICE', '사무공간', NULL, 2, TRUE), (now(), now(), 'SERVER_ROOM', '전산실', NULL, 3, TRUE);