S1 파일럿 3종(sirsoft-board · sirsoft-gdpr · sirsoft-admin_basic)에 이어
결제·본인인증 동형군 6종의 AGENTS.md · README.md · docs/ 5문서를 집필했다.
확장을 고치려는 쪽이 매번 src/ 를 훑어 구조를 재발견하지 않도록, 설계 의도와
확장점(발행·구독 훅)·수정 시 동반 의무·금지 패턴을 코드 근거로 서술했다.
생성기(ExtensionDocScaffolder)에서 표를 무의미하게 만들던 세 결함을 함께 고쳤다.
getLayoutExtensions 기본 구현이 돌려주는 절대경로가 파일 목록과 중복돼 로컬
머신 경로가 커밋 문서에 실리던 문제, getNotificationDefinitions 를 'key'/'event'
로 읽어 모든 행이 '-' 로 찍히던 문제, getSettingsLayout 절대경로가 정규화 없이
노출되던 문제다. 셋 다 예외를 남기지 않고 표만 조용히 망가뜨리므로
ExtensionDocContractTest 에 각각의 되돌림 red 를 확인한 단언을 두었다.
템플릿의 extensions/{id}/ 는 모듈·플러그인의 발행과 반대 방향(오버라이드)이라
별도 블록(template-overrides)으로 분리했다.
sirsoft-admin_basic 의 컴포넌트·핸들러·레이아웃 문서를 코어 docs/ 에서 그 템플릿
소유로 이관하고, 남은 참조 6축을 재는 가드를 추가했다. 이관 후 남은 옛 경로는
오류가 아니라 헛걸음으로만 나타나 드러나지 않는다. 의 상대 링크가
한 단계 얕아 공유 docs/ 대신 를 가리키던 문제도 함께 고쳤다.
README 상단의 확장명 이미지 배지를 평문 H1 로 바꿨다( 지시 2026-08-31).
루트 README.md · README.ko.md 도 같은 기준을 적용했다. 정보 배지는 유지한다.
sirsoft-gdpr: 회원탈퇴로 자동 철회된 동의가 관리자 동의 이력 화면의 출처 필터로
걸러지지 않던 문제를 고쳤다. Repository 가 'withdraw' 리터럴을 직접 UPDATE 에
싣는데 그 값이 ConsentSource enum 에 없어, 화면 필터 옵션·라벨 어느 쪽에도
도달하지 못했다. 어휘를 enum 단일 출처로 모으고 ko·en·ja 라벨과 필터 옵션을
함께 채웠으며, 어휘 대조 테스트의 모집단에 Repository 를 편입했다.
329 lines
19 KiB
JSON
329 lines
19 KiB
JSON
{
|
|
"editor": {
|
|
"data_source": {
|
|
"gdprConsentLog": "Consent Log",
|
|
"gdprMeConsents": "My Consents",
|
|
"gdprMyConsent": "My Consent",
|
|
"gdprMyConsents": "My Consents",
|
|
"gdprPolicyVersionCurrent": "Current Policy Version",
|
|
"gdprPolicyVersionHistory": "Policy Version History",
|
|
"gdprPolicyVersionSnapshot": "Policy Version Snapshot",
|
|
"gdprPublicSettings": "GDPR Public Settings",
|
|
"gdprSettings": "GDPR Settings"
|
|
}
|
|
},
|
|
"consent": {
|
|
"granted": "Consent has been saved.",
|
|
"granted_again": "Consent has been renewed.",
|
|
"rejected_saved": "Continuing without consent. Optional items will not be used.",
|
|
"revoked": "Consent has been revoked.",
|
|
"renew_all_success": "{renewed} active consent item(s) renewed to the new policy version.",
|
|
"granting": "Granting...",
|
|
"revoking": "Revoking...",
|
|
"renewing": "Renewing...",
|
|
"already_same_state": "Already in the same state.",
|
|
"required_cannot_revoke": "Required consent cannot be revoked.",
|
|
"invalid_key": "Invalid consent key.",
|
|
"category_cookie_necessary": "Strictly Necessary",
|
|
"category_cookie_functional": "Functional",
|
|
"category_cookie_analytics": "Analytics",
|
|
"category_cookie_marketing": "Marketing"
|
|
},
|
|
"blocked_domains": {
|
|
"invalid_format": "Invalid domain format. (FQDN only; *.example.com wildcard supported)",
|
|
"invalid_format_functional": "Functional — Invalid domain format. (FQDN only; *.example.com wildcard supported)",
|
|
"invalid_format_analytics": "Analytics — Invalid domain format. (FQDN only; *.example.com wildcard supported)",
|
|
"invalid_format_marketing": "Marketing — Invalid domain format. (FQDN only; *.example.com wildcard supported)",
|
|
"too_long": "Domain cannot exceed 253 characters.",
|
|
"too_long_functional": "Functional — Domain cannot exceed 253 characters.",
|
|
"too_long_analytics": "Analytics — Domain cannot exceed 253 characters.",
|
|
"too_long_marketing": "Marketing — Domain cannot exceed 253 characters.",
|
|
"must_be_array": "Each category must be an array of domain strings."
|
|
},
|
|
"settings": {
|
|
"saved": "Settings have been saved.",
|
|
"title": "GDPR Settings",
|
|
"description": "Operators control the cookie consent banner and the MyPage privacy card.",
|
|
"section": {
|
|
"operator": "Operator / Privacy Policy",
|
|
"operator_desc": "Register the operator name, data storage location, and privacy policy page slug shown in the cookie banner and policy page.",
|
|
"cookie_banner": "Cookie Consent Banner",
|
|
"cookie_banner_desc": "Configure visibility, position, categories, and policy version of the cookie consent banner — all in one place.",
|
|
"cookie_banner_settings": "Banner Display Settings",
|
|
"cookie_categories": "Cookie Categories",
|
|
"cookie_policy_version": "Cookie Policy Version",
|
|
"auto_blocking": "Auto-blocking Policy",
|
|
"auto_blocking_desc": "When the cookie banner is shown, external tracking resources matching the blocked-domain lists below are auto-blocked until the user consents."
|
|
},
|
|
"nav": {
|
|
"operator": "Operator",
|
|
"cookie_banner": "Cookie Banner",
|
|
"auto_blocking_policy": "Auto-blocking Policy"
|
|
},
|
|
"status": {
|
|
"enabled": "Enabled",
|
|
"disabled": "Disabled",
|
|
"visible": "Visible",
|
|
"hidden": "Hidden"
|
|
},
|
|
"fields": {
|
|
"cookie_policy_version": {
|
|
"label": "Policy Version",
|
|
"hint": "When the policy body, category semantics, or operator/retention information changes, click \"+ Publish new version\". On publish, all members will re-consent on their next visit."
|
|
},
|
|
"privacy_policy_slug": {
|
|
"label": "Privacy Policy Page Slug",
|
|
"hint": "Slug of the privacy policy page registered in the Page plugin. If empty, the policy link in the cookie banner is hidden.",
|
|
"placeholder": "e.g., privacy-policy"
|
|
},
|
|
"legal_entity_name": {
|
|
"label": "Legal Entity / Operator Name",
|
|
"hint": "The operator name shown in the cookie banner and MyPage.",
|
|
"placeholder": "e.g., Acme Corp."
|
|
},
|
|
"data_storage_location": {
|
|
"label": "Data Storage Location",
|
|
"hint": "Country where user data is stored, shown to users. e.g., \"United States (AWS)\", \"Germany\". Do not enter IP addresses, cloud region codes (e.g., ap-northeast-2), or datacenter addresses — these are security-sensitive.",
|
|
"placeholder": "e.g., Korea (self-hosted IDC) / United States (AWS)"
|
|
},
|
|
"banner_enabled": {
|
|
"label": "Show Cookie Banner",
|
|
"hint": "When enabled, the cookie banner and pre-consent auto-blocking are activated together. The MyPage consent management card is independent of this toggle and always shows for members with consent/withdrawal history."
|
|
},
|
|
"banner_position": {
|
|
"label": "Banner Position",
|
|
"hint": "Choose where the cookie banner appears on screen.",
|
|
"option_bottom_bar": "Bottom bar (full width)",
|
|
"option_bottom_left_popup": "Bottom-left popup",
|
|
"option_bottom_right_popup": "Bottom-right popup",
|
|
"option_centered_modal": "Centered modal"
|
|
},
|
|
"blocked_domains": {
|
|
"warnings_title": "Notes",
|
|
"auto_blocking_off_hint": "Auto-blocking is only active when the Cookie Banner is ON. Enable Show Cookie Banner in the Cookie Banner card first.",
|
|
"warning_visual_break": "Be careful when classifying external font/stylesheet domains. Misclassification can break the page silently.",
|
|
"warning_policy_bump": "Bump the cookie policy version after changing the blocked domain list. This prevents existing consenters from being implicitly enrolled into newly added trackers.",
|
|
"warning_domain_format": "Domain format: example.com, *.example.com (wildcard) are supported. Names without dots (like localhost) and non-ASCII domains are not supported.",
|
|
"warning_scope_limit": "Auto-blocking only covers scripts registered by plugins/modules. External scripts inserted directly into the head area by admins (e.g. via Template External Scripts) are outside this protection — verify their load conditions separately.",
|
|
"tag_input_placeholder": "Type a domain and press Enter (e.g., google-analytics.com, *.hotjar.com)",
|
|
"tag_no_options": "No suggestions. Type to add.",
|
|
"category": {
|
|
"functional": "Functional — Blocked Domains",
|
|
"analytics": "Analytics — Blocked Domains",
|
|
"marketing": "Marketing — Blocked Domains"
|
|
}
|
|
},
|
|
"cookie_categories": {
|
|
"description": "Open each card's [Show details] to see the purpose of the four cookie categories and the blocked-tool examples.",
|
|
"category_required_badge": "Required",
|
|
"category_optional_badge": "Optional",
|
|
"info": {
|
|
"expand": "Show details",
|
|
"collapse": "Hide details",
|
|
"description_label": "User-facing description",
|
|
"scope_label": "Auto-blocking scope",
|
|
"tools_label": "Common tools",
|
|
"necessary": {
|
|
"scope": "Not auto-blocked. Session/auth tokens, shopping basket identifier, user-selected language preference at registration, and cookie consent records are essential to site operation and always allowed.",
|
|
"tools": "Session IDs, authentication tokens, CSRF tokens, shopping basket identifier, language preference, etc. (no configuration required)"
|
|
},
|
|
"functional": {
|
|
"scope": "External resources matching the functional blocked-domain list (in the Auto-blocking Policy tab) are auto-blocked until the user consents. User preferences such as dark mode and currency selection are also persisted only after consent.",
|
|
"tools": "Customer support chatbots (Crisp, Intercom, Tawk.to), translation widgets, user-preference synchronization services, etc."
|
|
},
|
|
"analytics": {
|
|
"scope": "External analytics scripts, embeds, and tracking pixels matching the analytics blocked-domain list (in the Auto-blocking Policy tab) are auto-blocked until the user consents. Resources are restored immediately on consent.",
|
|
"tools": "Google Analytics 4 (GA4), Hotjar, Microsoft Clarity, Mixpanel, Matomo, Naver Premium Log Analysis, etc."
|
|
},
|
|
"marketing": {
|
|
"scope": "External advertising, embeds, and tracking pixels matching the marketing blocked-domain list (in the Auto-blocking Policy tab) are auto-blocked until the user consents. Resources are restored immediately on consent.",
|
|
"tools": "Meta Pixel (Facebook), Google Ads remarketing, Kakao Pixel, YouTube video embeds, etc."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"save_success": "Settings have been saved.",
|
|
"save_error": "An error occurred while saving settings.",
|
|
"validation_error": "Please check your inputs.",
|
|
"unsaved_changes": "You have unsaved changes.",
|
|
"policy_version": {
|
|
"current_label": "Current version",
|
|
"published_at_label": "Published at",
|
|
"publisher_label": "Publisher",
|
|
"publisher_system": "System",
|
|
"memo_label": "Change reason",
|
|
"publish_button": "Publish new version",
|
|
"history_toggle_show": "View history",
|
|
"history_toggle_hide": "Hide history",
|
|
"history_empty": "No policy versions have been published yet.",
|
|
"publish_success": "A new policy version has been published. All members will be prompted to re-consent on their next visit.",
|
|
"publishing": "Publishing...",
|
|
"guide_title": "When to publish a new version",
|
|
"guide_body": "Routine operational changes such as editing blocked domains or tweaking UI labels do not require publishing a new version.",
|
|
"change_type": {
|
|
"material": "Triggers re-consent",
|
|
"non_material": "Minor change",
|
|
"initial": "Initial publication"
|
|
},
|
|
"history": {
|
|
"col": {
|
|
"version": "Version",
|
|
"created_at": "Published at",
|
|
"publisher": "Publisher",
|
|
"change_type": "Type",
|
|
"memo": "Reason",
|
|
"snapshot_action": "Snapshot"
|
|
}
|
|
},
|
|
"snapshot_view_short": "View",
|
|
"material_modal": {
|
|
"title": "Publish new policy version + trigger re-consent",
|
|
"body": "Clicking \"Publish new version\" publishes immediately, and all users must re-consent on their next visit.",
|
|
"effect_bump": "Policy version monotonic increment (e.g., v2 → v3)",
|
|
"effect_reconsent": "All members will see the consent screen on their next visit",
|
|
"effect_history": "A new version row will be added to the history table",
|
|
"memo_label": "Change reason (required)",
|
|
"memo_placeholder": "e.g., Privacy policy body update / Operator change",
|
|
"confirm": "Publish new version"
|
|
},
|
|
"snapshot_modal": {
|
|
"editor_label": "View policy version snapshot",
|
|
"title": "Policy version v{version} snapshot",
|
|
"description": "Full snapshot of settings at publication time — categories, privacy policy slug, blocked domains. Used by DPO as evidence in consent disputes.",
|
|
"section_categories": "Cookie categories",
|
|
"section_privacy_policy": "Privacy policy slug",
|
|
"section_blocked_domains": "Blocked domain catalog",
|
|
"category_required_badge": "Required",
|
|
"no_categories": "No categories registered.",
|
|
"no_blocked_domains": "No blocked domains registered.",
|
|
"view_button": "View v{version} snapshot",
|
|
"close": "Close",
|
|
"open_policy_page": "Open policy page",
|
|
"no_policy_slug": "No privacy policy page registered."
|
|
},
|
|
"not_found": "Policy version not found.",
|
|
"history_page_summary": "{total} total · page {current} / {last}",
|
|
"history_prev": "Previous",
|
|
"history_next": "Next"
|
|
}
|
|
},
|
|
"admin": {
|
|
"consent_log": {
|
|
"title": "GDPR Consent Log",
|
|
"description": "Audit consent and revocation history of members and guests. IP and User-Agent are included.",
|
|
"refresh": "Refresh",
|
|
"empty": "No consent log entries found.",
|
|
"clear_filters": "Clear filters",
|
|
"guest_label": "Guest",
|
|
"view_member_tooltip": "Open member detail page",
|
|
"search_placeholder": "Search by Email or Session ID",
|
|
"search_button": "Search",
|
|
"search_type": {
|
|
"email": "Email",
|
|
"session_id": "Session ID"
|
|
},
|
|
"filter": {
|
|
"consent_key_label": "Consent Key",
|
|
"action_label": "Action",
|
|
"source_label": "Source",
|
|
"option_all": "All"
|
|
},
|
|
"action": {
|
|
"granted": "Granted",
|
|
"revoked": "Revoked",
|
|
"rejected": "Rejected"
|
|
},
|
|
"source": {
|
|
"banner": "Banner",
|
|
"preference_center": "Preferences",
|
|
"mypage": "MyPage",
|
|
"register": "Sign-up",
|
|
"mypage_renew_all": "MyPage bulk re-consent",
|
|
"withdraw": "Account withdrawal"
|
|
},
|
|
"col": {
|
|
"created_at": "Time",
|
|
"subject": "Subject",
|
|
"consent_key": "Consent Key",
|
|
"action": "Action",
|
|
"source": "Source",
|
|
"policy_version": "Policy Version",
|
|
"ip": "IP"
|
|
},
|
|
"detail": {
|
|
"session_id_label": "Session ID",
|
|
"user_agent_label": "User-Agent",
|
|
"categories_label": "Categories Snapshot",
|
|
"categories_hint": "The member's category-by-category choices at the time of consent. This record stays immutable even after the policy is updated.",
|
|
"snapshot_granted": "Granted",
|
|
"snapshot_revoked": "Not Consented"
|
|
}
|
|
}
|
|
},
|
|
"mypage": {
|
|
"privacy": {
|
|
"title": "Cookie Consent",
|
|
"description": "Change or revoke your consent for the cookies this site uses.",
|
|
"section_consents": "My Consents",
|
|
"section_consents_hint": "Changes apply immediately. Required items cannot be revoked.",
|
|
"col_consent_key": "Consent",
|
|
"col_consented": "Status",
|
|
"col_consented_at": "Consented At",
|
|
"col_revoked_at": "Revoked At",
|
|
"col_policy_version": "Policy Version",
|
|
"col_action": "Action",
|
|
"consented": "Consented",
|
|
"revoked": "Revoked",
|
|
"rejected_label": "Rejected",
|
|
"revoke": "Revoke",
|
|
"grant": "Consent",
|
|
"grant_again": "Consent Again",
|
|
"label_suffix": "{label} cookies",
|
|
"locked_label": "Required",
|
|
"enable_all": "Consent to all",
|
|
"enable_all_hint": "You have optional items you haven't consented to. Consent to them all at once.",
|
|
"enable_all_success": "You have consented to all optional items.",
|
|
"required_label": "Required",
|
|
"required_hint": "This item is required for service operation and cannot be revoked.",
|
|
"grant_confirm_title": "Confirm Cookie Consent",
|
|
"grant_confirm_message": "Do you want to consent to this cookie? Once consented, this category's cookies will be used, and you can revoke it anytime.",
|
|
"revoke_confirm_title": "Revoke Consent",
|
|
"revoke_confirm_message": "Are you sure you want to revoke this consent? Revoking consent may limit features related to that category.",
|
|
"revoke_target_consented_at": "Consented · {date}",
|
|
"no_consents": "No active consent items.",
|
|
"needs_renewal": "The cookie policy has been updated. Please renew your consent.",
|
|
"needs_renewal_with_version": "The cookie policy has been updated to version {version}. Please review the optional consent items.",
|
|
"needs_renewal_hint": "Strictly necessary cookies are essential for site operation and remain unchanged regardless of policy updates.",
|
|
"btn_renew_all": "Renew Current Consent",
|
|
"btn_renew_this_item": "Renew Policy",
|
|
"renew_all_success": "Renewed {renewed} active item(s) to the new policy version.",
|
|
"operator_and_storage_meta": "This site is operated by {entity}, and data is stored in {location}.",
|
|
"operator_only_meta": "This site is operated by {entity}.",
|
|
"storage_only_meta": "User data is stored in {location}."
|
|
}
|
|
},
|
|
"common": {
|
|
"loading": "Loading...",
|
|
"refresh": "Refresh"
|
|
},
|
|
"banner": {
|
|
"re_appear_reason": "The cookie policy has been updated to version {version}. Please review your consent.",
|
|
"consent_required_hint": "Features related to declined categories may be limited.",
|
|
"btn_renew_consent": "Renew Current Consent",
|
|
"title": "Cookie Notice",
|
|
"description": "This site uses cookies to improve user experience and for analytics. You can choose which cookies to allow.",
|
|
"accept_all": "Accept All",
|
|
"reject_continue": "Continue without consent",
|
|
"preferences": "Select Consent",
|
|
"save": "Save Selection",
|
|
"policy_link": "Privacy Policy",
|
|
"preferences_title": "Cookie Preferences",
|
|
"preferences_description": "You can grant or revoke each category individually. Required categories cannot be turned off.",
|
|
"category_required_badge": "Required",
|
|
"view_policy_label": "View updated policy",
|
|
"operator_and_storage_line": "This site is operated by {entity}, and data is stored in {location}.",
|
|
"operator_only_line": "This site is operated by {entity}.",
|
|
"storage_only_line": "User data is stored in {location}."
|
|
}
|
|
}
|