Files
Gnuboard7/plugins/_bundled/sirsoft-gdpr/docs/api/consent-log.md
T
HeuJung b10e89bef0 fix(core,board,ecommerce,page,gdpr,ckeditor5,kginicis,admin_basic,basic): 목록 조회·검증 계층 정비 및 감사 지적 전건 처리
목록 조회 성능 축(깊은 OFFSET·정렬·색인)과 그 검증 계층에서 계획서 전수검수와 3회에 걸친
감사가 지적한 항목을 처리했다. 세부 경위는 의 각 회차 문서에 있다.

검증 계층 — 컨트롤러가 base Request 를 직접 주입받던 확장 13곳을 전용 FormRequest 로 옮겼다.
옮기면서 기존 동작 계약은 그대로 두었다: 상한 초과 limit 을 거부하지 않고 상한까지 반환하던
공개 API, per_page 를 범위로 조정하던 관리자 목록, 미지원 period 를 year 로 해석하던 인기글
목록 모두 종전과 같은 응답을 낸다. 상한/폴백을 rules 로 승격시키면 200 이던 응답이 422 가
되어 기존 링크가 깨지므로, 규칙은 타입만 닫고 클램프·폴백은 접근자가 맡는다. period 는
접근자가 닫힌 집합만 반환해 캐시 키 공간도 함께 닫힌다.

ckeditor5 이미지 업로드만 ResponseHelper 봉투를 쓰지 않는다. 응답을 파싱하는 주체가 CDN 으로
로드되는 상위 CKEditor5 43.3.1 의 SimpleUploadAdapter 라 규약을 바꿀 수 없어, 각 응답 지점에
사유를 명시한 면제를 부착하고 근거를 API 문서에 남겼다.

하네스 — 룰 5개의 대상 경로 패턴이 매처와 맞지 않아 번들 확장 컨트롤러가 검사 대상에서
통째로 빠져 있었다. 패턴을 고치자 확장 위반 17건이 드러나 전건 처리했다. severity 오타가
요약 집계 양쪽에 안 잡혀 "0 error" 로 보고되던 문제도 런너 사전 검증으로 막았다.

정렬 게이트 대조 하네스는 관계 정렬 변형만 쓰는 저장소를 탐지하지 못한 채 통과시키고 있었다.
탐지·제외·인자 파싱을 함께 고치고 단위 테스트를 신설했다.
2026-08-02 15:29:29 +09:00

95 lines
5.1 KiB
Markdown

