mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 12:46:23 +00:00
백엔드 서비스 구조 개선 및 데이터베이스 스키마 추가
This commit is contained in:
parent
a41e431daf
commit
34291e1613
@ -12,7 +12,6 @@ import javax.crypto.SecretKey;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JWT 토큰 생성 및 검증 제공자
|
* JWT 토큰 생성 및 검증 제공자
|
||||||
@ -57,13 +56,13 @@ public class JwtTokenProvider {
|
|||||||
* @return Access Token
|
* @return Access Token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public String createAccessToken(UUID userId, UUID storeId, String email, String name, List<String> roles) {
|
public String createAccessToken(String userId, String storeId, String email, String name, List<String> roles) {
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expiryDate = new Date(now.getTime() + accessTokenValidityMs);
|
Date expiryDate = new Date(now.getTime() + accessTokenValidityMs);
|
||||||
|
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.subject(userId.toString())
|
.subject(userId)
|
||||||
.claim("storeId", storeId != null ? storeId.toString() : null)
|
.claim("storeId", storeId)
|
||||||
.claim("email", email)
|
.claim("email", email)
|
||||||
.claim("name", name)
|
.claim("name", name)
|
||||||
.claim("roles", roles)
|
.claim("roles", roles)
|
||||||
@ -80,12 +79,12 @@ public class JwtTokenProvider {
|
|||||||
* @param userId 사용자 ID
|
* @param userId 사용자 ID
|
||||||
* @return Refresh Token
|
* @return Refresh Token
|
||||||
*/
|
*/
|
||||||
public String createRefreshToken(UUID userId) {
|
public String createRefreshToken(String userId) {
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expiryDate = new Date(now.getTime() + refreshTokenValidityMs);
|
Date expiryDate = new Date(now.getTime() + refreshTokenValidityMs);
|
||||||
|
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.subject(userId.toString())
|
.subject(userId)
|
||||||
.claim("type", "refresh")
|
.claim("type", "refresh")
|
||||||
.issuedAt(now)
|
.issuedAt(now)
|
||||||
.expiration(expiryDate)
|
.expiration(expiryDate)
|
||||||
@ -99,9 +98,9 @@ public class JwtTokenProvider {
|
|||||||
* @param token JWT 토큰
|
* @param token JWT 토큰
|
||||||
* @return 사용자 ID
|
* @return 사용자 ID
|
||||||
*/
|
*/
|
||||||
public UUID getUserIdFromToken(String token) {
|
public String getUserIdFromToken(String token) {
|
||||||
Claims claims = parseToken(token);
|
Claims claims = parseToken(token);
|
||||||
return UUID.fromString(claims.getSubject());
|
return claims.getSubject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,9 +112,8 @@ public class JwtTokenProvider {
|
|||||||
public UserPrincipal getUserPrincipalFromToken(String token) {
|
public UserPrincipal getUserPrincipalFromToken(String token) {
|
||||||
Claims claims = parseToken(token);
|
Claims claims = parseToken(token);
|
||||||
|
|
||||||
UUID userId = UUID.fromString(claims.getSubject());
|
String userId = claims.getSubject();
|
||||||
String storeIdStr = claims.get("storeId", String.class);
|
String storeId = claims.get("storeId", String.class);
|
||||||
UUID storeId = storeIdStr != null ? UUID.fromString(storeIdStr) : null;
|
|
||||||
String email = claims.get("email", String.class);
|
String email = claims.get("email", String.class);
|
||||||
String name = claims.get("name", String.class);
|
String name = claims.get("name", String.class);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,12 +23,12 @@ public class UserPrincipal implements UserDetails {
|
|||||||
/**
|
/**
|
||||||
* 사용자 ID
|
* 사용자 ID
|
||||||
*/
|
*/
|
||||||
private final UUID userId;
|
private final String userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 매장 ID
|
* 매장 ID
|
||||||
*/
|
*/
|
||||||
private final UUID storeId;
|
private final String storeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자 이메일
|
* 사용자 이메일
|
||||||
|
|||||||
234
develop/database/migration/alter_event_id_to_varchar.sql
Normal file
234
develop/database/migration/alter_event_id_to_varchar.sql
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
-- ====================================================================================================
|
||||||
|
-- Event ID 타입 변경 DDL (UUID → VARCHAR(50)) - PostgreSQL
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 작성일: 2025-10-29
|
||||||
|
-- 작성자: Backend Development Team
|
||||||
|
-- 설명: Event 엔티티의 eventId가 String 타입으로 변경됨에 따라 관련 테이블들의 event_id 컬럼 타입을 UUID에서 VARCHAR(50)으로 변경합니다.
|
||||||
|
-- 영향 범위:
|
||||||
|
-- - events 테이블 (Primary Key)
|
||||||
|
-- - event_channels 테이블 (Foreign Key)
|
||||||
|
-- - generated_images 테이블 (Foreign Key)
|
||||||
|
-- - ai_recommendations 테이블 (Foreign Key)
|
||||||
|
-- - jobs 테이블 (Foreign Key)
|
||||||
|
-- ====================================================================================================
|
||||||
|
|
||||||
|
-- 0. 현재 상태 확인 (실행 전 확인용)
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 각 테이블의 event_id 컬럼 타입 확인
|
||||||
|
-- SELECT table_name, column_name, data_type
|
||||||
|
-- FROM information_schema.columns
|
||||||
|
-- WHERE column_name = 'event_id'
|
||||||
|
-- AND table_schema = 'public'
|
||||||
|
-- ORDER BY table_name;
|
||||||
|
|
||||||
|
-- event_id 관련 모든 외래키 제약조건 확인
|
||||||
|
-- SELECT
|
||||||
|
-- tc.constraint_name,
|
||||||
|
-- tc.table_name,
|
||||||
|
-- kcu.column_name,
|
||||||
|
-- ccu.table_name AS foreign_table_name,
|
||||||
|
-- ccu.column_name AS foreign_column_name
|
||||||
|
-- FROM information_schema.table_constraints AS tc
|
||||||
|
-- JOIN information_schema.key_column_usage AS kcu
|
||||||
|
-- ON tc.constraint_name = kcu.constraint_name
|
||||||
|
-- AND tc.table_schema = kcu.table_schema
|
||||||
|
-- JOIN information_schema.constraint_column_usage AS ccu
|
||||||
|
-- ON ccu.constraint_name = tc.constraint_name
|
||||||
|
-- AND ccu.table_schema = tc.table_schema
|
||||||
|
-- WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
-- AND kcu.column_name = 'event_id'
|
||||||
|
-- AND tc.table_schema = 'public';
|
||||||
|
|
||||||
|
-- 1. 외래키 제약조건 전체 제거
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- JPA가 자동 생성한 제약조건 이름도 포함하여 모두 제거
|
||||||
|
|
||||||
|
-- event_channels 테이블의 모든 event_id 관련 외래키 제거
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
constraint_name TEXT;
|
||||||
|
BEGIN
|
||||||
|
FOR constraint_name IN
|
||||||
|
SELECT tc.constraint_name
|
||||||
|
FROM information_schema.table_constraints AS tc
|
||||||
|
JOIN information_schema.key_column_usage AS kcu
|
||||||
|
ON tc.constraint_name = kcu.constraint_name
|
||||||
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
AND tc.table_name = 'event_channels'
|
||||||
|
AND kcu.column_name = 'event_id'
|
||||||
|
AND tc.table_schema = 'public'
|
||||||
|
LOOP
|
||||||
|
EXECUTE 'ALTER TABLE event_channels DROP CONSTRAINT IF EXISTS ' || constraint_name;
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- generated_images 테이블의 모든 event_id 관련 외래키 제거
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
constraint_name TEXT;
|
||||||
|
BEGIN
|
||||||
|
FOR constraint_name IN
|
||||||
|
SELECT tc.constraint_name
|
||||||
|
FROM information_schema.table_constraints AS tc
|
||||||
|
JOIN information_schema.key_column_usage AS kcu
|
||||||
|
ON tc.constraint_name = kcu.constraint_name
|
||||||
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
AND tc.table_name = 'generated_images'
|
||||||
|
AND kcu.column_name = 'event_id'
|
||||||
|
AND tc.table_schema = 'public'
|
||||||
|
LOOP
|
||||||
|
EXECUTE 'ALTER TABLE generated_images DROP CONSTRAINT IF EXISTS ' || constraint_name;
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- ai_recommendations 테이블의 모든 event_id 관련 외래키 제거
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
constraint_name TEXT;
|
||||||
|
BEGIN
|
||||||
|
FOR constraint_name IN
|
||||||
|
SELECT tc.constraint_name
|
||||||
|
FROM information_schema.table_constraints AS tc
|
||||||
|
JOIN information_schema.key_column_usage AS kcu
|
||||||
|
ON tc.constraint_name = kcu.constraint_name
|
||||||
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
AND tc.table_name = 'ai_recommendations'
|
||||||
|
AND kcu.column_name = 'event_id'
|
||||||
|
AND tc.table_schema = 'public'
|
||||||
|
LOOP
|
||||||
|
EXECUTE 'ALTER TABLE ai_recommendations DROP CONSTRAINT IF EXISTS ' || constraint_name;
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- jobs 테이블의 모든 event_id 관련 외래키 제거
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
constraint_name TEXT;
|
||||||
|
BEGIN
|
||||||
|
FOR constraint_name IN
|
||||||
|
SELECT tc.constraint_name
|
||||||
|
FROM information_schema.table_constraints AS tc
|
||||||
|
JOIN information_schema.key_column_usage AS kcu
|
||||||
|
ON tc.constraint_name = kcu.constraint_name
|
||||||
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||||||
|
AND tc.table_name = 'jobs'
|
||||||
|
AND kcu.column_name = 'event_id'
|
||||||
|
AND tc.table_schema = 'public'
|
||||||
|
LOOP
|
||||||
|
EXECUTE 'ALTER TABLE jobs DROP CONSTRAINT IF EXISTS ' || constraint_name;
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
|
-- 2. 컬럼 타입 변경 (UUID/기타 → VARCHAR)
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 현재 타입에 관계없이 VARCHAR(50)으로 변환
|
||||||
|
-- UUID, BIGINT 등 모든 타입을 텍스트로 변환
|
||||||
|
|
||||||
|
-- events 테이블의 event_id 컬럼 타입 변경 (Primary Key)
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE events ALTER COLUMN event_id TYPE VARCHAR(50) USING event_id::text;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
RAISE NOTICE 'events.event_id 변환 중 오류: %', SQLERRM;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- event_channels 테이블의 event_id 컬럼 타입 변경
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE event_channels ALTER COLUMN event_id TYPE VARCHAR(50) USING event_id::text;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
RAISE NOTICE 'event_channels.event_id 변환 중 오류: %', SQLERRM;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- generated_images 테이블의 event_id 컬럼 타입 변경
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE generated_images ALTER COLUMN event_id TYPE VARCHAR(50) USING event_id::text;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
RAISE NOTICE 'generated_images.event_id 변환 중 오류: %', SQLERRM;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- ai_recommendations 테이블의 event_id 컬럼 타입 변경
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE ai_recommendations ALTER COLUMN event_id TYPE VARCHAR(50) USING event_id::text;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
RAISE NOTICE 'ai_recommendations.event_id 변환 중 오류: %', SQLERRM;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- jobs 테이블의 event_id 컬럼 타입 변경 (NULL 허용)
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE jobs ALTER COLUMN event_id TYPE VARCHAR(50) USING event_id::text;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
RAISE NOTICE 'jobs.event_id 변환 중 오류: %', SQLERRM;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
|
-- 3. 외래키 제약조건 재생성
|
||||||
|
-- ====================================================================================================
|
||||||
|
|
||||||
|
-- event_channels 테이블의 외래키 재생성
|
||||||
|
ALTER TABLE event_channels
|
||||||
|
ADD CONSTRAINT fk_event_channels_event
|
||||||
|
FOREIGN KEY (event_id) REFERENCES events(event_id)
|
||||||
|
ON DELETE CASCADE;
|
||||||
|
|
||||||
|
-- generated_images 테이블의 외래키 재생성
|
||||||
|
ALTER TABLE generated_images
|
||||||
|
ADD CONSTRAINT fk_generated_images_event
|
||||||
|
FOREIGN KEY (event_id) REFERENCES events(event_id)
|
||||||
|
ON DELETE CASCADE;
|
||||||
|
|
||||||
|
-- ai_recommendations 테이블의 외래키 재생성
|
||||||
|
ALTER TABLE ai_recommendations
|
||||||
|
ADD CONSTRAINT fk_ai_recommendations_event
|
||||||
|
FOREIGN KEY (event_id) REFERENCES events(event_id)
|
||||||
|
ON DELETE CASCADE;
|
||||||
|
|
||||||
|
-- jobs 테이블의 외래키 재생성
|
||||||
|
ALTER TABLE jobs
|
||||||
|
ADD CONSTRAINT fk_jobs_event
|
||||||
|
FOREIGN KEY (event_id) REFERENCES events(event_id)
|
||||||
|
ON DELETE SET NULL;
|
||||||
|
|
||||||
|
|
||||||
|
-- 4. 인덱스 확인 (옵션)
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 기존 인덱스들이 자동으로 유지되는지 확인
|
||||||
|
-- \d events
|
||||||
|
-- \d event_channels
|
||||||
|
-- \d generated_images
|
||||||
|
-- \d ai_recommendations
|
||||||
|
-- \d jobs
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 롤백 스크립트 (필요시 사용)
|
||||||
|
-- ====================================================================================================
|
||||||
|
/*
|
||||||
|
-- 1. 외래키 제약조건 제거
|
||||||
|
ALTER TABLE event_channels DROP CONSTRAINT IF EXISTS fk_event_channels_event;
|
||||||
|
ALTER TABLE generated_images DROP CONSTRAINT IF EXISTS fk_generated_images_event;
|
||||||
|
ALTER TABLE ai_recommendations DROP CONSTRAINT IF EXISTS fk_ai_recommendations_event;
|
||||||
|
ALTER TABLE jobs DROP CONSTRAINT IF EXISTS fk_jobs_event;
|
||||||
|
|
||||||
|
-- 2. 컬럼 타입 원복 (VARCHAR → UUID)
|
||||||
|
ALTER TABLE events ALTER COLUMN event_id TYPE UUID USING event_id::UUID;
|
||||||
|
ALTER TABLE event_channels ALTER COLUMN event_id TYPE UUID USING event_id::UUID;
|
||||||
|
ALTER TABLE generated_images ALTER COLUMN event_id TYPE UUID USING event_id::UUID;
|
||||||
|
ALTER TABLE ai_recommendations ALTER COLUMN event_id TYPE UUID USING event_id::UUID;
|
||||||
|
ALTER TABLE jobs ALTER COLUMN event_id TYPE UUID USING event_id::UUID;
|
||||||
|
|
||||||
|
-- 4. 외래키 제약조건 재생성
|
||||||
|
ALTER TABLE event_channels ADD CONSTRAINT fk_event_channels_event FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE generated_images ADD CONSTRAINT fk_generated_images_event FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE ai_recommendations ADD CONSTRAINT fk_ai_recommendations_event FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE;
|
||||||
|
ALTER TABLE jobs ADD CONSTRAINT fk_jobs_event FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE SET NULL;
|
||||||
|
*/
|
||||||
233
develop/database/schema/create_event_tables.sql
Normal file
233
develop/database/schema/create_event_tables.sql
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
-- ====================================================================================================
|
||||||
|
-- Event Service 테이블 생성 스크립트 - PostgreSQL
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 작성일: 2025-10-29
|
||||||
|
-- 작성자: Backend Development Team
|
||||||
|
-- 설명: Event 서비스의 모든 테이블을 생성합니다.
|
||||||
|
-- 참고: FK(Foreign Key) 제약조건은 제외되어 있습니다.
|
||||||
|
-- ====================================================================================================
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 1. events 테이블 - 이벤트 메인 테이블
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS events (
|
||||||
|
event_id VARCHAR(50) PRIMARY KEY,
|
||||||
|
user_id VARCHAR(50) NOT NULL,
|
||||||
|
store_id VARCHAR(50) NOT NULL,
|
||||||
|
event_name VARCHAR(200),
|
||||||
|
description TEXT,
|
||||||
|
objective VARCHAR(100) NOT NULL,
|
||||||
|
start_date DATE,
|
||||||
|
end_date DATE,
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
|
||||||
|
selected_image_id VARCHAR(50),
|
||||||
|
selected_image_url VARCHAR(500),
|
||||||
|
participants INTEGER DEFAULT 0,
|
||||||
|
target_participants INTEGER,
|
||||||
|
roi DOUBLE PRECISION DEFAULT 0.0,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- events 테이블 인덱스
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_user_id ON events(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_store_id ON events(store_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_status ON events(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_events_created_at ON events(created_at);
|
||||||
|
|
||||||
|
COMMENT ON TABLE events IS '이벤트 메인 테이블';
|
||||||
|
COMMENT ON COLUMN events.event_id IS '이벤트 ID (Primary Key)';
|
||||||
|
COMMENT ON COLUMN events.user_id IS '사용자 ID';
|
||||||
|
COMMENT ON COLUMN events.store_id IS '상점 ID';
|
||||||
|
COMMENT ON COLUMN events.event_name IS '이벤트명';
|
||||||
|
COMMENT ON COLUMN events.description IS '이벤트 설명';
|
||||||
|
COMMENT ON COLUMN events.objective IS '이벤트 목적';
|
||||||
|
COMMENT ON COLUMN events.start_date IS '이벤트 시작일';
|
||||||
|
COMMENT ON COLUMN events.end_date IS '이벤트 종료일';
|
||||||
|
COMMENT ON COLUMN events.status IS '이벤트 상태 (DRAFT, PUBLISHED, ENDED)';
|
||||||
|
COMMENT ON COLUMN events.selected_image_id IS '선택된 이미지 ID';
|
||||||
|
COMMENT ON COLUMN events.selected_image_url IS '선택된 이미지 URL';
|
||||||
|
COMMENT ON COLUMN events.participants IS '참여자 수';
|
||||||
|
COMMENT ON COLUMN events.target_participants IS '목표 참여자 수';
|
||||||
|
COMMENT ON COLUMN events.roi IS 'ROI (투자 대비 수익률)';
|
||||||
|
COMMENT ON COLUMN events.created_at IS '생성일시';
|
||||||
|
COMMENT ON COLUMN events.updated_at IS '수정일시';
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 2. event_channels 테이블 - 이벤트 배포 채널 (ElementCollection)
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS event_channels (
|
||||||
|
event_id VARCHAR(50) NOT NULL,
|
||||||
|
channel VARCHAR(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- event_channels 테이블 인덱스
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_event_channels_event_id ON event_channels(event_id);
|
||||||
|
|
||||||
|
COMMENT ON TABLE event_channels IS '이벤트 배포 채널 테이블';
|
||||||
|
COMMENT ON COLUMN event_channels.event_id IS '이벤트 ID';
|
||||||
|
COMMENT ON COLUMN event_channels.channel IS '배포 채널명';
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 3. generated_images 테이블 - 생성된 이미지
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS generated_images (
|
||||||
|
image_id VARCHAR(50) PRIMARY KEY,
|
||||||
|
event_id VARCHAR(50) NOT NULL,
|
||||||
|
image_url VARCHAR(500) NOT NULL,
|
||||||
|
style VARCHAR(50),
|
||||||
|
platform VARCHAR(50),
|
||||||
|
is_selected BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- generated_images 테이블 인덱스
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_generated_images_event_id ON generated_images(event_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_generated_images_is_selected ON generated_images(is_selected);
|
||||||
|
|
||||||
|
COMMENT ON TABLE generated_images IS 'AI가 생성한 이미지 테이블';
|
||||||
|
COMMENT ON COLUMN generated_images.image_id IS '이미지 ID (Primary Key)';
|
||||||
|
COMMENT ON COLUMN generated_images.event_id IS '이벤트 ID';
|
||||||
|
COMMENT ON COLUMN generated_images.image_url IS '이미지 URL';
|
||||||
|
COMMENT ON COLUMN generated_images.style IS '이미지 스타일';
|
||||||
|
COMMENT ON COLUMN generated_images.platform IS '타겟 플랫폼';
|
||||||
|
COMMENT ON COLUMN generated_images.is_selected IS '선택 여부';
|
||||||
|
COMMENT ON COLUMN generated_images.created_at IS '생성일시';
|
||||||
|
COMMENT ON COLUMN generated_images.updated_at IS '수정일시';
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 4. ai_recommendations 테이블 - AI 추천 기획안
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS ai_recommendations (
|
||||||
|
recommendation_id VARCHAR(50) PRIMARY KEY,
|
||||||
|
event_id VARCHAR(50) NOT NULL,
|
||||||
|
event_name VARCHAR(200) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
promotion_type VARCHAR(50),
|
||||||
|
target_audience VARCHAR(100),
|
||||||
|
is_selected BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ai_recommendations 테이블 인덱스
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_recommendations_event_id ON ai_recommendations(event_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ai_recommendations_is_selected ON ai_recommendations(is_selected);
|
||||||
|
|
||||||
|
COMMENT ON TABLE ai_recommendations IS 'AI 추천 이벤트 기획안 테이블';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.recommendation_id IS '추천 ID (Primary Key)';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.event_id IS '이벤트 ID';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.event_name IS '추천 이벤트명';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.description IS '추천 설명';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.promotion_type IS '프로모션 유형';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.target_audience IS '타겟 고객층';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.is_selected IS '선택 여부';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.created_at IS '생성일시';
|
||||||
|
COMMENT ON COLUMN ai_recommendations.updated_at IS '수정일시';
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 5. jobs 테이블 - 비동기 작업 관리
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS jobs (
|
||||||
|
job_id VARCHAR(50) PRIMARY KEY,
|
||||||
|
event_id VARCHAR(50) NOT NULL,
|
||||||
|
job_type VARCHAR(30) NOT NULL,
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
|
||||||
|
progress INTEGER NOT NULL DEFAULT 0,
|
||||||
|
result_key VARCHAR(200),
|
||||||
|
error_message VARCHAR(500),
|
||||||
|
completed_at TIMESTAMP,
|
||||||
|
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
max_retry_count INTEGER NOT NULL DEFAULT 3,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- jobs 테이블 인덱스
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_jobs_event_id ON jobs(event_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_jobs_job_type ON jobs(job_type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_jobs_created_at ON jobs(created_at);
|
||||||
|
|
||||||
|
COMMENT ON TABLE jobs IS '비동기 작업 관리 테이블';
|
||||||
|
COMMENT ON COLUMN jobs.job_id IS '작업 ID (Primary Key)';
|
||||||
|
COMMENT ON COLUMN jobs.event_id IS '이벤트 ID';
|
||||||
|
COMMENT ON COLUMN jobs.job_type IS '작업 유형 (AI_RECOMMENDATION, IMAGE_GENERATION)';
|
||||||
|
COMMENT ON COLUMN jobs.status IS '작업 상태 (PENDING, PROCESSING, COMPLETED, FAILED)';
|
||||||
|
COMMENT ON COLUMN jobs.progress IS '진행률 (0-100)';
|
||||||
|
COMMENT ON COLUMN jobs.result_key IS '결과 키';
|
||||||
|
COMMENT ON COLUMN jobs.error_message IS '에러 메시지';
|
||||||
|
COMMENT ON COLUMN jobs.completed_at IS '완료일시';
|
||||||
|
COMMENT ON COLUMN jobs.retry_count IS '재시도 횟수';
|
||||||
|
COMMENT ON COLUMN jobs.max_retry_count IS '최대 재시도 횟수';
|
||||||
|
COMMENT ON COLUMN jobs.created_at IS '생성일시';
|
||||||
|
COMMENT ON COLUMN jobs.updated_at IS '수정일시';
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 6. updated_at 자동 업데이트를 위한 트리거 함수 생성
|
||||||
|
-- ====================================================================================================
|
||||||
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 7. 각 테이블에 updated_at 자동 업데이트 트리거 적용
|
||||||
|
-- ====================================================================================================
|
||||||
|
|
||||||
|
-- events 테이블 트리거
|
||||||
|
DROP TRIGGER IF EXISTS update_events_updated_at ON events;
|
||||||
|
CREATE TRIGGER update_events_updated_at
|
||||||
|
BEFORE UPDATE ON events
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION update_updated_at_column();
|
||||||
|
|
||||||
|
-- generated_images 테이블 트리거
|
||||||
|
DROP TRIGGER IF EXISTS update_generated_images_updated_at ON generated_images;
|
||||||
|
CREATE TRIGGER update_generated_images_updated_at
|
||||||
|
BEFORE UPDATE ON generated_images
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION update_updated_at_column();
|
||||||
|
|
||||||
|
-- ai_recommendations 테이블 트리거
|
||||||
|
DROP TRIGGER IF EXISTS update_ai_recommendations_updated_at ON ai_recommendations;
|
||||||
|
CREATE TRIGGER update_ai_recommendations_updated_at
|
||||||
|
BEFORE UPDATE ON ai_recommendations
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION update_updated_at_column();
|
||||||
|
|
||||||
|
-- jobs 테이블 트리거
|
||||||
|
DROP TRIGGER IF EXISTS update_jobs_updated_at ON jobs;
|
||||||
|
CREATE TRIGGER update_jobs_updated_at
|
||||||
|
BEFORE UPDATE ON jobs
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION update_updated_at_column();
|
||||||
|
|
||||||
|
|
||||||
|
-- ====================================================================================================
|
||||||
|
-- 완료 메시지
|
||||||
|
-- ====================================================================================================
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE '=================================================';
|
||||||
|
RAISE NOTICE 'Event Service 테이블 생성이 완료되었습니다.';
|
||||||
|
RAISE NOTICE '=================================================';
|
||||||
|
RAISE NOTICE '생성된 테이블:';
|
||||||
|
RAISE NOTICE ' 1. events - 이벤트 메인 테이블';
|
||||||
|
RAISE NOTICE ' 2. event_channels - 이벤트 배포 채널';
|
||||||
|
RAISE NOTICE ' 3. generated_images - 생성된 이미지';
|
||||||
|
RAISE NOTICE ' 4. ai_recommendations - AI 추천 기획안';
|
||||||
|
RAISE NOTICE ' 5. jobs - 비동기 작업 관리';
|
||||||
|
RAISE NOTICE '=================================================';
|
||||||
|
RAISE NOTICE '참고: FK 제약조건은 생성되지 않았습니다.';
|
||||||
|
RAISE NOTICE '=================================================';
|
||||||
|
END $$;
|
||||||
@ -7,7 +7,6 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 생성 완료 메시지 DTO
|
* 이벤트 생성 완료 메시지 DTO
|
||||||
@ -21,16 +20,16 @@ import java.util.UUID;
|
|||||||
public class EventCreatedMessage {
|
public class EventCreatedMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 ID (UUID)
|
* 이벤트 ID
|
||||||
*/
|
*/
|
||||||
@JsonProperty("event_id")
|
@JsonProperty("event_id")
|
||||||
private UUID eventId;
|
private String eventId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자 ID (UUID)
|
* 사용자 ID
|
||||||
*/
|
*/
|
||||||
@JsonProperty("user_id")
|
@JsonProperty("user_id")
|
||||||
private UUID userId;
|
private String userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 제목
|
* 이벤트 제목
|
||||||
|
|||||||
@ -8,8 +8,6 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 추천 요청 DTO
|
* AI 추천 요청 DTO
|
||||||
*
|
*
|
||||||
@ -42,8 +40,8 @@ public class AiRecommendationRequest {
|
|||||||
public static class StoreInfo {
|
public static class StoreInfo {
|
||||||
|
|
||||||
@NotNull(message = "매장 ID는 필수입니다.")
|
@NotNull(message = "매장 ID는 필수입니다.")
|
||||||
@Schema(description = "매장 ID", required = true, example = "550e8400-e29b-41d4-a716-446655440002")
|
@Schema(description = "매장 ID", required = true, example = "str_20250124_001")
|
||||||
private UUID storeId;
|
private String storeId;
|
||||||
|
|
||||||
@NotNull(message = "매장명은 필수입니다.")
|
@NotNull(message = "매장명은 필수입니다.")
|
||||||
@Schema(description = "매장명", required = true, example = "우진네 고깃집")
|
@Schema(description = "매장명", required = true, example = "우진네 고깃집")
|
||||||
|
|||||||
@ -6,8 +6,6 @@ import lombok.Builder;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이미지 선택 요청 DTO
|
* 이미지 선택 요청 DTO
|
||||||
*
|
*
|
||||||
@ -22,7 +20,7 @@ import java.util.UUID;
|
|||||||
public class SelectImageRequest {
|
public class SelectImageRequest {
|
||||||
|
|
||||||
@NotNull(message = "이미지 ID는 필수입니다.")
|
@NotNull(message = "이미지 ID는 필수입니다.")
|
||||||
private UUID imageId;
|
private String imageId;
|
||||||
|
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 추천 선택 요청 DTO
|
* AI 추천 선택 요청 DTO
|
||||||
@ -28,8 +27,8 @@ import java.util.UUID;
|
|||||||
public class SelectRecommendationRequest {
|
public class SelectRecommendationRequest {
|
||||||
|
|
||||||
@NotNull(message = "추천 ID는 필수입니다.")
|
@NotNull(message = "추천 ID는 필수입니다.")
|
||||||
@Schema(description = "선택한 추천 ID", required = true, example = "550e8400-e29b-41d4-a716-446655440007")
|
@Schema(description = "선택한 추천 ID", required = true, example = "rec_20250124_001")
|
||||||
private UUID recommendationId;
|
private String recommendationId;
|
||||||
|
|
||||||
@Valid
|
@Valid
|
||||||
@Schema(description = "커스터마이징 항목")
|
@Schema(description = "커스터마이징 항목")
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 생성 응답 DTO
|
* 이벤트 생성 응답 DTO
|
||||||
@ -22,7 +21,7 @@ import java.util.UUID;
|
|||||||
@Builder
|
@Builder
|
||||||
public class EventCreatedResponse {
|
public class EventCreatedResponse {
|
||||||
|
|
||||||
private UUID eventId;
|
private String eventId;
|
||||||
private EventStatus status;
|
private EventStatus status;
|
||||||
private String objective;
|
private String objective;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 상세 응답 DTO
|
* 이벤트 상세 응답 DTO
|
||||||
@ -25,16 +24,16 @@ import java.util.UUID;
|
|||||||
@Builder
|
@Builder
|
||||||
public class EventDetailResponse {
|
public class EventDetailResponse {
|
||||||
|
|
||||||
private UUID eventId;
|
private String eventId;
|
||||||
private UUID userId;
|
private String userId;
|
||||||
private UUID storeId;
|
private String storeId;
|
||||||
private String eventName;
|
private String eventName;
|
||||||
private String description;
|
private String description;
|
||||||
private String objective;
|
private String objective;
|
||||||
private LocalDate startDate;
|
private LocalDate startDate;
|
||||||
private LocalDate endDate;
|
private LocalDate endDate;
|
||||||
private EventStatus status;
|
private EventStatus status;
|
||||||
private UUID selectedImageId;
|
private String selectedImageId;
|
||||||
private String selectedImageUrl;
|
private String selectedImageUrl;
|
||||||
private Integer participants;
|
private Integer participants;
|
||||||
private Integer targetParticipants;
|
private Integer targetParticipants;
|
||||||
@ -57,7 +56,7 @@ public class EventDetailResponse {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public static class GeneratedImageDto {
|
public static class GeneratedImageDto {
|
||||||
private UUID imageId;
|
private String imageId;
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private String style;
|
private String style;
|
||||||
private String platform;
|
private String platform;
|
||||||
@ -70,7 +69,7 @@ public class EventDetailResponse {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public static class AiRecommendationDto {
|
public static class AiRecommendationDto {
|
||||||
private UUID recommendationId;
|
private String recommendationId;
|
||||||
private String eventName;
|
private String eventName;
|
||||||
private String description;
|
private String description;
|
||||||
private String promotionType;
|
private String promotionType;
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이미지 편집 응답 DTO
|
* 이미지 편집 응답 DTO
|
||||||
@ -25,8 +24,8 @@ import java.util.UUID;
|
|||||||
@Schema(description = "이미지 편집 응답")
|
@Schema(description = "이미지 편집 응답")
|
||||||
public class ImageEditResponse {
|
public class ImageEditResponse {
|
||||||
|
|
||||||
@Schema(description = "편집된 이미지 ID", example = "550e8400-e29b-41d4-a716-446655440008")
|
@Schema(description = "편집된 이미지 ID", example = "img_20250124_001")
|
||||||
private UUID imageId;
|
private String imageId;
|
||||||
|
|
||||||
@Schema(description = "편집된 이미지 URL", example = "https://cdn.kt-event.com/images/event-img-001-edited.jpg")
|
@Schema(description = "편집된 이미지 URL", example = "https://cdn.kt-event.com/images/event-img-001-edited.jpg")
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이미지 생성 응답 DTO
|
* 이미지 생성 응답 DTO
|
||||||
@ -21,7 +20,7 @@ import java.util.UUID;
|
|||||||
@Builder
|
@Builder
|
||||||
public class ImageGenerationResponse {
|
public class ImageGenerationResponse {
|
||||||
|
|
||||||
private UUID jobId;
|
private String jobId;
|
||||||
private String status;
|
private String status;
|
||||||
private String message;
|
private String message;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
|
|||||||
@ -7,8 +7,6 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job 접수 응답 DTO
|
* Job 접수 응답 DTO
|
||||||
*
|
*
|
||||||
@ -25,8 +23,8 @@ import java.util.UUID;
|
|||||||
@Schema(description = "Job 접수 응답")
|
@Schema(description = "Job 접수 응답")
|
||||||
public class JobAcceptedResponse {
|
public class JobAcceptedResponse {
|
||||||
|
|
||||||
@Schema(description = "생성된 Job ID", example = "550e8400-e29b-41d4-a716-446655440005")
|
@Schema(description = "생성된 Job ID", example = "job_20250124_001")
|
||||||
private UUID jobId;
|
private String jobId;
|
||||||
|
|
||||||
@Schema(description = "Job 상태 (초기 상태는 PENDING)", example = "PENDING")
|
@Schema(description = "Job 상태 (초기 상태는 PENDING)", example = "PENDING")
|
||||||
private JobStatus status;
|
private JobStatus status;
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job 상태 응답 DTO
|
* Job 상태 응답 DTO
|
||||||
@ -23,7 +22,7 @@ import java.util.UUID;
|
|||||||
@Builder
|
@Builder
|
||||||
public class JobStatusResponse {
|
public class JobStatusResponse {
|
||||||
|
|
||||||
private UUID jobId;
|
private String jobId;
|
||||||
private JobType jobType;
|
private JobType jobType;
|
||||||
private JobStatus status;
|
private JobStatus status;
|
||||||
private int progress;
|
private int progress;
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,13 +51,13 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 생성 (Step 1: 목적 선택)
|
* 이벤트 생성 (Step 1: 목적 선택)
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param storeId 매장 ID (UUID)
|
* @param storeId 매장 ID
|
||||||
* @param request 목적 선택 요청
|
* @param request 목적 선택 요청
|
||||||
* @return 생성된 이벤트 응답
|
* @return 생성된 이벤트 응답
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public EventCreatedResponse createEvent(UUID userId, UUID storeId, SelectObjectiveRequest request) {
|
public EventCreatedResponse createEvent(String userId, String storeId, SelectObjectiveRequest request) {
|
||||||
log.info("이벤트 생성 시작 - userId: {}, storeId: {}, objective: {}",
|
log.info("이벤트 생성 시작 - userId: {}, storeId: {}, objective: {}",
|
||||||
userId, storeId, request.getObjective());
|
userId, storeId, request.getObjective());
|
||||||
|
|
||||||
@ -87,11 +86,11 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 상세 조회
|
* 이벤트 상세 조회
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @return 이벤트 상세 응답
|
* @return 이벤트 상세 응답
|
||||||
*/
|
*/
|
||||||
public EventDetailResponse getEvent(UUID userId, UUID eventId) {
|
public EventDetailResponse getEvent(String userId, String eventId) {
|
||||||
log.info("이벤트 조회 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이벤트 조회 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
||||||
@ -108,7 +107,7 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 목록 조회 (페이징, 필터링)
|
* 이벤트 목록 조회 (페이징, 필터링)
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param status 상태 필터
|
* @param status 상태 필터
|
||||||
* @param search 검색어
|
* @param search 검색어
|
||||||
* @param objective 목적 필터
|
* @param objective 목적 필터
|
||||||
@ -116,7 +115,7 @@ public class EventService {
|
|||||||
* @return 이벤트 목록
|
* @return 이벤트 목록
|
||||||
*/
|
*/
|
||||||
public Page<EventDetailResponse> getEvents(
|
public Page<EventDetailResponse> getEvents(
|
||||||
UUID userId,
|
String userId,
|
||||||
EventStatus status,
|
EventStatus status,
|
||||||
String search,
|
String search,
|
||||||
String objective,
|
String objective,
|
||||||
@ -139,11 +138,11 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 삭제
|
* 이벤트 삭제
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void deleteEvent(UUID userId, UUID eventId) {
|
public void deleteEvent(String userId, String eventId) {
|
||||||
log.info("이벤트 삭제 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이벤트 삭제 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
||||||
@ -161,11 +160,11 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 배포
|
* 이벤트 배포
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void publishEvent(UUID userId, UUID eventId) {
|
public void publishEvent(String userId, String eventId) {
|
||||||
log.info("이벤트 배포 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이벤트 배포 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
||||||
@ -190,11 +189,11 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 종료
|
* 이벤트 종료
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void endEvent(UUID userId, UUID eventId) {
|
public void endEvent(String userId, String eventId) {
|
||||||
log.info("이벤트 종료 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이벤트 종료 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
Event event = eventRepository.findByEventIdAndUserId(eventId, userId)
|
||||||
@ -210,13 +209,13 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이미지 생성 요청
|
* 이미지 생성 요청
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param request 이미지 생성 요청
|
* @param request 이미지 생성 요청
|
||||||
* @return 이미지 생성 응답 (Job ID 포함)
|
* @return 이미지 생성 응답 (Job ID 포함)
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public ImageGenerationResponse requestImageGeneration(UUID userId, UUID eventId, ImageGenerationRequest request) {
|
public ImageGenerationResponse requestImageGeneration(String userId, String eventId, ImageGenerationRequest request) {
|
||||||
log.info("이미지 생성 요청 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이미지 생성 요청 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
// 이벤트 조회 및 권한 확인
|
// 이벤트 조회 및 권한 확인
|
||||||
@ -245,9 +244,9 @@ public class EventService {
|
|||||||
|
|
||||||
// Kafka 메시지 발행
|
// Kafka 메시지 발행
|
||||||
imageJobKafkaProducer.publishImageGenerationJob(
|
imageJobKafkaProducer.publishImageGenerationJob(
|
||||||
job.getJobId().toString(),
|
job.getJobId(),
|
||||||
userId.toString(),
|
userId,
|
||||||
eventId.toString(),
|
eventId,
|
||||||
prompt
|
prompt
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -265,13 +264,13 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이미지 선택
|
* 이미지 선택
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param imageId 이미지 ID
|
* @param imageId 이미지 ID
|
||||||
* @param request 이미지 선택 요청
|
* @param request 이미지 선택 요청
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void selectImage(UUID userId, UUID eventId, UUID imageId, SelectImageRequest request) {
|
public void selectImage(String userId, String eventId, String imageId, SelectImageRequest request) {
|
||||||
log.info("이미지 선택 - userId: {}, eventId: {}, imageId: {}", userId, eventId, imageId);
|
log.info("이미지 선택 - userId: {}, eventId: {}, imageId: {}", userId, eventId, imageId);
|
||||||
|
|
||||||
// 이벤트 조회 및 권한 확인
|
// 이벤트 조회 및 권한 확인
|
||||||
@ -294,13 +293,13 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* AI 추천 요청
|
* AI 추천 요청
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param request AI 추천 요청
|
* @param request AI 추천 요청
|
||||||
* @return Job 접수 응답
|
* @return Job 접수 응답
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public JobAcceptedResponse requestAiRecommendations(UUID userId, UUID eventId, AiRecommendationRequest request) {
|
public JobAcceptedResponse requestAiRecommendations(String userId, String eventId, AiRecommendationRequest request) {
|
||||||
log.info("AI 추천 요청 - userId: {}, eventId: {}", userId, eventId);
|
log.info("AI 추천 요청 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
// 이벤트 조회 및 권한 확인
|
// 이벤트 조회 및 권한 확인
|
||||||
@ -322,9 +321,9 @@ public class EventService {
|
|||||||
|
|
||||||
// Kafka 메시지 발행
|
// Kafka 메시지 발행
|
||||||
aiJobKafkaProducer.publishAIGenerationJob(
|
aiJobKafkaProducer.publishAIGenerationJob(
|
||||||
job.getJobId().toString(),
|
job.getJobId(),
|
||||||
userId.toString(),
|
userId,
|
||||||
eventId.toString(),
|
eventId,
|
||||||
request.getStoreInfo().getStoreName(),
|
request.getStoreInfo().getStoreName(),
|
||||||
request.getStoreInfo().getCategory(),
|
request.getStoreInfo().getCategory(),
|
||||||
request.getStoreInfo().getDescription(),
|
request.getStoreInfo().getDescription(),
|
||||||
@ -343,12 +342,12 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* AI 추천 선택
|
* AI 추천 선택
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param request AI 추천 선택 요청
|
* @param request AI 추천 선택 요청
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void selectRecommendation(UUID userId, UUID eventId, SelectRecommendationRequest request) {
|
public void selectRecommendation(String userId, String eventId, SelectRecommendationRequest request) {
|
||||||
log.info("AI 추천 선택 - userId: {}, eventId: {}, recommendationId: {}",
|
log.info("AI 추천 선택 - userId: {}, eventId: {}, recommendationId: {}",
|
||||||
userId, eventId, request.getRecommendationId());
|
userId, eventId, request.getRecommendationId());
|
||||||
|
|
||||||
@ -409,14 +408,14 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이미지 편집
|
* 이미지 편집
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param imageId 이미지 ID
|
* @param imageId 이미지 ID
|
||||||
* @param request 이미지 편집 요청
|
* @param request 이미지 편집 요청
|
||||||
* @return 이미지 편집 응답
|
* @return 이미지 편집 응답
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public ImageEditResponse editImage(UUID userId, UUID eventId, UUID imageId, ImageEditRequest request) {
|
public ImageEditResponse editImage(String userId, String eventId, String imageId, ImageEditRequest request) {
|
||||||
log.info("이미지 편집 - userId: {}, eventId: {}, imageId: {}", userId, eventId, imageId);
|
log.info("이미지 편집 - userId: {}, eventId: {}, imageId: {}", userId, eventId, imageId);
|
||||||
|
|
||||||
// 이벤트 조회 및 권한 확인
|
// 이벤트 조회 및 권한 확인
|
||||||
@ -450,12 +449,12 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 배포 채널 선택
|
* 배포 채널 선택
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param request 배포 채널 선택 요청
|
* @param request 배포 채널 선택 요청
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void selectChannels(UUID userId, UUID eventId, SelectChannelsRequest request) {
|
public void selectChannels(String userId, String eventId, SelectChannelsRequest request) {
|
||||||
log.info("배포 채널 선택 - userId: {}, eventId: {}, channels: {}",
|
log.info("배포 채널 선택 - userId: {}, eventId: {}, channels: {}",
|
||||||
userId, eventId, request.getChannels());
|
userId, eventId, request.getChannels());
|
||||||
|
|
||||||
@ -479,13 +478,13 @@ public class EventService {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 수정
|
* 이벤트 수정
|
||||||
*
|
*
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID
|
||||||
* @param request 이벤트 수정 요청
|
* @param request 이벤트 수정 요청
|
||||||
* @return 이벤트 상세 응답
|
* @return 이벤트 상세 응답
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public EventDetailResponse updateEvent(UUID userId, UUID eventId, UpdateEventRequest request) {
|
public EventDetailResponse updateEvent(String userId, String eventId, UpdateEventRequest request) {
|
||||||
log.info("이벤트 수정 - userId: {}, eventId: {}", userId, eventId);
|
log.info("이벤트 수정 - userId: {}, eventId: {}", userId, eventId);
|
||||||
|
|
||||||
// 이벤트 조회 및 권한 확인
|
// 이벤트 조회 및 권한 확인
|
||||||
|
|||||||
@ -11,8 +11,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job 서비스
|
* Job 서비스
|
||||||
*
|
*
|
||||||
@ -38,7 +36,7 @@ public class JobService {
|
|||||||
* @return 생성된 Job
|
* @return 생성된 Job
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public Job createJob(UUID eventId, JobType jobType) {
|
public Job createJob(String eventId, JobType jobType) {
|
||||||
log.info("Job 생성 - eventId: {}, jobType: {}", eventId, jobType);
|
log.info("Job 생성 - eventId: {}, jobType: {}", eventId, jobType);
|
||||||
|
|
||||||
Job job = Job.builder()
|
Job job = Job.builder()
|
||||||
@ -59,7 +57,7 @@ public class JobService {
|
|||||||
* @param jobId Job ID
|
* @param jobId Job ID
|
||||||
* @return Job 상태 응답
|
* @return Job 상태 응답
|
||||||
*/
|
*/
|
||||||
public JobStatusResponse getJobStatus(UUID jobId) {
|
public JobStatusResponse getJobStatus(String jobId) {
|
||||||
log.info("Job 상태 조회 - jobId: {}", jobId);
|
log.info("Job 상태 조회 - jobId: {}", jobId);
|
||||||
|
|
||||||
Job job = jobRepository.findById(jobId)
|
Job job = jobRepository.findById(jobId)
|
||||||
@ -75,7 +73,7 @@ public class JobService {
|
|||||||
* @param progress 진행률
|
* @param progress 진행률
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updateJobProgress(UUID jobId, int progress) {
|
public void updateJobProgress(String jobId, int progress) {
|
||||||
log.info("Job 진행률 업데이트 - jobId: {}, progress: {}", jobId, progress);
|
log.info("Job 진행률 업데이트 - jobId: {}, progress: {}", jobId, progress);
|
||||||
|
|
||||||
Job job = jobRepository.findById(jobId)
|
Job job = jobRepository.findById(jobId)
|
||||||
@ -93,7 +91,7 @@ public class JobService {
|
|||||||
* @param resultKey Redis 결과 키
|
* @param resultKey Redis 결과 키
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void completeJob(UUID jobId, String resultKey) {
|
public void completeJob(String jobId, String resultKey) {
|
||||||
log.info("Job 완료 - jobId: {}, resultKey: {}", jobId, resultKey);
|
log.info("Job 완료 - jobId: {}, resultKey: {}", jobId, resultKey);
|
||||||
|
|
||||||
Job job = jobRepository.findById(jobId)
|
Job job = jobRepository.findById(jobId)
|
||||||
@ -113,7 +111,7 @@ public class JobService {
|
|||||||
* @param errorMessage 에러 메시지
|
* @param errorMessage 에러 메시지
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void failJob(UUID jobId, String errorMessage) {
|
public void failJob(String jobId, String errorMessage) {
|
||||||
log.info("Job 실패 - jobId: {}, errorMessage: {}", jobId, errorMessage);
|
log.info("Job 실패 - jobId: {}, errorMessage: {}", jobId, errorMessage);
|
||||||
|
|
||||||
Job job = jobRepository.findById(jobId)
|
Job job = jobRepository.findById(jobId)
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
package com.kt.event.eventservice.application.service;
|
package com.kt.event.eventservice.application.service;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 알림 서비스 인터페이스
|
* 알림 서비스 인터페이스
|
||||||
*
|
*
|
||||||
@ -22,7 +20,7 @@ public interface NotificationService {
|
|||||||
* @param jobType 작업 타입
|
* @param jobType 작업 타입
|
||||||
* @param message 알림 메시지
|
* @param message 알림 메시지
|
||||||
*/
|
*/
|
||||||
void notifyJobCompleted(UUID userId, UUID jobId, String jobType, String message);
|
void notifyJobCompleted(String userId, String jobId, String jobType, String message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 작업 실패 알림 전송
|
* 작업 실패 알림 전송
|
||||||
@ -32,7 +30,7 @@ public interface NotificationService {
|
|||||||
* @param jobType 작업 타입
|
* @param jobType 작업 타입
|
||||||
* @param errorMessage 에러 메시지
|
* @param errorMessage 에러 메시지
|
||||||
*/
|
*/
|
||||||
void notifyJobFailed(UUID userId, UUID jobId, String jobType, String errorMessage);
|
void notifyJobFailed(String userId, String jobId, String jobType, String errorMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 작업 진행 상태 알림 전송
|
* 작업 진행 상태 알림 전송
|
||||||
@ -42,5 +40,5 @@ public interface NotificationService {
|
|||||||
* @param jobType 작업 타입
|
* @param jobType 작업 타입
|
||||||
* @param progress 진행률 (0-100)
|
* @param progress 진행률 (0-100)
|
||||||
*/
|
*/
|
||||||
void notifyJobProgress(UUID userId, UUID jobId, String jobType, int progress);
|
void notifyJobProgress(String userId, String jobId, String jobType, int progress);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 개발 환경용 인증 필터
|
* 개발 환경용 인증 필터
|
||||||
@ -35,11 +34,11 @@ public class DevAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
|
|
||||||
// 개발용 기본 UserPrincipal 생성
|
// 개발용 기본 UserPrincipal 생성
|
||||||
UserPrincipal userPrincipal = new UserPrincipal(
|
UserPrincipal userPrincipal = new UserPrincipal(
|
||||||
UUID.fromString("11111111-1111-1111-1111-111111111111"), // userId
|
"usr_dev_test_001", // userId
|
||||||
UUID.fromString("22222222-2222-2222-2222-222222222222"), // storeId
|
"str_dev_test_001", // storeId
|
||||||
"dev@test.com", // email
|
"dev@test.com", // email
|
||||||
"개발테스트사용자", // name
|
"개발테스트사용자", // name
|
||||||
Collections.singletonList("USER") // roles
|
Collections.singletonList("USER") // roles
|
||||||
);
|
);
|
||||||
|
|
||||||
// Authentication 객체 생성 및 SecurityContext에 설정
|
// Authentication 객체 생성 및 SecurityContext에 설정
|
||||||
|
|||||||
@ -3,9 +3,6 @@ package com.kt.event.eventservice.domain.entity;
|
|||||||
import com.kt.event.common.entity.BaseTimeEntity;
|
import com.kt.event.common.entity.BaseTimeEntity;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 추천 엔티티
|
* AI 추천 엔티티
|
||||||
@ -26,10 +23,8 @@ import java.util.UUID;
|
|||||||
public class AiRecommendation extends BaseTimeEntity {
|
public class AiRecommendation extends BaseTimeEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "uuid2")
|
@Column(name = "recommendation_id", length = 50)
|
||||||
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
private String recommendationId;
|
||||||
@Column(name = "recommendation_id", columnDefinition = "uuid")
|
|
||||||
private UUID recommendationId;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "event_id", nullable = false)
|
@JoinColumn(name = "event_id", nullable = false)
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import jakarta.persistence.*;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.annotations.Fetch;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -32,16 +31,14 @@ import java.util.*;
|
|||||||
public class Event extends BaseTimeEntity {
|
public class Event extends BaseTimeEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "uuid2")
|
@Column(name = "event_id", length = 50)
|
||||||
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
private String eventId;
|
||||||
@Column(name = "event_id", columnDefinition = "uuid")
|
|
||||||
private UUID eventId;
|
|
||||||
|
|
||||||
@Column(name = "user_id", nullable = false, columnDefinition = "uuid")
|
@Column(name = "user_id", nullable = false, length = 50)
|
||||||
private UUID userId;
|
private String userId;
|
||||||
|
|
||||||
@Column(name = "store_id", nullable = false, columnDefinition = "uuid")
|
@Column(name = "store_id", nullable = false, length = 50)
|
||||||
private UUID storeId;
|
private String storeId;
|
||||||
|
|
||||||
@Column(name = "event_name", length = 200)
|
@Column(name = "event_name", length = 200)
|
||||||
private String eventName;
|
private String eventName;
|
||||||
@ -63,8 +60,8 @@ public class Event extends BaseTimeEntity {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private EventStatus status = EventStatus.DRAFT;
|
private EventStatus status = EventStatus.DRAFT;
|
||||||
|
|
||||||
@Column(name = "selected_image_id", columnDefinition = "uuid")
|
@Column(name = "selected_image_id", length = 50)
|
||||||
private UUID selectedImageId;
|
private String selectedImageId;
|
||||||
|
|
||||||
@Column(name = "selected_image_url", length = 500)
|
@Column(name = "selected_image_url", length = 500)
|
||||||
private String selectedImageUrl;
|
private String selectedImageUrl;
|
||||||
@ -128,7 +125,7 @@ public class Event extends BaseTimeEntity {
|
|||||||
/**
|
/**
|
||||||
* 이미지 선택
|
* 이미지 선택
|
||||||
*/
|
*/
|
||||||
public void selectImage(UUID imageId, String imageUrl) {
|
public void selectImage(String imageId, String imageUrl) {
|
||||||
this.selectedImageId = imageId;
|
this.selectedImageId = imageId;
|
||||||
this.selectedImageUrl = imageUrl;
|
this.selectedImageUrl = imageUrl;
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,6 @@ package com.kt.event.eventservice.domain.entity;
|
|||||||
import com.kt.event.common.entity.BaseTimeEntity;
|
import com.kt.event.common.entity.BaseTimeEntity;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 생성된 이미지 엔티티
|
* 생성된 이미지 엔티티
|
||||||
@ -26,10 +23,8 @@ import java.util.UUID;
|
|||||||
public class GeneratedImage extends BaseTimeEntity {
|
public class GeneratedImage extends BaseTimeEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "uuid2")
|
@Column(name = "image_id", length = 50)
|
||||||
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
private String imageId;
|
||||||
@Column(name = "image_id", columnDefinition = "uuid")
|
|
||||||
private UUID imageId;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "event_id", nullable = false)
|
@JoinColumn(name = "event_id", nullable = false)
|
||||||
|
|||||||
@ -5,10 +5,8 @@ import com.kt.event.eventservice.domain.enums.JobStatus;
|
|||||||
import com.kt.event.eventservice.domain.enums.JobType;
|
import com.kt.event.eventservice.domain.enums.JobType;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 비동기 작업 엔티티
|
* 비동기 작업 엔티티
|
||||||
@ -29,13 +27,11 @@ import java.util.UUID;
|
|||||||
public class Job extends BaseTimeEntity {
|
public class Job extends BaseTimeEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "uuid2")
|
@Column(name = "job_id", length = 50)
|
||||||
@GenericGenerator(name = "uuid2", strategy = "uuid2")
|
private String jobId;
|
||||||
@Column(name = "job_id", columnDefinition = "uuid")
|
|
||||||
private UUID jobId;
|
|
||||||
|
|
||||||
@Column(name = "event_id", nullable = false, columnDefinition = "uuid")
|
@Column(name = "event_id", nullable = false, length = 50)
|
||||||
private UUID eventId;
|
private String eventId;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "job_type", nullable = false, length = 30)
|
@Column(name = "job_type", nullable = false, length = 30)
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 추천 Repository
|
* AI 추천 Repository
|
||||||
@ -15,15 +14,15 @@ import java.util.UUID;
|
|||||||
* @since 2025-10-23
|
* @since 2025-10-23
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface AiRecommendationRepository extends JpaRepository<AiRecommendation, UUID> {
|
public interface AiRecommendationRepository extends JpaRepository<AiRecommendation, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트별 AI 추천 목록 조회
|
* 이벤트별 AI 추천 목록 조회
|
||||||
*/
|
*/
|
||||||
List<AiRecommendation> findByEventEventId(UUID eventId);
|
List<AiRecommendation> findByEventEventId(String eventId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트별 선택된 AI 추천 조회
|
* 이벤트별 선택된 AI 추천 조회
|
||||||
*/
|
*/
|
||||||
AiRecommendation findByEventEventIdAndIsSelectedTrue(UUID eventId);
|
AiRecommendation findByEventEventIdAndIsSelectedTrue(String eventId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import org.springframework.data.repository.query.Param;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 Repository
|
* 이벤트 Repository
|
||||||
@ -20,7 +19,7 @@ import java.util.UUID;
|
|||||||
* @since 2025-10-23
|
* @since 2025-10-23
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface EventRepository extends JpaRepository<Event, UUID> {
|
public interface EventRepository extends JpaRepository<Event, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자 ID와 이벤트 ID로 조회
|
* 사용자 ID와 이벤트 ID로 조회
|
||||||
@ -29,8 +28,8 @@ public interface EventRepository extends JpaRepository<Event, UUID> {
|
|||||||
"LEFT JOIN FETCH e.channels " +
|
"LEFT JOIN FETCH e.channels " +
|
||||||
"WHERE e.eventId = :eventId AND e.userId = :userId")
|
"WHERE e.eventId = :eventId AND e.userId = :userId")
|
||||||
Optional<Event> findByEventIdAndUserId(
|
Optional<Event> findByEventIdAndUserId(
|
||||||
@Param("eventId") UUID eventId,
|
@Param("eventId") String eventId,
|
||||||
@Param("userId") UUID userId
|
@Param("userId") String userId
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +41,7 @@ public interface EventRepository extends JpaRepository<Event, UUID> {
|
|||||||
"AND (:search IS NULL OR e.eventName LIKE %:search%) " +
|
"AND (:search IS NULL OR e.eventName LIKE %:search%) " +
|
||||||
"AND (:objective IS NULL OR e.objective = :objective)")
|
"AND (:objective IS NULL OR e.objective = :objective)")
|
||||||
Page<Event> findEventsByUser(
|
Page<Event> findEventsByUser(
|
||||||
@Param("userId") UUID userId,
|
@Param("userId") String userId,
|
||||||
@Param("status") EventStatus status,
|
@Param("status") EventStatus status,
|
||||||
@Param("search") String search,
|
@Param("search") String search,
|
||||||
@Param("objective") String objective,
|
@Param("objective") String objective,
|
||||||
@ -52,5 +51,5 @@ public interface EventRepository extends JpaRepository<Event, UUID> {
|
|||||||
/**
|
/**
|
||||||
* 사용자별 이벤트 개수 조회 (상태별)
|
* 사용자별 이벤트 개수 조회 (상태별)
|
||||||
*/
|
*/
|
||||||
long countByUserIdAndStatus(UUID userId, EventStatus status);
|
long countByUserIdAndStatus(String userId, EventStatus status);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 생성된 이미지 Repository
|
* 생성된 이미지 Repository
|
||||||
@ -15,15 +14,15 @@ import java.util.UUID;
|
|||||||
* @since 2025-10-23
|
* @since 2025-10-23
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface GeneratedImageRepository extends JpaRepository<GeneratedImage, UUID> {
|
public interface GeneratedImageRepository extends JpaRepository<GeneratedImage, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트별 생성된 이미지 목록 조회
|
* 이벤트별 생성된 이미지 목록 조회
|
||||||
*/
|
*/
|
||||||
List<GeneratedImage> findByEventEventId(UUID eventId);
|
List<GeneratedImage> findByEventEventId(String eventId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트별 선택된 이미지 조회
|
* 이벤트별 선택된 이미지 조회
|
||||||
*/
|
*/
|
||||||
GeneratedImage findByEventEventIdAndIsSelectedTrue(UUID eventId);
|
GeneratedImage findByEventEventIdAndIsSelectedTrue(String eventId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import org.springframework.stereotype.Repository;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 비동기 작업 Repository
|
* 비동기 작업 Repository
|
||||||
@ -18,22 +17,22 @@ import java.util.UUID;
|
|||||||
* @since 2025-10-23
|
* @since 2025-10-23
|
||||||
*/
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface JobRepository extends JpaRepository<Job, UUID> {
|
public interface JobRepository extends JpaRepository<Job, String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트별 작업 목록 조회
|
* 이벤트별 작업 목록 조회
|
||||||
*/
|
*/
|
||||||
List<Job> findByEventId(UUID eventId);
|
List<Job> findByEventId(String eventId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 및 작업 유형별 조회
|
* 이벤트 및 작업 유형별 조회
|
||||||
*/
|
*/
|
||||||
Optional<Job> findByEventIdAndJobType(UUID eventId, JobType jobType);
|
Optional<Job> findByEventIdAndJobType(String eventId, JobType jobType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 및 작업 유형별 최신 작업 조회
|
* 이벤트 및 작업 유형별 최신 작업 조회
|
||||||
*/
|
*/
|
||||||
Optional<Job> findFirstByEventIdAndJobTypeOrderByCreatedAtDesc(UUID eventId, JobType jobType);
|
Optional<Job> findFirstByEventIdAndJobTypeOrderByCreatedAtDesc(String eventId, JobType jobType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 상태별 작업 목록 조회
|
* 상태별 작업 목록 조회
|
||||||
|
|||||||
@ -18,8 +18,6 @@ import org.springframework.messaging.handler.annotation.Payload;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI 이벤트 생성 작업 메시지 구독 Consumer
|
* AI 이벤트 생성 작업 메시지 구독 Consumer
|
||||||
*
|
*
|
||||||
@ -93,7 +91,7 @@ public class AIJobKafkaConsumer {
|
|||||||
@Transactional
|
@Transactional
|
||||||
protected void processAIEventGenerationJob(AIEventGenerationJobMessage message) {
|
protected void processAIEventGenerationJob(AIEventGenerationJobMessage message) {
|
||||||
try {
|
try {
|
||||||
UUID jobId = UUID.fromString(message.getJobId());
|
String jobId = message.getJobId();
|
||||||
|
|
||||||
// Job 조회
|
// Job 조회
|
||||||
Job job = jobRepository.findById(jobId).orElse(null);
|
Job job = jobRepository.findById(jobId).orElse(null);
|
||||||
@ -102,7 +100,7 @@ public class AIJobKafkaConsumer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID eventId = job.getEventId();
|
String eventId = job.getEventId();
|
||||||
|
|
||||||
// Event 조회 (모든 케이스에서 사용)
|
// Event 조회 (모든 케이스에서 사용)
|
||||||
Event event = eventRepository.findById(eventId).orElse(null);
|
Event event = eventRepository.findById(eventId).orElse(null);
|
||||||
@ -142,7 +140,7 @@ public class AIJobKafkaConsumer {
|
|||||||
eventId, aiData.getEventTitle());
|
eventId, aiData.getEventTitle());
|
||||||
|
|
||||||
// 사용자에게 알림 전송
|
// 사용자에게 알림 전송
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobCompleted(
|
notificationService.notifyJobCompleted(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
@ -166,7 +164,7 @@ public class AIJobKafkaConsumer {
|
|||||||
|
|
||||||
// 사용자에게 실패 알림 전송
|
// 사용자에게 실패 알림 전송
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobFailed(
|
notificationService.notifyJobFailed(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
@ -185,7 +183,7 @@ public class AIJobKafkaConsumer {
|
|||||||
|
|
||||||
// 사용자에게 진행 상태 알림 전송
|
// 사용자에게 진행 상태 알림 전송
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobProgress(
|
notificationService.notifyJobProgress(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
|
|||||||
@ -29,12 +29,12 @@ public class EventKafkaProducer {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 생성 완료 메시지 발행
|
* 이벤트 생성 완료 메시지 발행
|
||||||
*
|
*
|
||||||
* @param eventId 이벤트 ID (UUID)
|
* @param eventId 이벤트 ID
|
||||||
* @param userId 사용자 ID (UUID)
|
* @param userId 사용자 ID
|
||||||
* @param title 이벤트 제목
|
* @param title 이벤트 제목
|
||||||
* @param eventType 이벤트 타입
|
* @param eventType 이벤트 타입
|
||||||
*/
|
*/
|
||||||
public void publishEventCreated(java.util.UUID eventId, java.util.UUID userId, String title, String eventType) {
|
public void publishEventCreated(String eventId, String userId, String title, String eventType) {
|
||||||
EventCreatedMessage message = EventCreatedMessage.builder()
|
EventCreatedMessage message = EventCreatedMessage.builder()
|
||||||
.eventId(eventId)
|
.eventId(eventId)
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
|
|||||||
@ -18,8 +18,6 @@ import org.springframework.messaging.handler.annotation.Payload;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이미지 생성 작업 메시지 구독 Consumer
|
* 이미지 생성 작업 메시지 구독 Consumer
|
||||||
*
|
*
|
||||||
@ -94,8 +92,8 @@ public class ImageJobKafkaConsumer {
|
|||||||
@Transactional
|
@Transactional
|
||||||
protected void processImageGenerationJob(ImageGenerationJobMessage message) {
|
protected void processImageGenerationJob(ImageGenerationJobMessage message) {
|
||||||
try {
|
try {
|
||||||
UUID jobId = UUID.fromString(message.getJobId());
|
String jobId = message.getJobId();
|
||||||
UUID eventId = UUID.fromString(message.getEventId());
|
String eventId = message.getEventId();
|
||||||
|
|
||||||
// Job 조회
|
// Job 조회
|
||||||
Job job = jobRepository.findById(jobId).orElse(null);
|
Job job = jobRepository.findById(jobId).orElse(null);
|
||||||
@ -130,7 +128,7 @@ public class ImageJobKafkaConsumer {
|
|||||||
eventId, message.getImageUrl());
|
eventId, message.getImageUrl());
|
||||||
|
|
||||||
// 사용자에게 알림 전송
|
// 사용자에게 알림 전송
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobCompleted(
|
notificationService.notifyJobCompleted(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
@ -181,7 +179,7 @@ public class ImageJobKafkaConsumer {
|
|||||||
|
|
||||||
// 사용자에게 실패 알림 전송
|
// 사용자에게 실패 알림 전송
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobFailed(
|
notificationService.notifyJobFailed(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
@ -202,7 +200,7 @@ public class ImageJobKafkaConsumer {
|
|||||||
|
|
||||||
// 사용자에게 진행 상태 알림 전송
|
// 사용자에게 진행 상태 알림 전송
|
||||||
if (event != null) {
|
if (event != null) {
|
||||||
UUID userId = event.getUserId();
|
String userId = event.getUserId();
|
||||||
notificationService.notifyJobProgress(
|
notificationService.notifyJobProgress(
|
||||||
userId,
|
userId,
|
||||||
jobId,
|
jobId,
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import com.kt.event.eventservice.application.service.NotificationService;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 로깅 기반 알림 서비스 구현
|
* 로깅 기반 알림 서비스 구현
|
||||||
*
|
*
|
||||||
@ -20,16 +18,16 @@ import java.util.UUID;
|
|||||||
public class LoggingNotificationService implements NotificationService {
|
public class LoggingNotificationService implements NotificationService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyJobCompleted(UUID userId, UUID jobId, String jobType, String message) {
|
public void notifyJobCompleted(String userId, String jobId, String jobType, String message) {
|
||||||
log.info("📢 [작업 완료 알림] UserId: {}, JobId: {}, JobType: {}, Message: {}",
|
log.info("📢 [작업 완료 알림] UserId: {}, JobId: {}, JobType: {}, Message: {}",
|
||||||
userId, jobId, jobType, message);
|
userId, jobId, jobType, message);
|
||||||
|
|
||||||
// TODO: WebSocket, SSE, 또는 Push Notification으로 실시간 알림 전송
|
// TODO: WebSocket, SSE, 또는 Push Notification으로 실시간 알림 전송
|
||||||
// 예: webSocketTemplate.convertAndSendToUser(userId.toString(), "/queue/notifications", notification);
|
// 예: webSocketTemplate.convertAndSendToUser(userId, "/queue/notifications", notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyJobFailed(UUID userId, UUID jobId, String jobType, String errorMessage) {
|
public void notifyJobFailed(String userId, String jobId, String jobType, String errorMessage) {
|
||||||
log.error("📢 [작업 실패 알림] UserId: {}, JobId: {}, JobType: {}, Error: {}",
|
log.error("📢 [작업 실패 알림] UserId: {}, JobId: {}, JobType: {}, Error: {}",
|
||||||
userId, jobId, jobType, errorMessage);
|
userId, jobId, jobType, errorMessage);
|
||||||
|
|
||||||
@ -37,7 +35,7 @@ public class LoggingNotificationService implements NotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyJobProgress(UUID userId, UUID jobId, String jobType, int progress) {
|
public void notifyJobProgress(String userId, String jobId, String jobType, int progress) {
|
||||||
log.info("📢 [작업 진행 알림] UserId: {}, JobId: {}, JobType: {}, Progress: {}%",
|
log.info("📢 [작업 진행 알림] UserId: {}, JobId: {}, JobType: {}, Progress: {}%",
|
||||||
userId, jobId, jobType, progress);
|
userId, jobId, jobType, progress);
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,6 @@ import org.springframework.http.ResponseEntity;
|
|||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 컨트롤러
|
* 이벤트 컨트롤러
|
||||||
*
|
*
|
||||||
@ -129,7 +127,7 @@ public class EventController {
|
|||||||
@GetMapping("/{eventId}")
|
@GetMapping("/{eventId}")
|
||||||
@Operation(summary = "이벤트 상세 조회", description = "특정 이벤트의 상세 정보를 조회합니다.")
|
@Operation(summary = "이벤트 상세 조회", description = "특정 이벤트의 상세 정보를 조회합니다.")
|
||||||
public ResponseEntity<ApiResponse<EventDetailResponse>> getEvent(
|
public ResponseEntity<ApiResponse<EventDetailResponse>> getEvent(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
log.info("이벤트 상세 조회 API 호출 - userId: {}, eventId: {}",
|
log.info("이벤트 상세 조회 API 호출 - userId: {}, eventId: {}",
|
||||||
@ -150,7 +148,7 @@ public class EventController {
|
|||||||
@DeleteMapping("/{eventId}")
|
@DeleteMapping("/{eventId}")
|
||||||
@Operation(summary = "이벤트 삭제", description = "이벤트를 삭제합니다. DRAFT 상태만 삭제 가능합니다.")
|
@Operation(summary = "이벤트 삭제", description = "이벤트를 삭제합니다. DRAFT 상태만 삭제 가능합니다.")
|
||||||
public ResponseEntity<ApiResponse<Void>> deleteEvent(
|
public ResponseEntity<ApiResponse<Void>> deleteEvent(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
log.info("이벤트 삭제 API 호출 - userId: {}, eventId: {}",
|
log.info("이벤트 삭제 API 호출 - userId: {}, eventId: {}",
|
||||||
@ -171,7 +169,7 @@ public class EventController {
|
|||||||
@PostMapping("/{eventId}/publish")
|
@PostMapping("/{eventId}/publish")
|
||||||
@Operation(summary = "이벤트 배포", description = "이벤트를 배포합니다. DRAFT → PUBLISHED 상태 변경.")
|
@Operation(summary = "이벤트 배포", description = "이벤트를 배포합니다. DRAFT → PUBLISHED 상태 변경.")
|
||||||
public ResponseEntity<ApiResponse<Void>> publishEvent(
|
public ResponseEntity<ApiResponse<Void>> publishEvent(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
log.info("이벤트 배포 API 호출 - userId: {}, eventId: {}",
|
log.info("이벤트 배포 API 호출 - userId: {}, eventId: {}",
|
||||||
@ -192,7 +190,7 @@ public class EventController {
|
|||||||
@PostMapping("/{eventId}/end")
|
@PostMapping("/{eventId}/end")
|
||||||
@Operation(summary = "이벤트 종료", description = "이벤트를 종료합니다. PUBLISHED → ENDED 상태 변경.")
|
@Operation(summary = "이벤트 종료", description = "이벤트를 종료합니다. PUBLISHED → ENDED 상태 변경.")
|
||||||
public ResponseEntity<ApiResponse<Void>> endEvent(
|
public ResponseEntity<ApiResponse<Void>> endEvent(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
log.info("이벤트 종료 API 호출 - userId: {}, eventId: {}",
|
log.info("이벤트 종료 API 호출 - userId: {}, eventId: {}",
|
||||||
@ -214,7 +212,7 @@ public class EventController {
|
|||||||
@PostMapping("/{eventId}/images")
|
@PostMapping("/{eventId}/images")
|
||||||
@Operation(summary = "이미지 생성 요청", description = "AI를 통해 이벤트 이미지를 생성합니다.")
|
@Operation(summary = "이미지 생성 요청", description = "AI를 통해 이벤트 이미지를 생성합니다.")
|
||||||
public ResponseEntity<ApiResponse<ImageGenerationResponse>> requestImageGeneration(
|
public ResponseEntity<ApiResponse<ImageGenerationResponse>> requestImageGeneration(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@Valid @RequestBody ImageGenerationRequest request,
|
@Valid @RequestBody ImageGenerationRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -243,8 +241,8 @@ public class EventController {
|
|||||||
@PutMapping("/{eventId}/images/{imageId}/select")
|
@PutMapping("/{eventId}/images/{imageId}/select")
|
||||||
@Operation(summary = "이미지 선택", description = "생성된 이미지 중 하나를 선택합니다.")
|
@Operation(summary = "이미지 선택", description = "생성된 이미지 중 하나를 선택합니다.")
|
||||||
public ResponseEntity<ApiResponse<Void>> selectImage(
|
public ResponseEntity<ApiResponse<Void>> selectImage(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@PathVariable UUID imageId,
|
@PathVariable String imageId,
|
||||||
@Valid @RequestBody SelectImageRequest request,
|
@Valid @RequestBody SelectImageRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -272,7 +270,7 @@ public class EventController {
|
|||||||
@PostMapping("/{eventId}/ai-recommendations")
|
@PostMapping("/{eventId}/ai-recommendations")
|
||||||
@Operation(summary = "AI 추천 요청", description = "AI 서비스에 이벤트 추천 생성을 요청합니다.")
|
@Operation(summary = "AI 추천 요청", description = "AI 서비스에 이벤트 추천 생성을 요청합니다.")
|
||||||
public ResponseEntity<ApiResponse<JobAcceptedResponse>> requestAiRecommendations(
|
public ResponseEntity<ApiResponse<JobAcceptedResponse>> requestAiRecommendations(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@Valid @RequestBody AiRecommendationRequest request,
|
@Valid @RequestBody AiRecommendationRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -300,7 +298,7 @@ public class EventController {
|
|||||||
@PutMapping("/{eventId}/recommendations")
|
@PutMapping("/{eventId}/recommendations")
|
||||||
@Operation(summary = "AI 추천 선택", description = "AI가 생성한 추천 중 하나를 선택하고 커스터마이징합니다.")
|
@Operation(summary = "AI 추천 선택", description = "AI가 생성한 추천 중 하나를 선택하고 커스터마이징합니다.")
|
||||||
public ResponseEntity<ApiResponse<Void>> selectRecommendation(
|
public ResponseEntity<ApiResponse<Void>> selectRecommendation(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@Valid @RequestBody SelectRecommendationRequest request,
|
@Valid @RequestBody SelectRecommendationRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -328,8 +326,8 @@ public class EventController {
|
|||||||
@PutMapping("/{eventId}/images/{imageId}/edit")
|
@PutMapping("/{eventId}/images/{imageId}/edit")
|
||||||
@Operation(summary = "이미지 편집", description = "선택된 이미지를 편집합니다.")
|
@Operation(summary = "이미지 편집", description = "선택된 이미지를 편집합니다.")
|
||||||
public ResponseEntity<ApiResponse<ImageEditResponse>> editImage(
|
public ResponseEntity<ApiResponse<ImageEditResponse>> editImage(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@PathVariable UUID imageId,
|
@PathVariable String imageId,
|
||||||
@Valid @RequestBody ImageEditRequest request,
|
@Valid @RequestBody ImageEditRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -357,7 +355,7 @@ public class EventController {
|
|||||||
@PutMapping("/{eventId}/channels")
|
@PutMapping("/{eventId}/channels")
|
||||||
@Operation(summary = "배포 채널 선택", description = "이벤트를 배포할 채널을 선택합니다.")
|
@Operation(summary = "배포 채널 선택", description = "이벤트를 배포할 채널을 선택합니다.")
|
||||||
public ResponseEntity<ApiResponse<Void>> selectChannels(
|
public ResponseEntity<ApiResponse<Void>> selectChannels(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@Valid @RequestBody SelectChannelsRequest request,
|
@Valid @RequestBody SelectChannelsRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
@ -384,7 +382,7 @@ public class EventController {
|
|||||||
@PutMapping("/{eventId}")
|
@PutMapping("/{eventId}")
|
||||||
@Operation(summary = "이벤트 수정", description = "기존 이벤트의 정보를 수정합니다. DRAFT 상태만 수정 가능합니다.")
|
@Operation(summary = "이벤트 수정", description = "기존 이벤트의 정보를 수정합니다. DRAFT 상태만 수정 가능합니다.")
|
||||||
public ResponseEntity<ApiResponse<EventDetailResponse>> updateEvent(
|
public ResponseEntity<ApiResponse<EventDetailResponse>> updateEvent(
|
||||||
@PathVariable UUID eventId,
|
@PathVariable String eventId,
|
||||||
@Valid @RequestBody UpdateEventRequest request,
|
@Valid @RequestBody UpdateEventRequest request,
|
||||||
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
@AuthenticationPrincipal UserPrincipal userPrincipal) {
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Job 컨트롤러
|
* Job 컨트롤러
|
||||||
*
|
*
|
||||||
@ -41,7 +39,7 @@ public class JobController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/{jobId}")
|
@GetMapping("/{jobId}")
|
||||||
@Operation(summary = "Job 상태 조회", description = "비동기 작업의 상태를 조회합니다 (폴링 방식).")
|
@Operation(summary = "Job 상태 조회", description = "비동기 작업의 상태를 조회합니다 (폴링 방식).")
|
||||||
public ResponseEntity<ApiResponse<JobStatusResponse>> getJobStatus(@PathVariable UUID jobId) {
|
public ResponseEntity<ApiResponse<JobStatusResponse>> getJobStatus(@PathVariable String jobId) {
|
||||||
log.info("Job 상태 조회 API 호출 - jobId: {}", jobId);
|
log.info("Job 상태 조회 API 호출 - jobId: {}", jobId);
|
||||||
|
|
||||||
JobStatusResponse response = jobService.getJobStatus(jobId);
|
JobStatusResponse response = jobService.getJobStatus(jobId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user