doyeon b198c46d06 Analytics 서비스 및 보안 기능 업데이트
- Analytics 서비스 구현 추가 (API, 소스 코드)
- Event 서비스 소스 코드 추가
- 보안 관련 공통 컴포넌트 업데이트 (JWT, UserPrincipal, ErrorCode)
- API 컨벤션 및 명세서 업데이트
- 데이터베이스 SQL 스크립트 추가
- 백엔드 개발 문서 및 테스트 가이드 추가
- Kafka 메시지 체크 도구 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 16:11:00 +09:00

22 KiB

OpenAPI 3.0.3 공통 컨벤션

KT AI 기반 소상공인 이벤트 자동 생성 서비스의 모든 마이크로서비스 API 명세서에 적용되는 공통 컨벤션입니다.

목차

  1. 기본 정보 섹션
  2. 서버 정의
  3. 보안 스키마
  4. 태그 구성
  5. 엔드포인트 정의
  6. 응답 구조
  7. 에러 응답 구조
  8. 스키마 정의
  9. 메타데이터 주석
  10. 기술 명세 섹션
  11. 예제 작성

1. 기본 정보 섹션

1.1 OpenAPI 버전

openapi: 3.0.3
  • 필수: 모든 명세서는 OpenAPI 3.0.3 버전을 사용합니다.

1.2 Info 객체

info:
  title: {Service Name} API
  description: |
    KT AI 기반 소상공인 이벤트 자동 생성 서비스 - {Service Name} API

    {서비스 설명 1-2줄}

    **주요 기능:**
    - {기능 1}
    - {기능 2}
    - {기능 3}

    **보안:** (보안 관련 서비스인 경우)
    - {보안 메커니즘 1}
    - {보안 메커니즘 2}
  version: 1.0.0
  contact:
    name: Digital Garage Team
    email: support@kt-event-marketing.com

필수 항목:

  • title: "{서비스명} API" 형식
  • description: 마크다운 형식으로 서비스 설명 작성
    • 첫 줄: 프로젝트명과 서비스 역할
    • 서비스 설명
    • 주요 기능 목록 (bullet points)
    • 보안 관련 서비스의 경우 보안 섹션 추가
  • version: "1.0.0"
  • contact: name과 email 필수

2. 서버 정의

2.1 서버 URL 구조

servers:
  - url: http://localhost:{port}
    description: Local Development Server
  - url: https://dev-api.kt-event-marketing.com/{service}/v1
    description: Development Server
  - url: https://api.kt-event-marketing.com/{service}/v1
    description: Production Server

포트 번호 할당:

  • User Service: 8081
  • Event Service: 8080
  • Content Service: 8082
  • AI Service: 8083
  • Participation Service: 8084
  • Distribution Service: 8085
  • Analytics Service: 8086

URL 패턴:

  • Local: http://localhost:{port}
  • Dev: https://dev-api.kt-event-marketing.com/{service}/v1
  • Prod: https://api.kt-event-marketing.com/{service}/v1

3. 보안 스키마

3.1 JWT Bearer 인증

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT Bearer 토큰 인증

        **형식:** Authorization: Bearer {JWT_TOKEN}

        **토큰 만료:** 7일

        **Claims:**
        - userId: 사용자 ID
        - role: 사용자 역할 (OWNER)
        - iat: 발급 시각
        - exp: 만료 시각

3.2 전역 보안 적용

security:
  - BearerAuth: []

적용 방법:

  • 인증이 필요한 모든 엔드포인트에 security 섹션 추가
  • 공개 API (예: 로그인, 회원가입)는 엔드포인트 레벨에서 security: []로 오버라이드

4. 태그 구성

4.1 태그 정의 패턴

tags:
  - name: {Category Name}
    description: {카테고리 설명 (한글)}

태그 명명 규칙:

  • 영문 사용: 명확한 영문 카테고리명
  • 설명 한글: description은 한글로 상세 설명
  • 일관성 유지: 유사 기능은 동일한 태그명 사용

예시:

tags:
  - name: Authentication
    description: 인증 관련 API (로그인, 로그아웃, 회원가입)
  - name: Profile
    description: 프로필 관련 API (조회, 수정, 비밀번호 변경)
  - name: Event Creation
    description: 이벤트 생성 플로우

