Files
Gnuboard7/plugins/_bundled/sirsoft-marketing/docs/api/user-consent-injection.md
T
HeuJung 70452745c4 feat(api-docs): API 레퍼런스 문서 전면화 — 추출 파이프라인·전 대상 문서화·audit 강제
코드에만 존재하던 REST API 계약(약 663 엔드포인트)을 코어/확장 책임별로
분리된 마크다운 레퍼런스로 전면 문서화한다. 674개 규모에서 수기 문서는
반드시 drift 하므로 "코드 추출 → 스캐폴딩 → 사람이 서술 채움 → 하네스가
커버리지 강제" 하이브리드로 구성했다.

추출 파이프라인 (app/Support/ApiDoc):
- ApiRouteInventory / FormRequestIntrospector / ApiEndpointProbe(실측 HTTP) /
 ResponseSchemaInferrer / ApiDocScaffolder / ColumnCommentResolver /
 ResourceFieldDescriber / ParameterDescriber
- api:docgen 커맨드(--scope/--seed/--check/--dry-run/--base-url/--user) +
 응답/파라미터 in-place 백필 커맨드 2종(재생성 없이 TODO 셀만 치환, 멱등)
- ApiDocSampleSeeder 계약 + 코어/확장 시더로 실측용 완전 샘플 멱등 생성

문서화 (실측 기반, GET read-only 실호출):
- 코어 291엔드포인트 35파일(docs/backend/api) + 규정 docs/backend/api-documentation.md
- 확장: ecommerce(231)·board(80)·page(17)·hello_module(2)·pay_kginicis(22)·
 gdpr(15)·ckeditor5(2)·marketing(2)·verification_kginicis(1)
- 표준 4구성(헤더·요청 파라미터·응답 필드·에러 표) + 엔드포인트 용도 서술
- 파라미터 용도·응답 필드 설명 셀 전수 채움(도메인 지식 수기)

하네스:
- audit 룰 api-doc-coverage — API 표면(라우트/컨트롤러/FormRequest/Resource)
 변경 시 대응 문서 미동반이면 차단. 전 대상 문서 완비로 error 승격
- file-rules 리마인더(컨트롤러/라우트 편집 시), coverage.json, dev-dashboard 카드
- docs/backend/routing.md 확장 공개 API URL 스킴 정정(/api/modules|plugins/{id})
- /AGENTS.md/docs-index 동기
2026-07-08 18:22:33 +09:00

6.3 KiB
Raw Blame History

코어 User 응답 마케팅 동의 필드 주입 (Hook Injection)

소유: plugin sirsoft-marketing · 이 문서는 api:docgen 생성 대상이 아닌 훅 주입 계약 레퍼런스다(플러그인이 코어 응답에 필드를 주입하므로 라우트 단위 문서로 표현되지 않는다). 코어 API 문서(docs/backend/api/users.md, me.md, profile.md)의 응답 필드 표에서 "확장 소유"로 표기된 *_consent/notify_*/{channel}_* 필드의 실제 계약이 여기에 있다.


TL;DR (5초 요약)

1. sirsoft-marketing 은 core.user.filter_resource_data 훅으로 코어 User 응답에 마케팅 동의 필드를 병합한다
2. 주입 대상: /me, /auth/user, /admin/users/{user}, 프로필 등 User 리소스를 반환하는 모든 코어 엔드포인트
3. 주입 필드는 활성 채널·법적 항목·마스터 키에 따라 동적 — 고정 스키마가 아니다
4. 각 동의 항목마다 상태({key})·시각({key}_at)·활성화 플래그({key}_enabled)·약관 slug 3종을 함께 내린다
5. 이 필드들이 코어 문서에서 TODO 로 남은 이유: 코어가 아니라 이 플러그인이 소유하기 때문

왜 이 문서가 필요한가

코어 UserResource 등 User 계열 리소스는 core.user.filter_resource_data 필터 훅을 발화한다. sirsoft-marketing 플러그인의 MarketingConsentListener::filterResourceData() 가 이 훅을 구독해 코어 User 응답 data 에 마케팅 동의 관련 필드를 병합한다. 따라서 docs/backend/api/ 의 코어 User 문서에 나타나는 marketing_consent, third_party_consent_at, email_subscription_enabled, channels, consent_histories 같은 필드는 코어 코드에는 없고 이 플러그인이 런타임에 주입한 것이다.

코어 문서 생성기(api:docgen)는 정적 리플렉션으로 코어 Resource toArray() 만 읽으므로 이 필드들을 설명하지 못하고 TODO 로 남긴다. 그 설명의 SSoT 가 이 문서다.

