mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2026-01-22 00:06:24 +00:00
Merge branch 'develop' of https://github.com/ktds-dg0501/kt-event-marketing into develop
This commit is contained in:
commit
c915bc172e
23
.github/README.md
vendored
23
.github/README.md
vendored
@ -1,12 +1,15 @@
|
|||||||
# KT Event Marketing - CI/CD Infrastructure
|
# KT 이벤트 파트너
|
||||||
|
|
||||||
이 디렉토리는 KT Event Marketing 백엔드 서비스의 CI/CD 인프라를 포함합니다.
|
KT 이벤트 파트너는 소상공인이 AI를 활용하여 효과적인 이벤트를 쉽게 기획하고 관리할 수 있도록 지원하는 플랫폼입니다.
|
||||||
|
매장 정보와 AI 추천을 기반으로 이벤트를 생성하고, SNS 콘텐츠를 자동 생성하며, 다양한 채널로 배포하고, 실시간으로 성과를 분석할 수 있습니다.
|
||||||
|
|
||||||
|
이 디렉토리는 KT 이벤트 파트너 서비스의 CI/CD 인프라를 포함합니다.
|
||||||
|
|
||||||
## 디렉토리 구조
|
## 디렉토리 구조
|
||||||
|
|
||||||
```
|
```
|
||||||
.github/
|
.github/
|
||||||
├── README.md # 이 파일
|
├── README.md
|
||||||
├── workflows/
|
├── workflows/
|
||||||
│ └── backend-cicd.yaml # GitHub Actions 워크플로우
|
│ └── backend-cicd.yaml # GitHub Actions 워크플로우
|
||||||
├── kustomize/ # Kubernetes 매니페스트 관리
|
├── kustomize/ # Kubernetes 매니페스트 관리
|
||||||
@ -126,13 +129,13 @@ GitHub Actions 워크플로우 정의 파일입니다.
|
|||||||
|
|
||||||
## 서비스 목록
|
## 서비스 목록
|
||||||
|
|
||||||
1. **user-service** (8081) - 사용자 관리
|
1. **user-service** (8081) - 사용자 및 매장 관리
|
||||||
2. **event-service** (8082) - 이벤트 관리
|
2. **event-service** (8080) - 이벤트 관리
|
||||||
3. **ai-service** (8083) - AI 기반 콘텐츠 생성
|
3. **ai-service** (8083) - AI 기반 트렌드 분석 및 이벤트 추천
|
||||||
4. **content-service** (8084) - 콘텐츠 관리
|
4. **content-service** (8084) - SNS 콘텐츠(이미지) 생성
|
||||||
5. **distribution-service** (8085) - 경품 배포
|
5. **distribution-service** (8085) - 다중 채 배포
|
||||||
6. **participation-service** (8086) - 이벤트 참여
|
6. **participation-service** (8084) - 이벤트 참여자 관리
|
||||||
7. **analytics-service** (8087) - 분석 및 통계
|
7. **analytics-service** (8086) - 성과 분석 및 통계
|
||||||
|
|
||||||
## 모니터링
|
## 모니터링
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="AiServiceApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
|
<configuration default="false" name="AiServiceApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
|
||||||
<option name="ACTIVE_PROFILES" />
|
<option name="ACTIVE_PROFILES" />
|
||||||
<module name="kt-event-marketing.ai-service.main" />
|
<module name="kt-event-marketing.ai-service.main" />
|
||||||
<option name="SPRING_BOOT_MAIN_CLASS" value="com.kt.ai.AiApplication" />
|
<option name="SPRING_BOOT_MAIN_CLASS" value="com.kt.ai.AiServiceApplication" />
|
||||||
<extension name="coverage">
|
<extension name="coverage">
|
||||||
<pattern>
|
<pattern>
|
||||||
<option name="PATTERN" value="com.kt.ai.*" />
|
<option name="PATTERN" value="com.kt.ai.*" />
|
||||||
@ -10,19 +10,25 @@
|
|||||||
</pattern>
|
</pattern>
|
||||||
</extension>
|
</extension>
|
||||||
<envs>
|
<envs>
|
||||||
<env name="SERVER_PORT" value="8081" />
|
<env name="SERVER_PORT" value="8083" />
|
||||||
<env name="DB_HOST" value="4.230.112.141" />
|
|
||||||
<env name="DB_PORT" value="5432" />
|
|
||||||
<env name="DB_NAME" value="aidb" />
|
|
||||||
<env name="DB_USERNAME" value="eventuser" />
|
|
||||||
<env name="DB_PASSWORD" value="Hi5Jessica!" />
|
|
||||||
<env name="REDIS_HOST" value="20.214.210.71" />
|
<env name="REDIS_HOST" value="20.214.210.71" />
|
||||||
<env name="REDIS_PORT" value="6379" />
|
<env name="REDIS_PORT" value="6379" />
|
||||||
<env name="REDIS_PASSWORD" value="Hi5Jessica!" />
|
<env name="REDIS_PASSWORD" value="Hi5Jessica!" />
|
||||||
|
<env name="REDIS_DATABASE" value="3" />
|
||||||
<env name="KAFKA_BOOTSTRAP_SERVERS" value="20.249.182.13:9095,4.217.131.59:9095" />
|
<env name="KAFKA_BOOTSTRAP_SERVERS" value="20.249.182.13:9095,4.217.131.59:9095" />
|
||||||
<env name="KAFKA_CONSUMER_GROUP" value="ai" />
|
<env name="KAFKA_CONSUMER_GROUP" value="ai-service-consumers" />
|
||||||
<env name="JPA_DDL_AUTO" value="update" />
|
<env name="KAFKA_TOPICS_AI_JOB" value="ai-event-generation-job" />
|
||||||
<env name="JPA_SHOW_SQL" value="false" />
|
<env name="KAFKA_TOPICS_AI_JOB_DLQ" value="ai-event-generation-job-dlq" />
|
||||||
|
<env name="AI_PROVIDER" value="CLAUDE" />
|
||||||
|
<env name="AI_CLAUDE_API_URL" value="https://api.anthropic.com/v1/messages" />
|
||||||
|
<env name="AI_CLAUDE_API_KEY" value="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" />
|
||||||
|
<env name="AI_CLAUDE_ANTHROPIC_VERSION" value="2023-06-01" />
|
||||||
|
<env name="AI_CLAUDE_MODEL" value="claude-sonnet-4-5-20250929" />
|
||||||
|
<env name="AI_CLAUDE_MAX_TOKENS" value="4096" />
|
||||||
|
<env name="AI_CLAUDE_TEMPERATURE" value="0.7" />
|
||||||
|
<env name="LOG_LEVEL_ROOT" value="INFO" />
|
||||||
|
<env name="LOG_LEVEL_AI" value="DEBUG" />
|
||||||
|
<env name="LOG_LEVEL_KAFKA" value="INFO" />
|
||||||
</envs>
|
</envs>
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
|
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
@ -17,7 +17,6 @@ import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSeriali
|
|||||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis 설정
|
* Redis 설정
|
||||||
@ -30,11 +29,11 @@ import java.util.Arrays;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class RedisConfig {
|
public class RedisConfig {
|
||||||
|
|
||||||
@Value("${spring.data.redis.sentinel.master:mymaster}")
|
@Value("${spring.data.redis.host}")
|
||||||
private String sentinelMaster;
|
private String redisHost;
|
||||||
|
|
||||||
@Value("${spring.data.redis.sentinel.nodes}")
|
@Value("${spring.data.redis.port}")
|
||||||
private String sentinelNodes;
|
private int redisPort;
|
||||||
|
|
||||||
@Value("${spring.data.redis.password}")
|
@Value("${spring.data.redis.password}")
|
||||||
private String redisPassword;
|
private String redisPassword;
|
||||||
@ -46,26 +45,18 @@ public class RedisConfig {
|
|||||||
private long redisTimeout;
|
private long redisTimeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis 연결 팩토리 설정 (Sentinel 모드)
|
* Redis 연결 팩토리 설정 (Standalone 모드)
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RedisConnectionFactory redisConnectionFactory() {
|
public RedisConnectionFactory redisConnectionFactory() {
|
||||||
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
|
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
|
||||||
.master(sentinelMaster);
|
redisConfig.setHostName(redisHost);
|
||||||
|
redisConfig.setPort(redisPort);
|
||||||
// Sentinel 노드 추가 (콤마로 구분된 host:port 형식)
|
redisConfig.setDatabase(redisDatabase);
|
||||||
Arrays.stream(sentinelNodes.split(","))
|
|
||||||
.map(String::trim)
|
|
||||||
.forEach(node -> {
|
|
||||||
String[] parts = node.split(":");
|
|
||||||
sentinelConfig.sentinel(parts[0], Integer.parseInt(parts[1]));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (redisPassword != null && !redisPassword.isEmpty()) {
|
if (redisPassword != null && !redisPassword.isEmpty()) {
|
||||||
sentinelConfig.setPassword(redisPassword);
|
redisConfig.setPassword(redisPassword);
|
||||||
sentinelConfig.setSentinelPassword(redisPassword);
|
|
||||||
}
|
}
|
||||||
sentinelConfig.setDatabase(redisDatabase);
|
|
||||||
|
|
||||||
// Lettuce Client 설정: Timeout 및 Connection 옵션
|
// Lettuce Client 설정: Timeout 및 Connection 옵션
|
||||||
SocketOptions socketOptions = SocketOptions.builder()
|
SocketOptions socketOptions = SocketOptions.builder()
|
||||||
@ -83,7 +74,7 @@ public class RedisConfig {
|
|||||||
.clientOptions(clientOptions)
|
.clientOptions(clientOptions)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return new LettuceConnectionFactory(sentinelConfig, clientConfig);
|
return new LettuceConnectionFactory(redisConfig, clientConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.kt.ai.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 추천 생성 중 발생한 예외
|
||||||
|
*
|
||||||
|
* @author AI Service Team
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public class RecommendationGenerationException extends AIServiceException {
|
||||||
|
public RecommendationGenerationException(String message) {
|
||||||
|
super("RECOMMENDATION_GENERATION_FAILED", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecommendationGenerationException(String message, Throwable cause) {
|
||||||
|
super("RECOMMENDATION_GENERATION_FAILED", message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,16 +2,14 @@ spring:
|
|||||||
application:
|
application:
|
||||||
name: ai-service
|
name: ai-service
|
||||||
|
|
||||||
# Redis Configuration with Sentinel
|
# Redis Configuration
|
||||||
data:
|
data:
|
||||||
redis:
|
redis:
|
||||||
|
host: ${REDIS_HOST:20.214.210.71}
|
||||||
|
port: ${REDIS_PORT:6379}
|
||||||
password: ${REDIS_PASSWORD:Hi5Jessica!}
|
password: ${REDIS_PASSWORD:Hi5Jessica!}
|
||||||
database: ${REDIS_DATABASE:3}
|
database: ${REDIS_DATABASE:3}
|
||||||
timeout: ${REDIS_TIMEOUT:3000}
|
timeout: ${REDIS_TIMEOUT:3000}
|
||||||
sentinel:
|
|
||||||
master: ${REDIS_SENTINEL_MASTER:mymaster}
|
|
||||||
nodes: ${REDIS_SENTINEL_NODES:redis-node-0.redis-headless.kt-event-marketing.svc.cluster.local:26379,redis-node-1.redis-headless.kt-event-marketing.svc.cluster.local:26379}
|
|
||||||
password: ${REDIS_PASSWORD:Hi5Jessica!}
|
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
max-active: ${REDIS_POOL_MAX:8}
|
max-active: ${REDIS_POOL_MAX:8}
|
||||||
|
|||||||
@ -150,7 +150,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"eventId": "evt_2025020104",
|
"eventId": "evt_2025020104",
|
||||||
"completedAt": null,
|
"completedAt": "2025-01-25T09:00:00",
|
||||||
"channels": [
|
"channels": [
|
||||||
{
|
{
|
||||||
"channel": "우리동네TV",
|
"channel": "우리동네TV",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user