5. 엔드포인트 정의

5.1 엔드포인트 경로 규칙

경로 패턴:

/{resource}
/{resource}/{id}
/{resource}/{id}/{sub-resource}

중요: /api prefix 사용 금지

  • 잘못된 예: /api/users/register
  • 올바른 예: /users/register

API Gateway 또는 서버 URL에서 서비스 구분이 이루어지므로, 엔드포인트 경로에 /api를 포함하지 않습니다.

5.2 공통 엔드포인트 구조

paths:
  /{resource}:
    {http-method}:
      tags:
        - {Tag Name}
      summary: {짧은 한글 설명}
      description: |
        {상세 설명}

        **유저스토리:** {UFR 코드}

        **주요 기능:**
        - {기능 1}
        - {기능 2}

        **처리 흐름:** (복잡한 로직인 경우)
        1. {단계 1}
        2. {단계 2}

        **보안:** (보안 관련 엔드포인트인 경우)
        - {보안 메커니즘}
      operationId: {camelCase 메서드명}
      x-user-story: {UFR 코드}
      x-controller: {ControllerClass}.{methodName}
      security:
        - BearerAuth: []
      parameters:
        - $ref: '#/components/parameters/{ParameterName}'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/{RequestSchema}'
            examples:
              {exampleName}:
                summary: {예시 설명}
                value: {...}
      responses:
        '{statusCode}':
          description: {응답 설명}
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/{ResponseSchema}'
              examples:
                {exampleName}:
                  summary: {예시 설명}
                  value: {...}

5.3 필수 항목

  • tags: 1개 이상의 태그 지정
  • summary: 한글로 간결하게 (10자 이내 권장)
  • description: 마크다운 형식의 상세 설명
    • 유저스토리 코드 명시
    • 주요 기능 bullet points
    • 복잡한 경우 처리 흐름 순서 작성
    • 보안 관련 내용 (해당 시)
  • operationId: camelCase 메서드명 (예: getUserProfile, createEvent)
  • x-user-story: UFR 코드 (예: UFR-USER-010)
  • x-controller: 컨트롤러 클래스와 메서드 (예: UserController.getProfile)

5.4 operationId 명명 규칙

{동사}{명사}

동사 목록:

  • get: 조회
  • list: 목록 조회
  • create: 생성
  • update: 수정
  • delete: 삭제
  • register: 등록
  • login: 로그인
  • logout: 로그아웃
  • select: 선택
  • request: 요청
  • publish: 배포
  • end: 종료

예시:

  • getUser, listEvents, createEvent
  • updateProfile, deleteEvent
  • registerUser, loginUser, logoutUser
  • selectRecommendation, publishEvent

6. 응답 구조

6.1 성공 응답 (Success Response)

원칙: 직접 응답 (Direct Response)

responses:
  '200':
    description: {작업} 성공
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/{ResponseSchema}'

응답 스키마 예시:

UserProfileResponse:
  type: object
  required:
    - userId
    - userName
    - email
  properties:
    userId:
      type: integer
      format: int64
      description: 사용자 ID
      example: 123
    userName:
      type: string
      description: 사용자 이름
      example: 홍길동
    email:
      type: string
      format: email
      description: 이메일 주소
      example: hong@example.com

예외: Wrapper가 필요한 경우 (메시지 전달 필요 시)

LogoutResponse:
  type: object
  required:
    - success
    - message
  properties:
    success:
      type: boolean
      description: 성공 여부
      example: true
    message:
      type: string
      description: 응답 메시지
      example: 안전하게 로그아웃되었습니다

6.2 페이징 응답 (Pagination Response)

{Resource}ListResponse:
  type: object
  required:
    - content
    - page
  properties:
    content:
      type: array
      items:
        $ref: '#/components/schemas/{ResourceSummary}'
    page:
      $ref: '#/components/schemas/PageInfo'

PageInfo:
  type: object
  required:
    - page
    - size
    - totalElements
    - totalPages
  properties:
    page:
      type: integer
      description: 현재 페이지 번호
      example: 0
    size:
      type: integer
      description: 페이지 크기
      example: 20
    totalElements:
      type: integer
      description: 전체 요소 개수
      example: 45
    totalPages:
      type: integer
      description: 전체 페이지 개수
      example: 3

