openapi: 3.0.3
info:
  title: 런모아 Storefront API
  version: 0.3.0
  description: 외부 정적 프론트엔드와 판매자 서버 연동을 위한 런모아 API 문서입니다.
servers:
  - url: https://{host}/api/storefront/v1
    description: 브라우저용 스토어프론트 API
    variables:
      host:
        default: your-site.runmoa.com
  - url: https://{host}/api/public/v1
    description: 서버용 비공개 API
    variables:
      host:
        default: your-site.runmoa.com
components:
  securitySchemes:
    StorefrontKey:
      type: apiKey
      in: header
      name: X-Runmoa-Site-Key
      description: 브라우저용 스토어프론트 키입니다. moa_pub_ 형식입니다.
    UserBearer:
      type: http
      scheme: bearer
      description: 로그인 callback 응답의 token 값을 사용합니다.
    ServerPrivateKey:
      type: http
      scheme: bearer
      description: 서버용 비공개 API 키입니다. 브라우저에 노출하면 안 됩니다.
  responses:
    Unauthorized:
      description: 인증 실패
    ValidationError:
      description: 요청 값 검증 실패
paths:
  /site:
    get:
      summary: 사이트 기본 정보 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 사이트 정보
  /site-meta/{key}:
    get:
      summary: 사이트 메타 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: key
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: 사이트 메타 값
  /pages:
    get:
      summary: 페이지 목록 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 페이지 목록
  /pages/{slug}:
    get:
      summary: 페이지 상세 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: 페이지 상세
  /pages/home:
    get:
      summary: 홈 페이지 데이터 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 홈 페이지 데이터
  /menus:
    get:
      summary: 메뉴 목록 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 메뉴 목록
  /popups:
    get:
      summary: 활성 팝업 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 활성 팝업 목록
  /auth/schoolmoa-client:
    get:
      summary: Schoolmoa 로그인 client id 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: Schoolmoa client id
  /auth/schoolmoa/callback:
    post:
      summary: Schoolmoa 로그인 callback 처리
      security:
        - StorefrontKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [code]
              properties:
                code:
                  type: string
      responses:
        "200":
          description: 로그인 성공. 사용자 token 포함.
        "401":
          $ref: "#/components/responses/Unauthorized"
  /auth/logout:
    post:
      summary: 로그아웃
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 로그아웃 완료
  /products:
    get:
      summary: 상품 목록 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
        - name: limit
          in: query
          schema:
            type: integer
        - name: search
          in: query
          schema:
            type: string
        - name: category_id
          in: query
          schema:
            type: integer
        - name: category_ids
          in: query
          schema:
            type: string
          description: 쉼표 문자열 또는 배열 형태로 전달합니다.
        - name: tag_id
          in: query
          schema:
            type: integer
        - name: tag_ids
          in: query
          schema:
            type: string
          description: 쉼표 문자열 또는 배열 형태로 전달합니다.
      responses:
        "200":
          description: 상품 목록
    post:
      summary: 상품 생성
      description: 이 경로는 서버용 /api/public/v1/products에서만 사용합니다.
      servers:
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - ServerPrivateKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title, category_id, featured_image]
              properties:
                title:
                  type: string
                category_id:
                  type: integer
                featured_image:
                  type: string
                tag_ids:
                  type: array
                  items:
                    type: integer
                  description: 현재 상품당 1개까지 선택 가능합니다.
      responses:
        "200":
          description: 상품 생성 결과
  /products/{productId}:
    get:
      summary: 상품 상세 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 상품 상세
    put:
      summary: 상품 수정
      description: 서버용 비공개 키 전용 API입니다.
      servers:
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - ServerPrivateKey: []
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                category_id:
                  type: integer
                tag_ids:
                  type: array
                  items:
                    type: integer
                  description: 빈 배열을 보내면 태그를 제거합니다.
      responses:
        "200":
          description: 상품 수정 결과
  /contents:
    get:
      summary: 콘텐츠 목록 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: page
          in: query
          schema:
            type: integer
        - name: limit
          in: query
          schema:
            type: integer
        - name: search
          in: query
          schema:
            type: string
        - name: content_type
          in: query
          schema:
            type: string
            enum: [vod, live, offline, digital_content]
        - name: category_id
          in: query
          schema:
            type: integer
        - name: category_ids
          in: query
          schema:
            type: string
          description: 쉼표 문자열 또는 배열 형태로 전달합니다.
        - name: tag_id
          in: query
          schema:
            type: integer
        - name: tag_ids
          in: query
          schema:
            type: string
          description: 쉼표 문자열 또는 배열 형태로 전달합니다.
      responses:
        "200":
          description: 콘텐츠 목록
    post:
      summary: 콘텐츠 생성
      description: 이 경로는 서버용 /api/public/v1/contents에서만 사용합니다.
      servers:
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - ServerPrivateKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [content_type, title, description_html, category_ids, featured_image]
              properties:
                content_type:
                  type: string
                  enum: [vod, live, offline, digital_content]
                title:
                  type: string
                description_html:
                  type: string
                category_ids:
                  type: array
                  items:
                    type: integer
                tag_ids:
                  type: array
                  items:
                    type: integer
                  description: 현재 콘텐츠당 1개까지 선택 가능합니다.
      responses:
        "200":
          description: 콘텐츠 생성 결과
  /contents/{contentId}:
    get:
      summary: 콘텐츠 상세 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: contentId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 콘텐츠 상세
    put:
      summary: 콘텐츠 수정
      description: 서버용 비공개 키 전용 API입니다.
      servers:
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - ServerPrivateKey: []
      parameters:
        - name: contentId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                category_ids:
                  type: array
                  items:
                    type: integer
                tag_ids:
                  type: array
                  items:
                    type: integer
                  description: 빈 배열을 보내면 태그를 제거합니다.
      responses:
        "200":
          description: 콘텐츠 수정 결과
  /contents/{contentId}/summary:
    get:
      summary: 콘텐츠 요약 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: contentId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 콘텐츠 요약
  /contents/{contentId}/description:
    get:
      summary: 콘텐츠 설명 조회
      security:
        - StorefrontKey: []
      parameters:
        - name: contentId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 콘텐츠 설명
  /contents/bulk:
    post:
      summary: 여러 콘텐츠 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 콘텐츠 목록
  /contents/cart-preview:
    post:
      summary: 장바구니용 콘텐츠 미리보기
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 장바구니 미리보기
  /content-categories:
    get:
      summary: 콘텐츠 카테고리 전체 조회
      description: 스토어프론트와 서버용 비공개 API에서 모두 사용할 수 있습니다.
      servers:
        - url: https://{host}/api/storefront/v1
          variables:
            host:
              default: your-site.runmoa.com
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - StorefrontKey: []
        - ServerPrivateKey: []
      responses:
        "200":
          description: 콘텐츠 카테고리 목록
  /content-categories/search:
    get:
      summary: 콘텐츠 카테고리 검색
      description: 스토어프론트와 서버용 비공개 API에서 모두 사용할 수 있습니다.
      servers:
        - url: https://{host}/api/storefront/v1
          variables:
            host:
              default: your-site.runmoa.com
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - StorefrontKey: []
        - ServerPrivateKey: []
      parameters:
        - name: query
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: 콘텐츠 카테고리 검색 결과
  /product-categories:
    get:
      summary: 상품 카테고리 전체 조회
      description: 스토어프론트와 서버용 비공개 API에서 모두 사용할 수 있습니다.
      servers:
        - url: https://{host}/api/storefront/v1
          variables:
            host:
              default: your-site.runmoa.com
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - StorefrontKey: []
        - ServerPrivateKey: []
      responses:
        "200":
          description: 상품 카테고리 목록
  /product-categories/search:
    get:
      summary: 상품 카테고리 검색
      description: 스토어프론트와 서버용 비공개 API에서 모두 사용할 수 있습니다.
      servers:
        - url: https://{host}/api/storefront/v1
          variables:
            host:
              default: your-site.runmoa.com
        - url: https://{host}/api/public/v1
          variables:
            host:
              default: your-site.runmoa.com
      security:
        - StorefrontKey: []
        - ServerPrivateKey: []
      parameters:
        - name: query
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: 상품 카테고리 검색 결과
  /product-tags:
    get:
      summary: 상품 태그 조회
      description: 노출 상품에서 사용 중인 태그를 조회합니다.
      security:
        - StorefrontKey: []
      parameters:
        - name: item_ids
          in: query
          required: false
          schema:
            type: string
          description: 특정 상품 ID 목록으로 제한할 때 쉼표 문자열로 전달합니다.
      responses:
        "200":
          description: 상품 태그 목록
  /content-tags:
    get:
      summary: 콘텐츠 태그 조회
      description: 노출 콘텐츠에서 사용 중인 태그를 조회합니다.
      security:
        - StorefrontKey: []
      parameters:
        - name: item_ids
          in: query
          required: false
          schema:
            type: string
          description: 특정 콘텐츠 ID 목록으로 제한할 때 쉼표 문자열로 전달합니다.
      responses:
        "200":
          description: 콘텐츠 태그 목록
  /guest-cart:
    get:
      summary: 게스트 장바구니 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 장바구니
    post:
      summary: 게스트 장바구니 추가
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 추가 결과
    delete:
      summary: 게스트 장바구니 비우기
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 삭제 결과
  /guest-cart/quantity:
    put:
      summary: 게스트 장바구니 수량 변경
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 변경 결과
  /guest-cart/{itemId}:
    delete:
      summary: 게스트 장바구니 항목 삭제
      security:
        - StorefrontKey: []
      parameters:
        - name: itemId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 삭제 결과
  /cart:
    get:
      summary: 로그인 장바구니 조회
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 장바구니
    post:
      summary: 로그인 장바구니 추가
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 추가 결과
    delete:
      summary: 로그인 장바구니 비우기
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 삭제 결과
  /cart/quantity:
    put:
      summary: 로그인 장바구니 수량 변경
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 변경 결과
  /cart/{itemId}:
    delete:
      summary: 로그인 장바구니 항목 삭제
      security:
        - StorefrontKey: []
          UserBearer: []
      parameters:
        - name: itemId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 삭제 결과
  /cart/merge-guest:
    post:
      summary: 게스트 장바구니 병합
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 병합 결과
  /checkout/metadata:
    get:
      summary: 결제 화면 메타데이터 조회
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 결제 메타데이터
  /orders:
    post:
      summary: 주문 생성
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 주문 생성 결과
  /me/orders:
    get:
      summary: 내 주문 목록
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 주문 목록
  /me/orders/{orderId}:
    get:
      summary: 내 주문 상세
      security:
        - StorefrontKey: []
          UserBearer: []
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 주문 상세
  /me:
    get:
      summary: 내 정보 조회
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 내 정보
  /me/access-context:
    get:
      summary: 사용자 접근 권한 컨텍스트 조회
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 접근 권한 컨텍스트
  /me/contents/{type}/{status}:
    get:
      summary: 내 콘텐츠 목록 조회
      security:
        - StorefrontKey: []
          UserBearer: []
      parameters:
        - name: type
          in: path
          required: true
          schema:
            type: string
        - name: status
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: 내 콘텐츠 목록
  /payments/initialize:
    post:
      summary: 결제 초기화
      description: PG별 URL을 직접 노출하지 않습니다. 사이트 결제 설정을 기준으로 서버가 처리합니다.
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 결제 초기화 결과
  /boards:
    get:
      summary: 게시판 목록
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 게시판 목록
  /boards/{boardId}:
    get:
      summary: 게시판 상세
      security:
        - StorefrontKey: []
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 게시판 상세
  /posts:
    get:
      summary: 게시글 목록
      security:
        - StorefrontKey: []
      responses:
        "200":
          description: 게시글 목록
    post:
      summary: 게시글 작성
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 작성 결과
  /posts/{postId}:
    get:
      summary: 게시글 상세
      security:
        - StorefrontKey: []
      parameters:
        - name: postId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: 게시글 상세
  /comments:
    post:
      summary: 댓글 작성
      security:
        - StorefrontKey: []
          UserBearer: []
      responses:
        "200":
          description: 작성 결과
