-- 할일관리 시스템 테이블 생성 -- 할일 아이템 테이블 CREATE TABLE IF NOT EXISTS todo_items ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, -- 기본 정보 content TEXT NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'scheduled', 'active', 'completed', 'delayed', 'split')), -- 시간 관리 created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), start_date TIMESTAMP WITH TIME ZONE, estimated_minutes INTEGER CHECK (estimated_minutes > 0 AND estimated_minutes <= 120), completed_at TIMESTAMP WITH TIME ZONE, delayed_until TIMESTAMP WITH TIME ZONE, -- 분할 관리 parent_id UUID REFERENCES todo_items(id) ON DELETE CASCADE, split_order INTEGER, -- 인덱스 CONSTRAINT unique_split_order UNIQUE (parent_id, split_order) ); -- 할일 댓글 테이블 CREATE TABLE IF NOT EXISTS todo_comments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), todo_item_id UUID NOT NULL REFERENCES todo_items(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, content TEXT NOT NULL, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); -- 인덱스 생성 CREATE INDEX IF NOT EXISTS idx_todo_items_user_id ON todo_items(user_id); CREATE INDEX IF NOT EXISTS idx_todo_items_status ON todo_items(status); CREATE INDEX IF NOT EXISTS idx_todo_items_start_date ON todo_items(start_date); CREATE INDEX IF NOT EXISTS idx_todo_items_parent_id ON todo_items(parent_id); CREATE INDEX IF NOT EXISTS idx_todo_comments_todo_item_id ON todo_comments(todo_item_id); CREATE INDEX IF NOT EXISTS idx_todo_comments_user_id ON todo_comments(user_id); -- 트리거: updated_at 자동 업데이트 CREATE OR REPLACE FUNCTION update_todo_comments_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_todo_comments_updated_at BEFORE UPDATE ON todo_comments FOR EACH ROW EXECUTE FUNCTION update_todo_comments_updated_at();