7. 에러 응답 구조

7.1 표준 에러 응답 스키마

ErrorResponse:
  type: object
  required:
    - code
    - message
    - timestamp
  properties:
    code:
      type: string
      description: 에러 코드
      example: USER_001
    message:
      type: string
      description: 에러 메시지
      example: 이미 가입된 전화번호입니다
    timestamp:
      type: string
      format: date-time
      description: 에러 발생 시각
      example: 2025-10-22T10:30:00Z
    details:
      type: array
      description: 상세 에러 정보 (선택 사항)
      items:
        type: string
      example: ["필드명: 필수 항목입니다"]

필수 필드:

  • code: 에러 코드 (서비스별 고유 코드)
  • message: 사용자에게 표시할 에러 메시지 (한글)
  • timestamp: 에러 발생 시각 (ISO 8601 형식)

선택 필드:

  • details: 상세 에러 정보 배열 (validation 에러 등)

7.2 에러 코드 명명 규칙

{SERVICE}_{NUMBER}

서비스 약어:

  • USER: User Service
  • EVENT: Event Service
  • CONT: Content Service
  • AI: AI Service
  • PART: Participation Service
  • DIST: Distribution Service
  • ANAL: Analytics Service
  • AUTH: 인증 관련 (공통)
  • VALIDATION_ERROR: 입력 검증 오류 (공통)

예시:

  • USER_001: 중복 사용자
  • USER_002: 사업자번호 검증 실패
  • AUTH_001: 인증 실패
  • AUTH_002: 유효하지 않은 토큰
  • VALIDATION_ERROR: 입력 검증 오류

7.3 공통 에러 응답 정의

components:
  responses:
    BadRequest:
      description: 잘못된 요청
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            validationError:
              summary: 입력 검증 오류
              value:
                code: VALIDATION_ERROR
                message: 요청 파라미터가 올바르지 않습니다
                timestamp: 2025-10-22T10:30:00Z
                details:
                  - "필드명: 필수 항목입니다"

    Unauthorized:
      description: 인증 실패
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            authFailed:
              summary: 인증 실패
              value:
                code: AUTH_001
                message: 인증에 실패했습니다
                timestamp: 2025-10-22T10:30:00Z

    Forbidden:
      description: 권한 없음
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            forbidden:
              summary: 권한 없음
              value:
                code: AUTH_003
                message: 해당 리소스에 접근할 권한이 없습니다
                timestamp: 2025-10-22T10:30:00Z

    NotFound:
      description: 리소스를 찾을 수 없음
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            notFound:
              summary: 리소스 없음
              value:
                code: NOT_FOUND
                message: 요청한 리소스를 찾을 수 없습니다
                timestamp: 2025-10-22T10:30:00Z

    InternalServerError:
      description: 서버 내부 오류
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            serverError:
              summary: 서버 오류
              value:
                code: INTERNAL_SERVER_ERROR
                message: 서버 내부 오류가 발생했습니다
                timestamp: 2025-10-22T10:30:00Z

7.4 엔드포인트별 에러 응답 적용

responses:
  '400':
    $ref: '#/components/responses/BadRequest'
  '401':
    $ref: '#/components/responses/Unauthorized'
  '403':
    $ref: '#/components/responses/Forbidden'
  '404':
    $ref: '#/components/responses/NotFound'
  '500':
    $ref: '#/components/responses/InternalServerError'

특수 에러 (비즈니스 로직 에러):

'409':
  description: 비즈니스 로직 충돌
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/ErrorResponse'
      examples:
        duplicateUser:
          summary: 중복 사용자
          value:
            code: USER_001
            message: 이미 가입된 전화번호입니다
            timestamp: 2025-10-22T10:30:00Z

8. 스키마 정의

8.1 스키마 명명 규칙

Request 스키마:

{Action}{Resource}Request

예: RegisterRequest, LoginRequest, CreateEventRequest

Response 스키마:

{Resource}{Type}Response

예: UserProfileResponse, EventListResponse, EventDetailResponse

공통 모델:

{Resource}{Type}

예: EventSummary, GeneratedImage, PageInfo

8.2 스키마 작성 원칙