주입 지점

core.user.filter_resource_data 훅을 발화하는 모든 코어 엔드포인트에서 주입된다. 대표적으로:

엔드포인트 문서
GET /api/me docs/backend/api/me.md
GET /api/auth/user, GET /api/user/auth/user docs/backend/api/auth.md
GET /api/admin/users/{user} docs/backend/api/users.md
프로필 조회/수정 응답 docs/backend/api/profile.md

주입 필드 계약

주입 필드 집합은 활성 채널 목록 + 법적 필수 항목 + 마스터 키에 따라 동적으로 결정된다. 고정 스키마가 아니므로 아래는 필드 패턴으로 기술한다.

동의 상태 필드 (동의 키별 2개)

동의 키 집합 = 활성 채널 키(channels JSON 의 enabled 채널) ∪ 마스터 키 marketing_consent ∪ 활성화된 법적 키(third_party_consent, info_disclosure 중 *_enabled 인 것).

필드 타입 용도/설명
{consent_key} boolean 해당 항목에 동의했는지. 동의 레코드 없으면 false
{consent_key}_at string|null 동의 시각(ISO 8601). 미동의면 null
  • marketing_consent (마스터 키): 마케팅 채널 전체 동의/철회를 제어하는 상위 키.
  • third_party_consent, info_disclosure: 법적 필수 동의 항목(고정 키, 활성화 시에만 주입).
  • 그 외 키는 관리자가 정의한 동적 채널 키(예: email_subscription, sms_subscription).

활성화·약관 플래그 필드 (프론트 조건부 렌더링용)

마스터·법적·채널 각각에 대해 3종 플래그를 내린다. 값 규칙은 공개 GET /settings 응답과 동일하다.

필드 패턴 타입 용도/설명
marketing_consent_enabled boolean 마케팅 전체 동의 UI 노출 여부(기본 true)
marketing_consent_terms_slug string|null 마케팅 약관 slug(미설정 null)
marketing_consent_terms_slug_set boolean 마케팅 약관 존재 여부
third_party_consent_enabled / _terms_slug / _terms_slug_set boolean/string·null/boolean 제3자 제공 동의 항목 플래그
info_disclosure_enabled / _terms_slug / _terms_slug_set boolean/string·null/boolean 정보 이용 안내 동의 항목 플래그
{channel_key}_enabled / _terms_slug / _terms_slug_set boolean/string·null/boolean 동적 채널별 노출·약관 플래그(모든 채널에 대해, 활성 여부 무관)

약관 slug 은 *_terms_slug(값)와 *_terms_slug_set(존재 플래그)을 함께 내린다. 프론트는 링크 표시를 *_terms_slug_set 으로 판정한다. 공개 settings.md 계약과 동일하다.

컬렉션 필드

필드 타입 용도/설명
channels array 관리자 정의 전체 채널 목록(iteration 렌더링용). 원소: key, 현재 로케일 label, enabled, terms_slug, terms_slug_set
consent_histories array 이 사용자의 동의 변경 이력. 원소: channel_key, action, source(register/admin/profile), created_at

주의사항

  • 책임 분리: 이 필드들의 값 규칙·존재 여부는 전적으로 sirsoft-marketing 이 결정한다. 플러그인을 비활성화하면 코어 User 응답에서 이 필드들이 사라진다. 코어 문서가 이들을 TODO 로 남긴 것은 오류가 아니라 책임 분리의 결과다.
  • 동적 스키마: 채널 추가/삭제(PUT /admin/channels)나 법적 항목 활성화 설정에 따라 주입 필드 집합이 바뀐다. 소비처는 고정 키 목록을 가정하지 말고 channels 배열을 순회하는 것을 권장한다.
  • 쓰기 경로: 이 필드들은 조회 시 주입되지만, 저장은 회원가입(agree_{key})·사용자 생성/수정 ({key}) 요청 필드를 같은 리스너가 validation rule 훅으로 추가하고 action 훅에서 별도 저장한다. User 테이블 컬럼이 아니라 별도 marketing_consents EAV 테이블에 보관된다.

관련

  • settings.md — 비로그인 공개 설정(동일한 *_terms_slug_set·channels 계약)
  • channels.md — 채널 목록 저장(동적 채널 키의 출처)
  • docs/backend/api/users.md, me.md, profile.md, auth.md — 주입 대상 코어 문서
  • docs/extension/hooks.md — Filter 훅(core.user.filter_resource_data) 계약