# Consent Log API 레퍼런스
> **소유**: plugin `sirsoft-gdpr` · **생성**: `php artisan api:docgen` (실측 기반). @generated 블록은 재생성 시 갱신되며, 사람이 작성한 설명은 보존됩니다.
---
## TL;DR (5초 요약)
```text
1. 이 문서는 실제 API 호출로 실측한 Consent Log 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
---
### GET /api/plugins/sirsoft-gdpr/admin/consent-log
<!-- @generated:start:api.plugins.sirsoft-gdpr.admin.consent-log.index -->
- **라우트명**: `api.plugins.sirsoft-gdpr.admin.consent-log.index`
- **컨트롤러**: `Plugins\Sirsoft\Gdpr\Http\Controllers\Admin\GdprAdminConsentLogController@index`
- **인증/권한**: `auth:sanctum` + `permission:sirsoft-gdpr.privacy.view`
**요청 파라미터**
_요청 파라미터 없음._
**요청 예시**
```http
GET /api/plugins/sirsoft-gdpr/admin/consent-log HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer {YOUR_TOKEN}
```
**응답 필드** (`data` 내부)
_목록 응답: `data.data[]` 배열 항목의 필드 + `data.pagination`._
| 필드 | 타입 | 실측 예시값 | 용도/설명 |
| --- | --- | --- | --- |
| id | integer | `83` | 기본 키 (내부 식별자) |
| user_id | integer | `130` | user 식별자 (연관 리소스 참조) |
| session_id | string | `c50916f6-58ee-42a6-a046-60a0c9ecfad2` | session 식별자 (연관 리소스 참조) |
| consent_key | string | `cookie_marketing` | 변경된 동의 항목 키 (쿠키 카테고리 키). 어떤 동의 항목의 부여/철회가 기록된 행인지 나타냅니다 |
| action | string | `revoked` | 이 이력 행의 변경 유형 (`granted`=동의 부여, `revoked`=철회, `rejected`=명시적 거부). `rejected`는 배너에서 "동의하지 않고 계속하기"로 선택형 카테고리를 거부한 행위이며 관리자 화면에 amber 배지로 표시됩니다. Art.7(1) 입증 트레일의 행위 구분입니다 |
| source | string | `banner` | 동의 변경이 발생한 경로. 허용 어휘는 `ConsentSource` enum 5종 — `banner`=쿠키 배너, `preference_center`=환경설정 센터, `register`=회원가입, `mypage`=마이페이지, `mypage_renew_all`=정책 개정 후 마이페이지 일괄 재동의(서버 자체 기록) |
| policy_version | string | `10` | 변경 시점의 정책 버전 문자열. 해당 동의가 어느 정책 버전 기준으로 표명되었는지 기록해 정책 갱신 후 재동의 판정과 감사에 사용됩니다 |
| categories | object | `{"cookie_analytics":false,"cookie_marketing":false,"cooki…` | 변경 시점 전체 카테고리별 동의 여부 스냅샷 (키→boolean). MySQL JSON 컬럼이라 키가 알파벳 순으로 정규화 저장됩니다 |
| categories_snapshot | array | `[{"key":"cookie_necessary","label_key":"sirsoft-gdpr.cons…` | `categories` 객체를 관리자 화면 iteration 친화 배열(`{key, label_key, granted}`)로 변환한 것. 필수→분석→마케팅 UX 위계 순으로 재정렬되며 `label_key`는 프론트가 다국어로 해석합니다 |
| ip_address | string | `127.0.0.1` | 요청/행위가 발생한 IP 주소 |
| user_agent | string | `Mozilla/5.0 (Windows NT 10.0; Win64; …` | 동의 변경 요청의 User-Agent 문자열. DPO 감사 시 동의 표명 단말/브라우저를 식별하는 용도이며 회원 삭제 시 NULL로 익명화됩니다 |
| created_at | string | `2026-07-03 00:24:27` | 생성 일시 |
| user | object | `{"id":130,"uuid":"a21d03b4-df0b-4aa6-ab7a-f51143f6375a","…` | 동의 주체 회원 정보(id/uuid/name/email). 관계가 로드된 경우에만 포함되며 게스트 이력이거나 삭제로 익명화된 경우 null입니다 |
**응답 예시**
```http
HTTP/1.1 200
```
```json
{
"success": true,
"message": "messages.success",
"data": {
"data": [],
"pagination": {
"current_page": 1,
"last_page": 1,
"per_page": 25,
"total": 0,
"from": null,
"to": null
}
}
}
```
**에러 응답**
| 상태코드 | 의미 | 발생 조건 |
| --- | --- | --- |
| 401 | Unauthenticated | 유효한 Bearer 토큰이 없거나 만료된 경우 |
| 403 | Forbidden | 요구 권한(`sirsoft-gdpr.privacy.view`)이 없는 경우 |
<!-- @generated:end -->
**설명** 관리자 감사 화면에서 `gdpr_user_consent_histories` 테이블의 동의 로그를 페이지네이션으로 조회합니다. `auth:sanctum`과 `sirsoft-gdpr.privacy.view` 권한이 필요합니다. `email`, `session_id`, `consent_keys[]`, `actions[]`(granted|revoked|rejected — `ConsentAction` enum 전 케이스), `sources[]`(banner|preference_center|register|mypage|mypage_renew_all — `ConsentSource` enum 전 케이스), `per_page`(1~100, 기본 20) 쿼리 필터를 지원합니다. DPO 감사 용도로 IP 주소와 User-Agent까지 노출되는 조회 전용 엔드포인트입니다.