필수 항목:

  • type: 객체 타입 (object, array, string 등)
  • required: 필수 필드 목록
  • properties: 각 필드 정의
    • type: 필드 타입
    • description: 필드 설명 (한글)
    • example: 예시 값

선택 항목:

  • format: 특수 형식 (date, date-time, email, uri, uuid, int64 등)
  • pattern: 정규식 패턴 (전화번호, 사업자번호 등)
  • minLength, maxLength: 문자열 길이 제한
  • minimum, maximum: 숫자 범위 제한
  • enum: 허용 값 목록

예시:

RegisterRequest:
  type: object
  required:
    - name
    - phoneNumber
    - email
    - password
  properties:
    name:
      type: string
      minLength: 2
      maxLength: 50
      description: 사용자 이름 (2자 이상, 한글/영문)
      example: 홍길동
    phoneNumber:
      type: string
      pattern: '^010\d{8}$'
      description: 휴대폰 번호 (010XXXXXXXX)
      example: "01012345678"
    email:
      type: string
      format: email
      maxLength: 100
      description: 이메일 주소
      example: hong@example.com
    password:
      type: string
      minLength: 8
      maxLength: 100
      description: 비밀번호 (8자 이상, 영문/숫자/특수문자 포함)
      example: "Password123!"

8.3 날짜/시간 형식

날짜: format: date, 형식 YYYY-MM-DD

startDate:
  type: string
  format: date
  description: 시작일
  example: "2025-03-01"

날짜/시간: format: date-time, 형식 ISO 8601

createdAt:
  type: string
  format: date-time
  description: 생성일시
  example: 2025-10-22T10:30:00Z

8.4 ID 형식

UUID:

eventId:
  type: string
  format: uuid
  description: 이벤트 ID
  example: "550e8400-e29b-41d4-a716-446655440000"

정수 ID:

userId:
  type: integer
  format: int64
  description: 사용자 ID
  example: 123

9. 메타데이터 주석

9.1 필수 메타데이터

x-user-story: {UFR 코드}
x-controller: {ControllerClass}.{methodName}

x-user-story:

  • 유저스토리 코드 명시
  • 여러 유저스토리와 관련된 경우 콤마로 구분
  • 예: UFR-USER-010, UFR-EVENT-010, UFR-EVENT-070

x-controller:

  • 컨트롤러 클래스와 메서드 매핑
  • 백엔드 개발 시 참조
  • 예: UserController.registerUser, EventController.getEvents

9.2 선택 메타데이터 (필요 시)

x-internal: true  # 내부 API 표시
x-async: true     # 비동기 처리 표시

10. 기술 명세 섹션

10.1 x-technical-specifications

비동기 처리 서비스 (AI, Content 등):

x-technical-specifications:
  async-processing:
    message-queue: Kafka
    topics:
      request: ai.recommendation.request
      response: ai.recommendation.response
    job-tracking: Redis (TTL 24h)
    timeout: 300s

  resilience:
    circuit-breaker:
      failure-threshold: 5
      timeout: 10s
      half-open-requests: 3
    retry:
      max-attempts: 3
      backoff: exponential
      initial-interval: 1s
      max-interval: 10s
    fallback:
      strategy: cached-result

  caching:
    provider: Redis
    ttl: 7d
    key-pattern: "content:event:{eventDraftId}"

  external-apis:
    - name: Claude API
      endpoint: https://api.anthropic.com/v1/messages
      timeout: 60s
      circuit-breaker: true
    - name: GPT-4 API
      endpoint: https://api.openai.com/v1/chat/completions
      timeout: 60s
      circuit-breaker: true

동기 처리 서비스:

x-technical-specifications:
  database:
    type: PostgreSQL
    connection-pool:
      min: 10
      max: 50
      timeout: 30s

  caching:
    provider: Redis
    ttl: 30m
    key-pattern: "user:{userId}"

  security:
    authentication: JWT Bearer
    password-hashing: bcrypt
    encryption:
      algorithm: AES-256-GCM
      fields: [businessNumber]

10.2 적용 기준

필수 포함 서비스:

  • Content Service: 비동기 처리, Kafka, 외부 API 통합
  • AI Service: 비동기 처리, Kafka, Claude/GPT 통합

