Files
Gnuboard7/plugins/_bundled/sirsoft-marketing/docs/api/channels.md
T
HeuJung 6c8381f164 fix(core,board,ecommerce,plugins): API 문서 미채움 마커 전수 채움 + 미해석 lang 키 정정 + IDV 조회 시도횟수 비노출
이슈 본연: API 레퍼런스의 미채움 마커 5종(실측 제외/TODO/필드 없음/대표 에러 없음)
1,194건을 코드에서 읽어 전수 채우고(0건), api:docgen 재생성이 사람이 채운 내용을
손실·열화시키던 멱등성 결함 4종(CRLF, 표 파이프 이스케이프, 에러 서술 보존, 중복
라우트명 키)을 근본 수정. --check 를 실측 제외와 드리프트가 구분되도록 재정의.
ParameterDescriber/ResourceFieldDescriber 에 leaf 폴백·SEO 스코프·공통 사전 확장.

파생 결함(문서 실측 중 발견): ResponseHelper 기본 메시지 키 6종이 존재하지 않는
messages.* 를 가리켜 응답 message 가 번역문 대신 키 문자열로 노출되던 문제를 common.*
으로 정정하고, 코어 7 + gdpr/marketing/pay_kginicis/verification/ecommerce 확장의
호출부와 누락 lang 키(게시판 10키 + 이커머스 category_images 4키 포함)를 ko/en/ja
전수 정정. 중복 그룹 키 2건은 기존 키로 호출부 통합.

보안: GET /api/identity/challenges/{id} 는 권한 가드 없는 공개 폴링 엔드포인트인데
Service::getStatus 가 attempts/max_attempts 를 응답에 담아 남은 시도 횟수를 추론할 수
있었다. 두 필드를 제거하고, 챌린지 화면(admin_basic/basic)의 서버 attempts 참조를
제거(남은 횟수 UI 는 query fallback + verify 실패 시 로컬 증가로 유지).

부수 정리(변경셋에 들어온 board 컨트롤러의 audit 사전 결함): FormRequest 4개 신설로
base Request 주입 제거, CommentController 의 Board 직접 호출을 BoardService 위임으로
전환, PHPDoc @return 보강. board 스위트에서 발견한 stale test 3건(seed SSoT 불일치,
admin 계정 user 역할 누락)도 같은 세션에서 정정.

버전 정렬(공개 release 기준): 코어 7.0.3→7.0.4, sirsoft-board 1.0.1→1.0.2,
verification_kginicis 1.0.0→1.0.1, admin_basic 1.0.1→1.0.4.
2026-08-06 14:16:40 +09:00

5.7 KiB

Channels API 레퍼런스

소유: plugin sirsoft-marketing · 생성: php artisan api:docgen (실측 기반). @generated 블록은 재생성 시 갱신되며, 사람이 작성한 설명은 보존됩니다.


TL;DR (5초 요약)

1. 이 문서는 실제 API 호출로 실측한 Channels 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다

PUT /api/plugins/sirsoft-marketing/admin/channels

  • 라우트명: api.plugins.sirsoft-marketing.admin.channels.update
  • 컨트롤러: Plugins\Sirsoft\Marketing\Http\Controllers\MarketingAdminController@updateChannels
  • 인증/권한: auth:sanctum

요청 파라미터

요청 파라미터 없음.

요청 예시

PUT /api/plugins/sirsoft-marketing/admin/channels HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer {YOUR_TOKEN}

응답 필드 (data 내부)

단건 응답: data 객체의 필드. data.channels 는 저장 후 확정된 채널 배열(시스템 채널 병합 결과)이며, 요청 body 의 channels 와 동일한 구조를 그대로 되돌려준다.

필드 타입 실측 예시값 용도/설명
channels array [{...}] 저장된 최종 채널 목록 (누락된 시스템 채널이 앞에 병합됨)
channels[].key string email_subscription 채널 식별자 (소문자·숫자·밑줄)
channels[].label object {"ko":"광고성 이메일 수신","en":"Email Marketing"} 로케일별 채널 라벨
channels[].label_key string sirsoft-marketing::channels.email_subscription.label 시스템 채널이 병합될 때만 포함되는 언어팩 라벨 키
channels[].page_slug string | null "" 연결 약관 페이지 slug (없으면 빈 문자열/null)
channels[].enabled boolean true 채널 노출 여부
channels[].is_system boolean true 시스템 채널 여부 (삭제·플래그 변경 불가)

응답 예시

{
    "success": true,
    "message": "채널이 저장되었습니다.",
    "data": {
        "channels": [
            {
                "key": "email_subscription",
                "label_key": "sirsoft-marketing::channels.email_subscription.label",
                "label": {
                    "ko": "광고성 이메일 수신",
                    "en": "Email Marketing"
                },
                "page_slug": "",
                "enabled": true,
                "is_system": true
            }
        ]
    }
}

에러 응답

상태코드 의미 발생 조건
401 Unauthenticated 유효한 Bearer 토큰이 없거나 만료된 경우
403 Forbidden 관리자 권한이 없는 사용자가 호출한 경우 (AdminBaseController)
422 동의 이력 존재 삭제 대상 채널에 동의한 회원이 있는 경우 — "채널(:key)에 동의한 회원이 :count명 있어 삭제할 수 없습니다."

설명

관리자 환경설정 화면에서 마케팅 동의 채널 목록 전체를 한 번에 저장하는 엔드포인트다. 컨트롤러가 AdminBaseController 를 상속하므로 실제 인증은 auth:sanctum 에 더해 관리자(admin) 권한을 요구한다(생성기 표기는 auth:sanctum 만 노출). 제출된 배열이 곧 새 상태가 되며, 개별 채널 추가/수정 엔드포인트는 없다(전량 교체 방식).

요청 파라미터는 생성기가 배열 중첩 규칙(channels.*)을 평면화하지 못해 위 표에 "없음"으로 표기되나, 실제 ChannelUpdateRequest 는 다음 body 를 요구한다:

이름 위치 타입 필수 허용값 용도
channels body array 예 최대 10개 저장할 채널 정의 배열(전체 교체)
channels.*.key body string 예 ^[a-z0-9_]+$ 채널 식별자(소문자·숫자·밑줄)
channels.*.label body object 예 로케일 맵, 각 값 최대 50자 다국어 라벨(LocaleRequiredTranslatable)
channels.*.page_slug body string 아니오 최대 100자 연결 약관 페이지 slug
channels.*.enabled body boolean 예 — 노출 여부
channels.*.is_system body boolean 예 — 시스템 채널 플래그
  • 시스템 채널 보호: is_system=true 채널은 제출 목록에서 빠져도 서버가 기본 정의를 다시 앞에 끼워 넣어 항상 유지된다. is_system 을 true→false 로 위변조하거나 시스템 채널을 누락시키면 검증 오류(422).
  • 동의 이력 보호: 이미 사용자 동의가 존재하는 채널을 목록에서 제거하려 하면 MarketingConsentService::countConsentedByKey() 가 0 이 아니어서 422 로 거부된다(개인정보 이력 보존).
  • key 중복 금지: 같은 key 가 둘 이상이면 422.
  • 성공 시 저장된 최종 channels 배열(시스템 채널 병합 포함)을 data.channels 로 되돌려준다.

응답 예시 (성공)

{
  "success": true,
  "data": {
    "channels": [
      { "key": "email_subscription", "label": { "ko": "광고성 이메일 수신", "en": "Email Marketing" }, "page_slug": "", "enabled": true, "is_system": true }
    ]
  },
  "message": "채널이 저장되었습니다.",
  "error": null
}