spring: application: name: ai-service # Redis Configuration with Sentinel data: redis: password: ${REDIS_PASSWORD:Hi5Jessica!} database: ${REDIS_DATABASE:3} 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: pool: max-active: ${REDIS_POOL_MAX:8} max-idle: ${REDIS_POOL_IDLE:8} min-idle: ${REDIS_POOL_MIN:2} max-wait: ${REDIS_POOL_WAIT:-1ms} # Kafka Consumer Configuration kafka: bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS:20.249.182.13:9095,4.217.131.59:9095} consumer: group-id: ${KAFKA_CONSUMER_GROUP:ai-service-consumers} auto-offset-reset: earliest enable-auto-commit: false key-deserializer: org.apache.kafka.common.serialization.StringDeserializer value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer properties: spring.json.trusted.packages: "*" spring.json.use.type.headers: false spring.json.value.default.type: com.kt.ai.kafka.message.AIJobMessage max.poll.records: 10 session.timeout.ms: 30000 listener: ack-mode: manual # Server Configuration server: port: ${SERVER_PORT:8083} servlet: context-path: /api/v1/ai encoding: charset: UTF-8 enabled: true force: true # JWT Configuration jwt: secret: ${JWT_SECRET:kt-event-marketing-secret-key-for-development-only-please-change-in-production} access-token-validity: ${JWT_ACCESS_TOKEN_VALIDITY:604800000} refresh-token-validity: ${JWT_REFRESH_TOKEN_VALIDITY:86400} # CORS Configuration cors: allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:*,http://kt-event-marketing.20.214.196.128.nip.io} allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH} allowed-headers: ${CORS_ALLOWED_HEADERS:*} allow-credentials: ${CORS_ALLOW_CREDENTIALS:true} max-age: ${CORS_MAX_AGE:3600} # Actuator Configuration management: endpoints: web: exposure: include: health,info,metrics,prometheus endpoint: health: show-details: always health: redis: enabled: true kafka: enabled: true # OpenAPI Documentation Configuration springdoc: api-docs: path: /v3/api-docs enabled: true swagger-ui: path: /swagger-ui.html enabled: true operations-sorter: method tags-sorter: alpha display-request-duration: true doc-expansion: none show-actuator: false default-consumes-media-type: application/json default-produces-media-type: application/json # Logging Configuration logging: level: root: ${LOG_LEVEL_ROOT:INFO} com.kt.ai: ${LOG_LEVEL_AI:DEBUG} org.springframework.kafka: ${LOG_LEVEL_KAFKA:INFO} org.springframework.data.redis: ${LOG_LEVEL_REDIS:INFO} io.github.resilience4j: ${LOG_LEVEL_RESILIENCE4J:DEBUG} pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: name: ${LOG_FILE_NAME:logs/ai-service.log} logback: rollingpolicy: max-file-size: ${LOG_FILE_MAX_SIZE:10MB} max-history: ${LOG_FILE_MAX_HISTORY:7} total-size-cap: ${LOG_FILE_TOTAL_CAP:100MB} # Kafka Topics Configuration kafka: topics: ai-job: ${KAFKA_TOPICS_AI_JOB:ai-event-generation-job} ai-job-dlq: ${KAFKA_TOPICS_AI_JOB_DLQ:ai-event-generation-job-dlq} # AI API Configuration (실제 API 사용) ai: provider: ${AI_PROVIDER:CLAUDE} claude: api-url: ${AI_CLAUDE_API_URL:https://api.anthropic.com/v1/messages} api-key: ${AI_CLAUDE_API_KEY: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} anthropic-version: ${AI_CLAUDE_ANTHROPIC_VERSION:2023-06-01} model: ${AI_CLAUDE_MODEL:claude-sonnet-4-5-20250929} max-tokens: ${AI_CLAUDE_MAX_TOKENS:4096} temperature: ${AI_CLAUDE_TEMPERATURE:0.7} timeout: ${AI_CLAUDE_TIMEOUT:300000} # Circuit Breaker Configuration resilience4j: circuitbreaker: configs: default: failure-rate-threshold: 50 slow-call-rate-threshold: 50 slow-call-duration-threshold: 60s permitted-number-of-calls-in-half-open-state: 3 max-wait-duration-in-half-open-state: 0 sliding-window-type: COUNT_BASED sliding-window-size: 10 minimum-number-of-calls: 5 wait-duration-in-open-state: 60s automatic-transition-from-open-to-half-open-enabled: true instances: claudeApi: base-config: default failure-rate-threshold: 50 wait-duration-in-open-state: 60s gpt4Api: base-config: default failure-rate-threshold: 50 wait-duration-in-open-state: 60s timelimiter: configs: default: timeout-duration: 300s # 5 minutes instances: claudeApi: timeout-duration: 300s gpt4Api: timeout-duration: 300s # Redis Cache TTL Configuration (seconds) cache: ttl: recommendation: ${CACHE_TTL_RECOMMENDATION:86400} # 24 hours job-status: ${CACHE_TTL_JOB_STATUS:86400} # 24 hours trend: ${CACHE_TTL_TREND:3600} # 1 hour fallback: ${CACHE_TTL_FALLBACK:604800} # 7 days