비즈뿌리오 알림톡 템플릿을 콘솔 위임(발송 전 실시간 조회) 방식에서 시스템 내 작성(draft) → 검수 신청(requested) → 승인(approved) 라이프사이클로 개편한다. 발송 판정의 SSoT 를 DB(bizppurio_templates)로 옮기고 발송 전 실시간 조회를 폐지. - 알림↔템플릿 바인딩 모델(notification_bindings) 제거, 알림 1건당 템플릿 1행으로 대체 - 검수 신청: template_code 자체 채번(codeCheck 재시도) → kapi add/update → request - 상태 동기화: 30분 스케줄러 + 수동 새로고침, 승인 전이 시 content 를 approved_content 로 동결 - SMS 본문 언어별 입력 복원(수신자 로케일 발송), SMS 단독 선택 시 알림톡 미발송 - 3면(코어/게시판/이커머스) '비즈뿌리오' 통합 탭 + 플러그인 '알림 템플릿 관리' 화면 - 중복 검수 신청은 서버 원자 선점(claimForInspection 조건부 UPDATE)으로 차단 - admin_basic 1.0.6 / board 1.0.5 / ecommerce 1.1.2: 채널 서브탭 통합 탭 선언(tab_channels) 지원 - 검증: 계획서 대비 5라운드 전수검증, §6.3 실측 매트릭스 Playwright 19 고정, PHPUnit 421 / Vitest 228 green, audit 0 error
12 KiB
Dispatch Results API 레퍼런스
소유: plugin
sirsoft-message_bizppurio· 생성:php artisan api:docgen(실측 기반). @generated 블록은 재생성 시 갱신되며, 사람이 작성한 설명은 보존됩니다.
TL;DR (5초 요약)
1. 이 문서는 실제 API 호출로 실측한 Dispatch Results 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
POST /api/plugins/sirsoft-message_bizppurio/admin/dispatch-results/lookup
- 라우트명:
api.plugins.sirsoft-message_bizppurio.admin.dispatch-results.lookup - 컨트롤러:
Plugins\Sirsoft\MessageBizppurio\Controllers\Admin\DispatchResultController@lookup - 인증/권한:
auth:sanctum+permission:sirsoft-message_bizppurio.messaging.view
요청 파라미터
| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 |
|---|---|---|---|---|---|
| notification_log_ids | body | array | 아니오 | max 100 | notification log 식별자 배열 |
요청 예시
POST /api/plugins/sirsoft-message_bizppurio/admin/dispatch-results/lookup HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer {YOUR_TOKEN}
Content-Type: application/json
{
"notification_log_ids": [
"예시값"
]
}
응답 필드 (data 내부)
단건 응답: data 객체의 필드.
| 필드 | 타입 | 실측 예시값 | 용도/설명 |
|---|---|---|---|
| results | array | [] |
요청한 notification_log_ids 각각의 비즈뿌리오 발송 결과. 해당 알림 로그로 발송된 건이 없으면 빈 배열 |
응답 예시
HTTP/1.1 200
{
"success": true,
"message": "messages.success",
"data": {
"results": []
}
}
에러 응답
| 상태코드 | 의미 | 발생 조건 |
|---|---|---|
| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 |
| 403 | Forbidden | 요구 권한(sirsoft-message_bizppurio.messaging.view)이 없는 경우 |
| 422 | Unprocessable Entity | 요청 파라미터가 검증 규칙을 위반한 경우 (error.errors 에 필드별 메시지) |
설명
코어 "알림 발송 이력" 화면에 얹은 결과 컬럼(layout_extensions overlay)이 소비하는 조회 API 다.
현재 페이지에 표시된 코어 알림 로그 id 배열(notification_log_ids, 최대 100)을 넘기면, 그 로그에
연결된 비즈뿌리오 발송 결과를 로그 id 를 키로 하는 맵으로 한 번에 돌려준다(행마다 개별 호출하지
않아 N+1 을 피한다). 코어 알림 로그 테이블은 수정하지 않으며, 연결 표식은 비즈뿌리오 쪽
(bizppurio_dispatches.notification_log_id)에만 둔다.
매칭되지 않는 로그 id(메일·사이트내알림 등 비-비즈뿌리오 발송)는 결과 맵에서 제외된다 — 화면에서는 그 행의 결과 컬럼이 빈 셀이 된다. 결과에는 전화번호 등 민감정보를 포함하지 않는다(결과 컬럼은 상태· 사유만 표시).
응답 필드 (data.results — 키는 notification_log_id, 값은 결과 객체)
| 필드 | 타입 | 용도 |
|---|---|---|
| status | string|null | 발송 상태: sent / success / failed (DispatchStatus) |
| status_label | string|null | 로케일 상태 라벨 (예: "성공", "실패", "발송중") |
| result_code | string|null | 결과 코드 (발송응답 또는 webhook 리포트). 리포트 미수신 시 null |
| result_label | string|null | 사유 (코드) 표시 라벨 (예: "음영 지역 (4400)"). 코드 없으면 null |
| is_low_balance | boolean | 잔액 부족(9070 문자 / 7436 알림톡) 여부 |
| fallback_status | string|null | SMS 대체발송 결과 (webhook TELRES). 없으면 null |
| channel | string|null | 발송 채널: sms / lms / alimtalk |
| content | string|null | 실제 비즈뿌리오에 발송한 본문. 알림톡은 코어 notification_logs.body(대체발송용 코어 템플릿 값)와 달리 카카오 승인 템플릿의 실제 내용이므로, 화면은 이 값을 채널별로 구분해 별도 노출한다 |
응답 예시
{
"success": true,
"message": "성공",
"data": {
"results": {
"128": {
"status": "failed",
"status_label": "실패",
"result_code": "4400",
"result_label": "음영 지역 (4400)",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
}
}
}
}
GET /api/plugins/sirsoft-message_bizppurio/admin/dispatch-results/recent
- 라우트명:
api.plugins.sirsoft-message_bizppurio.admin.dispatch-results.recent - 컨트롤러:
Plugins\Sirsoft\MessageBizppurio\Controllers\Admin\DispatchResultController@recent - 인증/권한:
auth:sanctum+permission:sirsoft-message_bizppurio.messaging.view
요청 파라미터
요청 파라미터 없음.
요청 예시
GET /api/plugins/sirsoft-message_bizppurio/admin/dispatch-results/recent HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer {YOUR_TOKEN}
응답 필드 (data 내부)
단건 응답: data 객체의 필드.
| 필드 | 타입 | 실측 예시값 | 용도/설명 |
|---|---|---|---|
| results | object | {"21":{"status":"pending","status_label":"대기","result_cod… |
notification_log_id 를 키로 하는 결과 맵. 각 값은 status(pending/sent/failed) · status_label(현재 로케일 라벨) · result_code(비즈뿌리오 결과 코드) · 실패 사유를 담는다 |
응답 예시
HTTP/1.1 200
{
"success": true,
"message": "messages.success",
"data": {
"results": {
"21": {
"status": "pending",
"status_label": "대기",
"result_code": null,
"result_label": null,
"is_low_balance": false,
"fallback_status": null,
"channel": "alimtalk"
},
"20": {
"status": "success",
"status_label": "성공",
"result_code": "7000",
"result_label": "성공 (7000)",
"is_low_balance": false,
"fallback_status": null,
"channel": "alimtalk"
},
"19": {
"status": "failed",
"status_label": "실패",
"result_code": "7206",
"result_label": "검수되지 않은 템플릿 (7206)",
"is_low_balance": false,
"fallback_status": null,
"channel": "alimtalk"
},
"18": {
"status": "failed",
"status_label": "실패",
"result_code": "7436",
"result_label": "지갑 잔액 부족(알림톡) (7436)",
"is_low_balance": true,
"fallback_status": "실패",
"channel": "alimtalk"
},
"17": {
"status": "success",
"status_label": "성공",
"result_code": "7000",
"result_label": "성공 (7000)",
"is_low_balance": false,
"fallback_status": "성공",
"channel": "alimtalk"
},
"16": {
"status": "success",
"status_label": "성공",
"result_code": "7000",
"result_label": "성공 (7000)",
"is_low_balance": false,
"fallback_status": null,
"channel": "alimtalk"
},
"15": {
"status": "failed",
"status_label": "실패",
"result_code": "6603",
"result_label": "음영 지역 (6603)",
"is_low_balance": false,
"fallback_status": null,
"channel": "lms"
},
"14": {
"status": "success",
"status_label": "성공",
"result_code": "6600",
"result_label": "성공 (6600)",
"is_low_balance": false,
"fallback_status": null,
"channel": "lms"
},
"13": {
"status": "failed",
"status_label": "실패",
"result_code": "9999",
"result_label": "9999",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"12": {
"status": "failed",
"status_label": "실패",
"result_code": "9070",
"result_label": "잔액 부족(문자) (9070)",
"is_low_balance": true,
"fallback_status": null,
"channel": "sms"
},
"11": {
"status": "success",
"status_label": "성공",
"result_code": "4100",
"result_label": "성공 (4100)",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"10": {
"status": "pending",
"status_label": "대기",
"result_code": null,
"result_label": null,
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"9": {
"status": "sent",
"status_label": "발송중",
"result_code": null,
"result_label": null,
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"8": {
"status": "failed",
"status_label": "실패",
"result_code": "4410",
"result_label": "잘못된 번호 (4410)",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"7": {
"status": "failed",
"status_label": "실패",
"result_code": "4400",
"result_label": "음영 지역 (4400)",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
},
"6": {
"status": "success",
"status_label": "성공",
"result_code": "4100",
"result_label": "성공 (4100)",
"is_low_balance": false,
"fallback_status": null,
"channel": "sms"
}
}
}
}
에러 응답
| 상태코드 | 의미 | 발생 조건 |
|---|---|---|
| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 |
| 403 | Forbidden | 요구 권한(sirsoft-message_bizppurio.messaging.view)이 없는 경우 |
설명
알림 발송 이력 화면이 최근 발송 건의 비즈뿌리오 결과를 한 번에 받아 결과 컬럼에 주입할 때 사용한다.
lookup 이 지정한 로그 ID 만 조회하는 것과 달리, 이 엔드포인트는 최근 구간을 서버가 정해 돌려주므로
화면이 조회 대상을 미리 알 필요가 없다. 결과는 notification_log_id 를 키로 하는 맵이며,
비즈뿌리오로 발송되지 않은 알림은 키 자체가 없다 — 화면은 키 부재를 "해당 없음" 으로 그린다.