diff --git a/meeting/src/main/resources/db/migration/V1__create_initial_schema.sql b/meeting/src/main/resources/db/migration/V1__create_initial_schema.sql new file mode 100644 index 0000000..4bafc9f --- /dev/null +++ b/meeting/src/main/resources/db/migration/V1__create_initial_schema.sql @@ -0,0 +1,177 @@ +-- ===================================================== +-- HGZero Meeting Service - Initial Schema +-- Version: V1 +-- Description: 초기 데이터베이스 스키마 생성 +-- ===================================================== + +-- Note: 기존 테이블이 있으면 유지하고, 없으면 새로 생성 +-- CREATE TABLE IF NOT EXISTS를 사용하여 안전하게 처리 + +-- 2. Templates 테이블 +CREATE TABLE IF NOT EXISTS templates ( + template_id VARCHAR(50) PRIMARY KEY, + name VARCHAR(200) NOT NULL, + description TEXT, + category VARCHAR(50) NOT NULL, + sections TEXT, + is_public BOOLEAN NOT NULL DEFAULT true, + created_by VARCHAR(50) NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +-- 3. Meetings 테이블 +CREATE TABLE IF NOT EXISTS meetings ( + meeting_id VARCHAR(50) PRIMARY KEY, + title VARCHAR(200) NOT NULL, + purpose VARCHAR(500), + description TEXT, + scheduled_at TIMESTAMP NOT NULL, + end_time TIMESTAMP, + location VARCHAR(200), + started_at TIMESTAMP, + ended_at TIMESTAMP, + status VARCHAR(20) NOT NULL DEFAULT 'SCHEDULED', + organizer_id VARCHAR(50) NOT NULL, + template_id VARCHAR(50), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_meetings_template FOREIGN KEY (template_id) REFERENCES templates(template_id) +); + +-- 4. Meeting Participants 테이블 (기존 V2 마이그레이션 통합) +CREATE TABLE IF NOT EXISTS meeting_participants ( + meeting_id VARCHAR(50) NOT NULL, + user_id VARCHAR(100) NOT NULL, + invitation_status VARCHAR(20) DEFAULT 'PENDING', + attended BOOLEAN DEFAULT false, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (meeting_id, user_id), + CONSTRAINT fk_participants_meeting FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id) ON DELETE CASCADE +); + +-- 5. Sessions 테이블 +CREATE TABLE IF NOT EXISTS sessions ( + session_id VARCHAR(50) PRIMARY KEY, + meeting_id VARCHAR(50) NOT NULL, + minutes_id VARCHAR(50), + started_by VARCHAR(50) NOT NULL, + started_at TIMESTAMP NOT NULL, + ended_at TIMESTAMP, + status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE', + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_sessions_meeting FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id) +); + +-- 6. Minutes 테이블 +CREATE TABLE IF NOT EXISTS minutes ( + minutes_id VARCHAR(50) PRIMARY KEY, + meeting_id VARCHAR(50) NOT NULL, + title VARCHAR(200) NOT NULL, + status VARCHAR(20) NOT NULL DEFAULT 'DRAFT', + version INTEGER NOT NULL DEFAULT 1, + created_by VARCHAR(50) NOT NULL, + finalized_by VARCHAR(50), + finalized_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_minutes_meeting FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id) +); + +-- 7. Minutes Sections 테이블 +CREATE TABLE IF NOT EXISTS minutes_sections ( + section_id VARCHAR(50) PRIMARY KEY, + minutes_id VARCHAR(50) NOT NULL, + type VARCHAR(50) NOT NULL, + title VARCHAR(200) NOT NULL, + content TEXT, + "order" INTEGER DEFAULT 0, + verified BOOLEAN NOT NULL DEFAULT false, + locked BOOLEAN NOT NULL DEFAULT false, + locked_by VARCHAR(50), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_sections_minutes FOREIGN KEY (minutes_id) REFERENCES minutes(minutes_id) ON DELETE CASCADE +); + +-- 8. Todos 테이블 +CREATE TABLE IF NOT EXISTS todos ( + todo_id VARCHAR(50) PRIMARY KEY, + minutes_id VARCHAR(50), + meeting_id VARCHAR(50) NOT NULL, + title VARCHAR(200) NOT NULL, + description TEXT, + assignee_id VARCHAR(50) NOT NULL, + assignee_name VARCHAR(100), + due_date DATE, + status VARCHAR(20) NOT NULL DEFAULT 'PENDING', + priority VARCHAR(20) DEFAULT 'MEDIUM', + completed_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_todos_meeting FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id) +); + +-- 9. Meeting Analysis 테이블 +CREATE TABLE IF NOT EXISTS meeting_analysis ( + analysis_id VARCHAR(50) PRIMARY KEY, + meeting_id VARCHAR(50) NOT NULL, + minutes_id VARCHAR(50) NOT NULL, + agenda_analyses TEXT, + status VARCHAR(20), + completed_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT fk_analysis_meeting FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id), + CONSTRAINT fk_analysis_minutes FOREIGN KEY (minutes_id) REFERENCES minutes(minutes_id) +); + +-- 10. Meeting Keywords 테이블 (ElementCollection) +CREATE TABLE IF NOT EXISTS meeting_keywords ( + analysis_id VARCHAR(50) NOT NULL, + keyword VARCHAR(255), + CONSTRAINT fk_keywords_analysis FOREIGN KEY (analysis_id) REFERENCES meeting_analysis(analysis_id) ON DELETE CASCADE +); + +-- 11. 인덱스 생성 +CREATE INDEX IF NOT EXISTS idx_meetings_organizer ON meetings(organizer_id); +CREATE INDEX IF NOT EXISTS idx_meetings_status ON meetings(status); +CREATE INDEX IF NOT EXISTS idx_meetings_scheduled ON meetings(scheduled_at); + +CREATE INDEX IF NOT EXISTS idx_participants_user ON meeting_participants(user_id); + +CREATE INDEX IF NOT EXISTS idx_sessions_meeting ON sessions(meeting_id); +CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status); + +CREATE INDEX IF NOT EXISTS idx_minutes_meeting ON minutes(meeting_id); +CREATE INDEX IF NOT EXISTS idx_minutes_status ON minutes(status); + +CREATE INDEX IF NOT EXISTS idx_sections_minutes ON minutes_sections(minutes_id); +CREATE INDEX IF NOT EXISTS idx_sections_order ON minutes_sections("order"); + +CREATE INDEX IF NOT EXISTS idx_todos_meeting ON todos(meeting_id); +CREATE INDEX IF NOT EXISTS idx_todos_assignee ON todos(assignee_id); +CREATE INDEX IF NOT EXISTS idx_todos_status ON todos(status); +CREATE INDEX IF NOT EXISTS idx_todos_due_date ON todos(due_date); + +CREATE INDEX IF NOT EXISTS idx_analysis_meeting ON meeting_analysis(meeting_id); +CREATE INDEX IF NOT EXISTS idx_analysis_minutes ON meeting_analysis(minutes_id); + +-- 12. Sessions에 minutes 외래키 추가 (minutes 테이블 생성 후) +-- 기존 데이터 무결성 이슈로 인해 외래키 제약조건 비활성화 +-- ALTER TABLE sessions DROP CONSTRAINT IF EXISTS fk_sessions_minutes; +-- ALTER TABLE sessions ADD CONSTRAINT fk_sessions_minutes +-- FOREIGN KEY (minutes_id) REFERENCES minutes(minutes_id); + +-- 13. Todos에 minutes 외래키 추가 +-- 기존 데이터 무결성 이슈로 인해 외래키 제약조건 비활성화 +-- ALTER TABLE todos DROP CONSTRAINT IF EXISTS fk_todos_minutes; +-- ALTER TABLE todos ADD CONSTRAINT fk_todos_minutes +-- FOREIGN KEY (minutes_id) REFERENCES minutes(minutes_id); + +-- 완료 메시지 +DO $$ +BEGIN + RAISE NOTICE 'Initial schema created successfully'; +END $$; diff --git a/meeting/src/main/resources/db/migration/V2__create_meeting_participants_table.sql b/meeting/src/main/resources/db/migration/V2__create_meeting_participants_table.sql index 95e3cde..25267c9 100644 --- a/meeting/src/main/resources/db/migration/V2__create_meeting_participants_table.sql +++ b/meeting/src/main/resources/db/migration/V2__create_meeting_participants_table.sql @@ -1,41 +1,5 @@ --- 회의 참석자 테이블 생성 -CREATE TABLE IF NOT EXISTS meeting_participants ( - meeting_id VARCHAR(50) NOT NULL, - user_id VARCHAR(100) NOT NULL, - invitation_status VARCHAR(20) DEFAULT 'PENDING', - attended BOOLEAN DEFAULT FALSE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (meeting_id, user_id), - CONSTRAINT fk_meeting_participants_meeting - FOREIGN KEY (meeting_id) REFERENCES meetings(meeting_id) - ON DELETE CASCADE -); +-- V2 마이그레이션은 V1에 통합되었습니다. +-- meeting_participants 테이블은 V1__create_initial_schema.sql에서 생성됩니다. +-- 이 파일은 Flyway 버전 순서 유지를 위해 빈 상태로 유지됩니다. --- 기존 meetings 테이블의 participants 데이터를 meeting_participants 테이블로 마이그레이션 -INSERT INTO meeting_participants (meeting_id, user_id, invitation_status, attended, created_at, updated_at) -SELECT - m.meeting_id, - TRIM(participant) as user_id, - 'PENDING' as invitation_status, - FALSE as attended, - m.created_at, - m.updated_at -FROM meetings m -CROSS JOIN LATERAL unnest(string_to_array(m.participants, ',')) AS participant -WHERE m.participants IS NOT NULL AND m.participants != ''; - --- meetings 테이블에서 participants 컬럼 삭제 -ALTER TABLE meetings DROP COLUMN IF EXISTS participants; - --- 인덱스 생성 -CREATE INDEX idx_meeting_participants_user_id ON meeting_participants(user_id); -CREATE INDEX idx_meeting_participants_invitation_status ON meeting_participants(invitation_status); -CREATE INDEX idx_meeting_participants_meeting_id_status ON meeting_participants(meeting_id, invitation_status); - --- 코멘트 추가 -COMMENT ON TABLE meeting_participants IS '회의 참석자 정보'; -COMMENT ON COLUMN meeting_participants.meeting_id IS '회의 ID'; -COMMENT ON COLUMN meeting_participants.user_id IS '사용자 ID (이메일)'; -COMMENT ON COLUMN meeting_participants.invitation_status IS '초대 상태 (PENDING, ACCEPTED, DECLINED)'; -COMMENT ON COLUMN meeting_participants.attended IS '참석 여부'; +SELECT 1; -- No-op statement to make Flyway happy diff --git a/meeting/src/main/resources/db/migration/V4__fix_missing_columns.sql b/meeting/src/main/resources/db/migration/V4__fix_missing_columns.sql new file mode 100644 index 0000000..c191ceb --- /dev/null +++ b/meeting/src/main/resources/db/migration/V4__fix_missing_columns.sql @@ -0,0 +1,33 @@ +-- V4: 누락된 컬럼 추가 및 스키마 수정 +-- 기존 테이블에 누락된 컬럼들을 추가합니다. + +-- 1. 시퀀스 생성 (먼저) +CREATE SEQUENCE IF NOT EXISTS minutes_sections_temp_seq; + +-- 2. minutes_sections 테이블에 section_id 컬럼 추가 (Primary Key) +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM information_schema.columns + WHERE table_name = 'minutes_sections' AND column_name = 'section_id') THEN + -- 임시 ID 컬럼으로 시작 + ALTER TABLE minutes_sections ADD COLUMN temp_section_id VARCHAR(50); + UPDATE minutes_sections SET temp_section_id = 'section-' || nextval('minutes_sections_temp_seq'::regclass) + WHERE temp_section_id IS NULL; + + -- 기존 Primary Key 제거 (있다면) + ALTER TABLE minutes_sections DROP CONSTRAINT IF EXISTS minutes_sections_pkey; + + -- temp_section_id를 section_id로 변경 + ALTER TABLE minutes_sections RENAME COLUMN temp_section_id TO section_id; + ALTER TABLE minutes_sections ALTER COLUMN section_id SET NOT NULL; + + -- 새로운 Primary Key 설정 + ALTER TABLE minutes_sections ADD PRIMARY KEY (section_id); + END IF; +END $$; + +-- 완료 메시지 +DO $$ +BEGIN + RAISE NOTICE 'Missing columns fixed successfully'; +END $$;