선택 포함 서비스:

  • User Service: 보안 관련 명세
  • Event Service: 오케스트레이션 패턴
  • Participation Service: 대용량 트래픽 대비 캐싱

11. 예제 작성

11.1 Request/Response 예제 원칙

모든 requestBody와 주요 response에 예제 필수:

requestBody:
  required: true
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/RegisterRequest'
      examples:
        restaurant:
          summary: 음식점 회원가입 예시
          value:
            name: 홍길동
            phoneNumber: "01012345678"
            email: hong@example.com
            password: "Password123!"
            storeName: 맛있는집
            industry: 음식점
        cafe:
          summary: 카페 회원가입 예시
          value:
            name: 김철수
            phoneNumber: "01087654321"
            email: kim@example.com
            password: "SecurePass456!"
            storeName: 아메리카노 카페
            industry: 카페

성공 응답 예제:

responses:
  '200':
    description: 프로필 조회 성공
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ProfileResponse'
        examples:
          success:
            summary: 프로필 조회 성공 응답
            value:
              userId: 123
              userName: 홍길동
              phoneNumber: "01012345678"
              email: hong@example.com

에러 응답 예제:

responses:
  '400':
    description: 잘못된 요청
    content:
      application/json:
        schema:
          $ref: '#/components/schemas/ErrorResponse'
        examples:
          duplicateUser:
            summary: 중복 사용자
            value:
              code: USER_001
              message: 이미 가입된 전화번호입니다
              timestamp: 2025-10-22T10:30:00Z
          invalidBusinessNumber:
            summary: 사업자번호 검증 실패
            value:
              code: USER_002
              message: 유효하지 않은 사업자번호입니다
              timestamp: 2025-10-22T10:30:00Z

11.2 예제 명명 규칙

  • success: 성공 케이스
  • {errorType}: 에러 케이스 (예: duplicateUser, validationError)
  • {scenario}: 시나리오별 예제 (예: restaurant, cafe)

12. 체크리스트

API 명세서 작성 시 아래 체크리스트를 확인하세요:

기본 정보

  • OpenAPI 버전 3.0.3 명시
  • info.title에 서비스명 포함
  • info.description에 주요 기능 목록 포함
  • info.version 1.0.0
  • contact 정보 포함

서버 및 보안

  • servers에 Local, Dev, Prod 정의
  • 포트 번호 정확히 할당
  • components.securitySchemes에 BearerAuth 정의
  • 인증 필요한 엔드포인트에 security 적용

엔드포인트

  • 모든 엔드포인트에 tags 지정
  • summary와 description 작성 (한글)
  • operationId camelCase로 작성
  • x-user-story UFR 코드 명시
  • x-controller 매핑 정보 포함

스키마

  • Request/Response 스키마 명명 규칙 준수
  • required 필드 명시
  • 모든 properties에 description과 example 포함
  • 적절한 format 사용 (date, date-time, email, uuid 등)

응답 구조

  • ErrorResponse 표준 스키마 사용
  • 공통 에러 응답 ($ref) 활용
  • 에러 코드 명명 규칙 준수
  • 페이징 응답에 PageInfo 사용

예제

  • requestBody에 최소 1개 이상 예제
  • 주요 response에 success 예제
  • 주요 에러 케이스에 예제

기술 명세 (해당 시)

  • 비동기 처리 서비스: x-technical-specifications 포함
  • Kafka 토픽, Redis 캐싱 정보 명시
  • 외부 API 연동 정보 포함

13. 참고 자료

서비스별 API 명세서

  • User Service API: /design/backend/api/user-service-api.yaml
  • Event Service API: /design/backend/api/event-service-api.yaml
  • Content Service API: /design/backend/api/content-service-api.yaml
  • AI Service API: /design/backend/api/ai-service-api.yaml
  • Participation Service API: /design/backend/api/participation-service-api.yaml
  • Distribution Service API: /design/backend/api/distribution-service-api.yaml
  • Analytics Service API: /design/backend/api/analytics-service-api.yaml

OpenAPI 3.0.3 공식 문서

프로젝트 아키텍처

  • High-Level Architecture: /design/high-level-architecture.md
  • Logical Architecture: /design/backend/logical/

문서 버전: 1.0.0 최종 수정일: 2025-10-23 작성자: Digital Garage Team