-- 기존 DB에 사용자 시스템 추가 마이그레이션 -- 사용자 테이블 추가 CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('admin', 'user')), is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_login TIMESTAMP ); -- 기존 travel_plans 테이블에 컬럼 추가 (안전하게 하나씩) DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='user_id') THEN ALTER TABLE travel_plans ADD COLUMN user_id INTEGER REFERENCES users(id) ON DELETE SET NULL; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='title') THEN ALTER TABLE travel_plans ADD COLUMN title VARCHAR(255) DEFAULT 'Untitled Trip'; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='description') THEN ALTER TABLE travel_plans ADD COLUMN description TEXT; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='destination') THEN ALTER TABLE travel_plans ADD COLUMN destination VARCHAR(255) DEFAULT 'Kumamoto'; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='is_public') THEN ALTER TABLE travel_plans ADD COLUMN is_public BOOLEAN DEFAULT false; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='is_template') THEN ALTER TABLE travel_plans ADD COLUMN is_template BOOLEAN DEFAULT false; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='template_category') THEN ALTER TABLE travel_plans ADD COLUMN template_category VARCHAR(20); END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='tags') THEN ALTER TABLE travel_plans ADD COLUMN tags TEXT[] DEFAULT '{}'; END IF; IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='travel_plans' AND column_name='status') THEN ALTER TABLE travel_plans ADD COLUMN status VARCHAR(20) DEFAULT 'draft'; END IF; END $$; -- 공유 링크 테이블 추가 CREATE TABLE IF NOT EXISTS share_links ( id SERIAL PRIMARY KEY, trip_id INTEGER NOT NULL REFERENCES travel_plans(id) ON DELETE CASCADE, created_by INTEGER NOT NULL REFERENCES users(id), share_code VARCHAR(8) UNIQUE NOT NULL, expires_at TIMESTAMP, is_active BOOLEAN DEFAULT true, access_count INTEGER DEFAULT 0, max_access_count INTEGER, can_view BOOLEAN DEFAULT true, can_edit BOOLEAN DEFAULT false, can_comment BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_accessed TIMESTAMP ); -- 댓글 테이블 추가 CREATE TABLE IF NOT EXISTS trip_comments ( id SERIAL PRIMARY KEY, trip_id INTEGER NOT NULL REFERENCES travel_plans(id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users(id), content TEXT NOT NULL, is_edited BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 시스템 설정 테이블 추가 CREATE TABLE IF NOT EXISTS system_settings ( key VARCHAR(100) PRIMARY KEY, value TEXT, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 인덱스 추가 CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_users_role ON users(role); CREATE INDEX IF NOT EXISTS idx_travel_plans_user ON travel_plans(user_id); CREATE INDEX IF NOT EXISTS idx_travel_plans_status ON travel_plans(status); CREATE INDEX IF NOT EXISTS idx_share_links_code ON share_links(share_code); CREATE INDEX IF NOT EXISTS idx_share_links_trip ON share_links(trip_id); CREATE INDEX IF NOT EXISTS idx_comments_trip ON trip_comments(trip_id); -- 초기 시스템 설정 INSERT INTO system_settings (key, value, description) VALUES ('app_version', '2.0.0', '애플리케이션 버전'), ('setup_completed', 'false', '초기 설정 완료 여부'), ('jwt_secret_set', 'false', 'JWT 시크릿 설정 여부') ON CONFLICT (key) DO NOTHING; -- 업데이트 트리거 함수 CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ language 'plpgsql'; -- 업데이트 트리거 적용 DROP TRIGGER IF EXISTS update_users_updated_at ON users; CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); DROP TRIGGER IF EXISTS update_travel_plans_updated_at ON travel_plans; CREATE TRIGGER update_travel_plans_updated_at BEFORE UPDATE ON travel_plans FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); DROP TRIGGER IF EXISTS update_comments_updated_at ON trip_comments; CREATE TRIGGER update_comments_updated_at BEFORE UPDATE ON trip_comments FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); DROP TRIGGER IF EXISTS update_settings_updated_at ON system_settings; CREATE TRIGGER update_settings_updated_at BEFORE UPDATE ON system_settings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();