diff --git a/AGENTS.md b/AGENTS.md index a74a6e4..105a761 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -129,9 +129,19 @@ Task 2: general-purpose - "Implement the planned skill" # Needs Task 1 result ### GTM Skills (60-69) -- Use **gtm-manager** agent for GTM-specific debugging -- Requires Chrome GTM Debug profile for live testing -- Scripts interact with GTM API and dataLayer +Three specialized skills with clear handoff workflow: **audit → edit → validate** + +| Skill | Purpose | MCP Tools | +|-------|---------|-----------| +| 60-gtm-audit | Scan pages, gap analysis, tag design blueprints | DTM Agent + Chrome DevTools | +| 61-gtm-editor | Create/modify tags, triggers, variables via GTM API | DTM Agent + Chrome DevTools | +| 62-gtm-validator | QA tag firing, trigger selectors, naming conventions | DTM Agent + Chrome DevTools | + +- **gtm-audit** Mode D outputs blueprints → hand off to **gtm-editor** for implementation +- **gtm-editor** creates tags → hand off to **gtm-validator** for QA verification +- **gtm-validator** finds broken selectors → hand back to **gtm-editor** for fixes +- All three use DTM Agent MCP for container operations and Chrome DevTools MCP for browser inspection +- Audit reports write to Notion GTM Audit Log database ### Jamie Clinic Skills (40-49) diff --git a/CLAUDE.md b/CLAUDE.md index 99a6cbd..8edf28a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -68,9 +68,9 @@ This is a Claude Skills collection repository containing: | # | Skill | Purpose | Trigger | |---|-------|---------|---------| -| 60 | gtm-audit | GTM container audit | "audit GTM", "GTM analysis" | -| 61 | gtm-manager | GTM management + dataLayer | "GTM manager", "dataLayer" | -| 62 | gtm-guardian | Live tag monitoring & validation | "monitor GTM", "tag validation" | +| 60 | gtm-audit | GTM audit — page scan, site audit, gap analysis, tag design | "GTM audit", "scan page", "tracking coverage", "gap analysis" | +| 61 | gtm-editor | GTM tag/trigger/variable creation via API, ES5 Custom HTML, dataLayer | "create GTM tag", "generate dataLayer", "modify trigger", "manage GTM" | +| 62 | gtm-validator | GTM QA — tag firing, trigger testing, naming conventions, cross-platform | "validate tags", "QA GTM", "debug GTM", "naming conventions" | ### Notion Tools (31-39) diff --git a/README.md b/README.md index 4657f35..65a06f2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > **Internal R&D Repository** - This repository is restricted for internal use only. -A collection of **62 custom Claude Skills** for OurDigital workflows, D.intelligence Agent Corps (9-agent business operations suite), Jamie Plastic Surgery Clinic brand management, SEO/GTM tools, NotebookLM automation, Notion integrations, reference documentation curation, macOS system optimization, and multi-agent collaboration. +A collection of **64 custom Claude Skills** for OurDigital workflows, D.intelligence Agent Corps (9-agent business operations suite), Jamie Plastic Surgery Clinic brand management, SEO/GTM tools, NotebookLM automation, Notion integrations, reference documentation curation, macOS system optimization, and multi-agent collaboration. ## Quick Install @@ -88,9 +88,9 @@ cd our-claude-skills/custom-skills/_ourdigital-shared | # | Skill | Purpose | |---|-------|---------| -| 60 | `gtm-audit` | GTM container audit with Chrome DevTools | -| 61 | `gtm-manager` | GTM management + dataLayer generation | -| 62 | `gtm-guardian` | Live tag monitoring & validation | +| 60 | `gtm-audit` | GTM container audit — page scan, site audit, gap analysis, tag design (DTM Agent + Chrome DevTools MCP) | +| 61 | `gtm-editor` | GTM tag/trigger/variable creation via API, ES5 Custom HTML, dataLayer generation, workspace lifecycle | +| 62 | `gtm-validator` | GTM QA — tag firing verification, trigger testing, dataLayer schema, naming conventions, cross-platform mapping | ### Notion Tools (31-39) diff --git a/custom-skills/60-gtm-audit/code/SKILL.md b/custom-skills/60-gtm-audit/code/SKILL.md new file mode 100644 index 0000000..c3ded5a --- /dev/null +++ b/custom-skills/60-gtm-audit/code/SKILL.md @@ -0,0 +1,140 @@ +--- +name: gtm-audit +description: > + Automated GTM audit and analysis. Scans websites for tracking coverage, compares + against GTM container config, identifies gaps, and reports to Notion. Uses Chrome + DevTools MCP for browser inspection and DTM Agent MCP for container operations. + Triggers on "GTM audit", "audit website", "scan page", "check tracking", + "tracking coverage", "gap analysis", "site audit", "tag firing check". + NOT for creating/modifying tags (use gtm-editor) or validating/QA (use gtm-validator). +--- + +# GTM Audit Skill + +Analyze GTM implementations by scanning websites and comparing against container configuration. + +## Available Tools + +### Browser Inspection (Chrome DevTools MCP) +- `navigate_page` — Load target URL +- `evaluate_script` — Capture dataLayer, detect GTM containers, check JS globals +- `list_network_requests` — Capture tag firing network requests +- `take_screenshot` — Document page state +- `click` / `hover` — Simulate user interactions +- `list_console_messages` — Check for JS errors + +### GTM Container (DTM Agent MCP) +- `dtm_status` — Check auth and active container +- `dtm_list_tags` / `dtm_list_triggers` / `dtm_list_variables` — Get container config +- `dtm_audit_scan` — Scan page with collected data (returns structured PageData) +- `dtm_audit_gap` — Run gap analysis (returns GapReport with OK/MISSING/ORPHAN) + +### Reporting (Notion MCP) +- Write findings to GTM Audit Log: `collection://2cf581e5-8a1e-815a-a7f8-000b88b93585` + +## 4 Audit Modes + +### Mode A: Page Scan (`/gtm-audit scan `) + +Quick single-page diagnostics. No GTM container needed. + +1. `navigate_page` to URL, wait for load +2. `evaluate_script`: capture dataLayer + ```javascript + JSON.stringify(window.dataLayer || []) + ``` +3. `evaluate_script`: detect GTM containers + ```javascript + (function(){var s=document.querySelectorAll('script[src*="googletagmanager.com/gtm.js"]');var ids=[];s.forEach(function(el){var m=el.src.match(/id=(GTM-[A-Z0-9]+)/);if(m)ids.push(m[1]);});return JSON.stringify(ids);})() + ``` +4. `evaluate_script`: detect tracking pixels + ```javascript + (function(){var f=[];if(window.fbq)f.push('Meta Pixel');if(window.gtag)f.push('GA4');if(window.clarity)f.push('Clarity');if(window.kakaoPixel)f.push('Kakao');if(window.wcs)f.push('Naver');if(window.ttq)f.push('TikTok');return JSON.stringify(f);})() + ``` +5. `list_network_requests` — filter for tag domains +6. Call `dtm_audit_scan` with collected html, network_requests, datalayer_json +7. Report findings + +### Mode B: Site Audit (`/gtm-audit site `) + +Full website coverage audit with auto-discovery. + +1. Navigate to root URL +2. `evaluate_script`: extract all internal links +3. Classify pages by type (home, product, service, form, blog, about) +4. For each page type: run Mode A scan +5. Build coverage matrix (page type × event × platform) +6. Run Mode C gap analysis against container +7. Write comprehensive report to Notion + +### Mode C: Gap Analysis (`/gtm-audit gap `) — MOST IMPORTANT + +Compare GTM container config against actual tag firing. + +1. `dtm_status` — verify auth and active container +2. `dtm_list_tags` + `dtm_list_triggers` — get expected configuration +3. `navigate_page` to URL +4. `evaluate_script` — capture dataLayer +5. `list_network_requests` — capture actual tag firings +6. Call `dtm_audit_gap` with network_requests +7. Analyze gaps: MISSING (in GTM, not firing), ORPHAN (firing, not in GTM) +8. Write to Notion GTM Audit Log + +### Mode D: Tag Design (`/gtm-audit design `) + +AI-powered analysis of what SHOULD be tracked on a page. + +1. `navigate_page` to URL +2. `take_screenshot` — visual reference +3. `evaluate_script` — inspect DOM: forms, buttons, links, product elements +4. `evaluate_script` — capture existing dataLayer schema +5. `dtm_list_tags` — check existing configuration +6. Design recommendations: which events, triggers, variables are needed +7. Output as structured blueprint (hand off to gtm-editor for implementation) + +## Detection Patterns + +### Cloudflare Zaraz Proxy +URLs with `/1tbv/` path proxy GA4/Ads through the site's domain: +``` +https://site.com/1tbv/ag/g/c?tid=G-XXXXX → GA4 +https://site.com/1tbv/ag/g/c?tid=AW-XXXXX → Google Ads +``` + +### Server-Side GTM (sGTM) +Custom subdomains: `stms.*`, `sgtm.*`, `ss.*`, `tag.*` +``` +https://stms.site.com/g/collect?tid=G-XXXXX → GA4 via sGTM +``` + +### GA4 Multiple Endpoints +One GA4 page_view fires to multiple endpoints — this is normal: +- `google-analytics.com/g/collect` +- `analytics.google.com/g/s/collect` +- `stats.g.doubleclick.net/g/collect` +- `www.google.com/ccm/collect` (Consent Mode) +- Zaraz proxy endpoints + +## Notion Report Fields + +| Field | Value | +|-------|-------| +| Site | domain name | +| URL | full URL | +| Container IDs | GTM-XXXXX | +| Audit Status | Pass / Warning / Fail | +| GTM Status | Installed / Not Found / Multiple Containers | +| Tags Fired | [GA4, Google Ads, Meta Pixel, Kakao, Naver, ...] | +| Journey Type | full / pageview / scroll / form / checkout / datalayer | +| Critical Issues | count | +| Issues Count | count | +| Summary | AI-generated findings | + +## Rules + +- Always check `dtm_status` before gap analysis +- Wait for page to fully load before capturing network requests +- Use `evaluate_script` to check consent mode before interpreting missing tags +- Orphan count may be high due to GA4 multi-endpoint — note this in reports +- Hand off tag creation work to `gtm-editor` skill +- Hand off QA/validation work to `gtm-validator` skill diff --git a/custom-skills/61-gtm-editor/code/SKILL.md b/custom-skills/61-gtm-editor/code/SKILL.md new file mode 100644 index 0000000..2d89e62 --- /dev/null +++ b/custom-skills/61-gtm-editor/code/SKILL.md @@ -0,0 +1,186 @@ +--- +name: gtm-editor +description: > + GTM implementation toolkit. Creates, updates, and modifies GTM tags, triggers, + variables via API. Generates Custom HTML with ES5 compliance. Handles workspace + lifecycle, DOM analysis for trigger design, and dataLayer code generation. + Triggers on "create GTM tag", "generate dataLayer", "modify trigger", "update variable", + "inject tracking code", "write custom HTML", "manage GTM", "design tags", + "create conversion tag", "set up tracking". + NOT for auditing (use gtm-audit) or validation/QA (use gtm-validator). +--- + +# GTM Editor Skill + +Create, modify, and deploy GTM configurations via API. Generates ES5-compliant Custom HTML tags. + +## Available Tools + +### GTM Container Management (DTM Agent MCP) +- `dtm_status` — Check auth and active account/container +- `dtm_set_account` / `dtm_set_container` — Switch context +- `dtm_list_tags` / `dtm_get_tag` / `dtm_create_tag` / `dtm_update_tag` / `dtm_delete_tag` +- `dtm_list_triggers` / `dtm_get_trigger` / `dtm_create_trigger` / `dtm_delete_trigger` +- `dtm_list_variables` / `dtm_get_variable` / `dtm_create_variable` / `dtm_delete_variable` +- `dtm_list_folders` / `dtm_list_workspaces` / `dtm_get_workspace_status` +- `dtm_list_versions` / `dtm_get_live_version` / `dtm_create_version` + +### Browser Analysis (Chrome DevTools MCP) +- `navigate_page` — Load page for DOM analysis +- `evaluate_script` — Inspect forms, buttons, links, CSS selectors +- `take_snapshot` — Get page structure for trigger design +- `list_network_requests` — Verify tags fire after changes + +### Reporting (Notion MCP) +- Write implementation plans and tag configurations to Notion + +## Core Capabilities + +### 1. Tag Creation via GTM API + +Create tags directly in GTM — no manual pasting. The API handles workspace lifecycle automatically (auto-creates new workspace if current one is published). + +**GA4 Event Tags:** +``` +GA4 event tags use type "gaawe" with: + - eventName: the GA4 event name (snake_case) + - measurementIdOverride: {{GA4 Measurement ID variable}} (NOT measurementId) + - eventParameters: list of name/value maps +``` + +**CRITICAL: measurementIdOverride, NOT measurementId** +GA4 event tags inherit from config — use `measurementIdOverride` to reference the measurement ID variable. The API rejects `measurementId`. + +### 2. Trigger Design from DOM Analysis + +Analyze page DOM to design precise triggers: + +```javascript +// Extract forms +(function(){var forms=document.querySelectorAll('form');return JSON.stringify(Array.from(forms).map(function(f){return{id:f.id,action:f.action,fields:Array.from(f.querySelectorAll('input,textarea,select')).map(function(el){return{name:el.name,type:el.type,id:el.id}})}}));})() + +// Extract CTAs and buttons +(function(){return JSON.stringify(Array.from(document.querySelectorAll('a[class*="btn"],button,[role="button"]')).map(function(el){return{text:(el.textContent||'').trim().substring(0,50),href:el.href||'',classes:el.className,id:el.id}}));})() +``` + +**Trigger types:** +| Type | Use For | Key Parameter | +|------|---------|---------------| +| `linkClick` | `` elements | `autoEventFilter` with CSS selector | +| `click` | Any element | `filter` on Click ID/Classes | +| `formSubmission` | Form submit | `filter` on Form ID | +| `customEvent` | dataLayer events | `custom_event_filter` on `{{_event}}` | +| `scrollDepth` | Scroll tracking | `verticalThresholdsPercent` | +| `timer` | Time on page | `interval`, `limit` | +| `domReady` | DOM loaded | No filter needed | + +### 3. Custom HTML Generation (ES5 MANDATORY) + +GTM Custom HTML uses a JavaScript compiler that does NOT support ES2020+. + +**FORBIDDEN:** +```javascript +// NO: optional chaining, arrow functions, const/let, template literals, +// destructuring, spread, async/await +``` + +**REQUIRED:** +```javascript +// YES: var, function(){}, string concatenation, explicit property access +(function() { + var form = document.getElementById('contact-form'); + if (!form) return; + form.addEventListener('submit', function() { + window.dataLayer = window.dataLayer || []; + window.dataLayer.push({ + 'event': 'generate_lead', + 'lead_type': form.querySelector('#requestType').value + }); + }); +})(); +``` + +### 4. Workspace Lifecycle Management + +GTM workspaces become **read-only after publishing**. The DTM Agent auto-handles this: +- If create/update fails with "Workspace is already submitted" +- Auto-creates a new workspace +- Retries the operation +- Caches the workspace ID for subsequent calls + +**You don't need to manage workspaces manually.** Just call `dtm_create_tag` etc. and it works. + +### 5. DataLayer Code Generation + +Generate dataLayer push code for common tracking scenarios: + +**E-commerce:** +```javascript +// purchase event +window.dataLayer = window.dataLayer || []; +window.dataLayer.push({ ecommerce: null }); // Clear previous +window.dataLayer.push({ + 'event': 'purchase', + 'ecommerce': { + 'transaction_id': /* order ID */, + 'currency': 'KRW', + 'value': /* total */, + 'items': [{ item_id: '', item_name: '', price: 0, quantity: 1 }] + } +}); +``` + +**Forms/Leads:** +```javascript +window.dataLayer.push({ + 'event': 'generate_lead', + 'lead_type': /* form type */, + 'form_id': /* form element ID */ +}); +``` + +## Korean Market Patterns + +| Context | Pattern | +|---------|---------| +| Currency | KRW (no decimals) | +| Payment buttons | 장바구니, 결제하기, 주문하기, 문의하기 | +| Payment methods | 카카오페이, 네이버페이, 토스, 신용카드 | +| Platforms | Kakao Pixel (`track.kakao.com`), Naver Analytics (`wcs.naver.net`) | + +## Supported Tag Types + +| GTM Type | Name | Platform | +|----------|------|----------| +| `googtag` | Google Tag | GA4 config | +| `gaawe` | GA4 Event | GA4 events | +| `gclidw` | Conversion Linker | Google Ads | +| `awct` | Ads Conversion | Google Ads | +| `html` | Custom HTML | Any (Meta, PostHog, Kakao, etc.) | +| `cvt_MQDKZ` | Clarity | Microsoft Clarity | +| `cvt_WF3R3` | Amplitude | Amplitude | + +## FB Conversions API Integration + +When creating tags that should trigger FB CAPI: +1. Check existing FBEventName mapping table (Regex Table variable) +2. If your custom event isn't mapped, add a new rule: `event_name → FB_Standard_Event` +3. Key mappings: `generate_lead → Lead`, `purchase → Purchase`, `page_view → PageView` + +## Workflow + +1. **Analyze**: Use Chrome DevTools to inspect the page (or receive from gtm-audit Mode D) +2. **Design**: Determine events, triggers, variables needed +3. **Create**: Use DTM Agent MCP tools to create in GTM +4. **Verify**: Hand off to gtm-validator for QA +5. **Document**: Write implementation details to Notion + +## Rules + +- Always use `dtm_status` first to verify auth and active container +- Always use `measurementIdOverride` for GA4 event tags (NOT `measurementId`) +- All Custom HTML must be ES5-compatible +- Use `--dry-run` conceptually — verify trigger selectors via Chrome DevTools before creating +- Rate limit: space API calls 1 second apart in batch operations +- Never delete tags without explicit user confirmation — move to Archive folder instead +- After creating tags, suggest user run gtm-validator to verify diff --git a/custom-skills/62-gtm-validator/code/SKILL.md b/custom-skills/62-gtm-validator/code/SKILL.md new file mode 100644 index 0000000..e653af2 --- /dev/null +++ b/custom-skills/62-gtm-validator/code/SKILL.md @@ -0,0 +1,224 @@ +--- +name: gtm-validator +description: > + GTM QA and validation toolkit. Verifies tags fire correctly on live pages, + tests trigger conditions against actual DOM, validates dataLayer schemas, + checks naming conventions, compares cross-platform events, and runs QA checklists. + Uses Chrome DevTools MCP for live page testing. + Triggers on "validate tags", "check triggers", "verify tracking", "QA GTM", + "test events", "debug GTM", "troubleshoot", "naming conventions", + "GTM question", "GTM best practice", "compare versions". + NOT for auditing (use gtm-audit) or creating/modifying (use gtm-editor). +--- + +# GTM Validator Skill + +Verify GTM implementations work correctly on live pages. Test triggers, validate dataLayer, check naming conventions. + +## Available Tools + +### Browser Testing (Chrome DevTools MCP) +- `navigate_page` — Load page to test +- `evaluate_script` — Check dataLayer state, test selectors, verify globals +- `list_network_requests` — Verify tag firing after interactions +- `click` / `hover` — Simulate user actions to trigger events +- `list_console_messages` — Check for JS errors +- `take_screenshot` — Document test results + +### GTM Container (DTM Agent MCP) +- `dtm_status` — Check active container +- `dtm_list_tags` / `dtm_get_tag` — Get tag configurations +- `dtm_list_triggers` / `dtm_get_trigger` — Get trigger conditions +- `dtm_list_variables` / `dtm_get_variable` — Get variable definitions +- `dtm_list_versions` / `dtm_get_live_version` — Compare versions + +## Validation Modes + +### 1. Tag Firing Verification + +Test that specific tags fire on the correct pages and interactions. + +**Steps:** +1. `dtm_list_tags` — get all active tags with their triggers +2. `navigate_page` to target URL +3. `list_network_requests` — capture initial tag firings +4. For click triggers: `click` the element, then check `list_network_requests` again +5. Compare: expected tags (from GTM config) vs actual network requests + +**Verification script for specific tag:** +```javascript +// Check if GA4 event fired +(function(){ + var dl = window.dataLayer || []; + var events = dl.filter(function(e){return e.event && e.event !== 'gtm.js' && e.event !== 'gtm.dom' && e.event !== 'gtm.load';}); + return JSON.stringify(events.map(function(e){return {event: e.event, params: Object.keys(e).filter(function(k){return k !== 'event' && !k.startsWith('gtm.')})}})); +})() +``` + +### 2. Trigger Condition Testing + +Verify trigger CSS selectors and conditions match the actual page DOM. + +**Steps:** +1. `dtm_get_trigger` — get trigger filter/autoEventFilter +2. Extract CSS selectors from trigger config +3. `evaluate_script` — test if selectors match elements on page: + +```javascript +// Test CSS selector +(function(selector){ + var els = document.querySelectorAll(selector); + return JSON.stringify({ + selector: selector, + matchCount: els.length, + elements: Array.from(els).slice(0,5).map(function(el){ + return {tag: el.tagName, id: el.id, classes: el.className, text: (el.textContent||'').trim().substring(0,30)}; + }) + }); +})('.hero a.btn') +``` + +4. If selector matches 0 elements → trigger will NEVER fire → **CRITICAL issue** +5. If selector matches too many elements → trigger may fire incorrectly → **WARNING** + +### 3. DataLayer Schema Validation + +Verify dataLayer pushes contain required fields with correct types. + +**GA4 Recommended Event Schemas:** + +| Event | Required Fields | +|-------|----------------| +| `page_view` | (automatic) | +| `generate_lead` | — (value, currency optional) | +| `purchase` | transaction_id, value, currency, items[] | +| `add_to_cart` | items[] (item_id, item_name, price, quantity) | +| `form_start` | form_id, form_name | +| `form_submit` | form_id, form_name | + +**Validation script:** +```javascript +// Check dataLayer for specific event schema +(function(eventName){ + var dl = window.dataLayer || []; + var events = dl.filter(function(e){return e.event === eventName;}); + if(events.length === 0) return JSON.stringify({found: false, event: eventName}); + var e = events[events.length-1]; + return JSON.stringify({found: true, event: eventName, keys: Object.keys(e), data: e}); +})('generate_lead') +``` + +### 4. Naming Convention Check + +Verify all GTM resources follow D.intelligence naming standards. + +**Tag naming:** +``` +[Platform] - [event_name] [context] +Examples: + GA4 - generate_lead (contact form) + sGTM - purchase + cHTML - Contact Form dataLayer Events + FB_CONVERSIONS_API-PIXEL_ID-Web-Tag-GA4_Event +``` + +**Trigger naming:** +``` +[Type] - [description] Trigger +Examples: + Click - Hero CTA (consult) + CE - contact_form_submit + Form Submit - contact-form + Scroll - 50pct Depth + PV - consult booking Trigger +``` + +**Variable naming:** +``` +[prefix] - [description] +Prefixes: dlv (dataLayer), cjs (Custom JS), aev (Auto-Event), + jsv (JS Variable), URL query, cookie, c (Constant) +Examples: + dlv - contact_form.request_type + cjs - Social platform + aev - click url hostname +``` + +**Validation steps:** +1. `dtm_list_tags` / `dtm_list_triggers` / `dtm_list_variables` +2. Check each name against patterns above +3. Flag violations: missing prefix, wrong case, unclear description + +### 5. Cross-Platform Event Mapping Verification + +Verify the same user action sends consistent events to all platforms. + +| User Action | GA4 | Meta (FB) | Google Ads | Kakao | Naver | +|------------|-----|-----------|------------|-------|-------| +| Page view | page_view | PageView | — | pageView | — | +| Product view | view_item | ViewContent | — | viewContent | — | +| Add to cart | add_to_cart | AddToCart | — | addToCart | — | +| Purchase | purchase | Purchase | purchase | purchase | — | +| Lead form | generate_lead | Lead | submit_lead_form | participation | — | + +**Steps:** +1. Trigger a user action (click, form submit) +2. `list_network_requests` — capture all resulting requests +3. Check each platform received the correct event: + - GA4: `google-analytics.com/g/collect?en=...` + - Meta: `facebook.com/tr/?ev=...` + - Google Ads: `googleads.g.doubleclick.net/pagead/...` + +### 6. QA Checklist Execution + +Run through a standard QA checklist for GTM implementation: + +- [ ] GTM container snippet in `` (not ``) +- [ ] GTM noscript fallback in `` +- [ ] No duplicate GTM containers on same page +- [ ] dataLayer initialized before GTM snippet +- [ ] All P1 tags fire on page load (GA4 config, Consent Mode) +- [ ] Click triggers use specific selectors (not generic classes) +- [ ] Form triggers match form IDs that exist on page +- [ ] Custom HTML tags use ES5 syntax only +- [ ] No console errors related to GTM/tags +- [ ] Consent Mode properly blocks tags before consent +- [ ] sGTM endpoint responding (no SSL errors) +- [ ] Cross-domain tracking configured if needed + +### 7. Version Comparison + +Compare tags between two container versions to identify changes. + +1. `dtm_list_versions` — get version list +2. `dtm_get_live_version` — get current live version with all tags +3. Compare tag counts, trigger counts, new/modified/deleted items +4. Report changes since last publish + +## Reference Files + +| File | Content | +|------|---------| +| `references/datalayer-schema.md` | GA4 recommended event schemas | +| `references/platform-mapping.md` | GA4 ↔ Meta ↔ Kakao ↔ Ads event mapping | +| `references/naming-conventions.md` | Tag/trigger/variable naming rules | +| `references/qa-checklist.md` | Full QA checklist | + +## Workflow + +1. **Receive** tag list from gtm-editor (or run `dtm_list_tags`) +2. **Navigate** to the target page via Chrome DevTools +3. **Test** each trigger's CSS selector matches actual DOM elements +4. **Simulate** user actions (clicks, form submits, scrolls) +5. **Capture** network requests after each action +6. **Verify** correct events fired to correct platforms +7. **Report** pass/fail with evidence (screenshots, network logs) + +## Rules + +- Always test on the LIVE published version, not preview (unless debugging) +- Test on both desktop and mobile viewports when possible +- Check consent mode state before flagging missing tags +- Document every test result with screenshots or network request evidence +- If a trigger selector doesn't match, suggest a fix and hand off to gtm-editor +- GTM questions, best practices, and architecture advice are also in scope diff --git a/custom-skills/62-gtm-validator/code/references/datalayer-schema.md b/custom-skills/62-gtm-validator/code/references/datalayer-schema.md new file mode 100644 index 0000000..2ec93bd --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/datalayer-schema.md @@ -0,0 +1,193 @@ +# DataLayer Schema Reference + +GA4 권장 이벤트 기반 DataLayer 스키마 정의. + +## Core Principles + +1. GTM 스니펫 이전에 dataLayer 초기화 +2. 이벤트 발생 시점에 push (사전 아님) +3. ecommerce 객체는 push 전 clear 필수 +4. PII 데이터 직접 수집 금지 + +## Base Structure + +### Page Load +```javascript +window.dataLayer = window.dataLayer || []; +dataLayer.push({ + 'event': 'page_data', + 'page': { + 'type': 'home|category|product|cart|checkout|thankyou|content|search', + 'name': 'Page Name', + 'category': 'Category/Subcategory', + 'language': 'ko' + }, + 'user': { + 'status': 'logged_in|logged_out', + 'id': 'hashed_user_id', // SHA256, 로그인 시에만 + 'type': 'new|returning|member|guest', + 'loginMethod': 'email|kakao|naver|google' + } +}); +``` + +## E-commerce Events + +### view_item +```javascript +dataLayer.push({ ecommerce: null }); +dataLayer.push({ + 'event': 'view_item', + 'ecommerce': { + 'currency': 'KRW', + 'value': 29000, + 'items': [{ + 'item_id': 'SKU_12345', + 'item_name': 'Product Name', + 'item_brand': 'Brand Name', + 'item_category': 'Category', + 'item_variant': 'Blue / Large', + 'price': 29000, + 'quantity': 1 + }] + } +}); +``` + +### add_to_cart +```javascript +dataLayer.push({ ecommerce: null }); +dataLayer.push({ + 'event': 'add_to_cart', + 'ecommerce': { + 'currency': 'KRW', + 'value': 29000, + 'items': [{ + 'item_id': 'SKU_12345', + 'item_name': 'Product Name', + 'price': 29000, + 'quantity': 1 + }] + } +}); +``` + +### begin_checkout +```javascript +dataLayer.push({ ecommerce: null }); +dataLayer.push({ + 'event': 'begin_checkout', + 'ecommerce': { + 'currency': 'KRW', + 'value': 58000, + 'coupon': 'WELCOME10', + 'items': [/* cart items */] + } +}); +``` + +### purchase +```javascript +dataLayer.push({ ecommerce: null }); +dataLayer.push({ + 'event': 'purchase', + 'ecommerce': { + 'transaction_id': 'T_20250115_001', + 'affiliation': 'Store Name', + 'value': 53000, + 'tax': 4818, + 'shipping': 3000, + 'currency': 'KRW', + 'coupon': 'WELCOME10', + 'items': [{ + 'item_id': 'SKU_12345', + 'item_name': 'Product Name', + 'price': 29000, + 'quantity': 1 + }] + } +}); +``` + +## Lead Gen Events + +### generate_lead +```javascript +dataLayer.push({ + 'event': 'generate_lead', + 'currency': 'KRW', + 'value': 50000, + 'lead': { + 'source': 'contact_form|landing_page', + 'type': 'inquiry|quote_request' + } +}); +``` + +### form_submit +```javascript +dataLayer.push({ + 'event': 'form_submit', + 'form': { + 'id': 'contact_form', + 'name': 'Contact Us Form', + 'type': 'contact', + 'success': true + } +}); +``` + +## Engagement Events + +### login / sign_up +```javascript +dataLayer.push({ + 'event': 'login', // or 'sign_up' + 'method': 'email|kakao|naver|google' +}); +``` + +### search +```javascript +dataLayer.push({ + 'event': 'search', + 'search_term': 'user search query', + 'search': { + 'results_count': 42, + 'category': 'product|content' + } +}); +``` + +## Item Object Reference + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| item_id | string | Yes | SKU | +| item_name | string | Yes | 상품명 | +| price | number | Yes | 단가 | +| quantity | number | Yes | 수량 | +| item_brand | string | No | 브랜드명 | +| item_category | string | No | 카테고리 | +| item_category2-5 | string | No | 하위 카테고리 | +| item_variant | string | No | 옵션 | +| coupon | string | No | 쿠폰 코드 | +| discount | number | No | 할인 금액 | +| index | number | No | 목록 위치 | + +## Validation Rules + +```javascript +// ✅ Correct +'price': 29000 // number +'quantity': 1 // number +'currency': 'KRW' // uppercase + +// ❌ Wrong +'price': '29000' // string +'currency': 'krw' // lowercase +``` + +### Array Limits +- items[]: 최대 200개 +- 초과 시 분할 전송 diff --git a/custom-skills/62-gtm-validator/code/references/naming-conventions.md b/custom-skills/62-gtm-validator/code/references/naming-conventions.md new file mode 100644 index 0000000..76129d2 --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/naming-conventions.md @@ -0,0 +1,130 @@ +# GTM Naming Conventions + +일관된 GTM 컨테이너 관리를 위한 네이밍 규칙. + +## Tag Naming + +### Pattern +``` +[Platform] - [Type] - [Description] +``` + +### Examples +| Platform | Type | Description | Tag Name | +|----------|------|-------------|----------| +| GA4 | Config | Main | GA4 - Config - Main | +| GA4 | Event | purchase | GA4 - Event - purchase | +| GAds | Conversion | Purchase | GAds - Conversion - Purchase | +| Meta | Event | Purchase | Meta - Event - Purchase | +| Kakao | Event | purchase | Kakao - Event - purchase | + +## Trigger Naming + +### Pattern +``` +[Type] - [Condition] - [Context] +``` + +### Type Codes +| Code | Type | Example | +|------|------|---------| +| PV | Page View | PV - All Pages | +| DL | DataLayer Event | DL - purchase | +| Click | Click | Click - CTA Button | +| Form | Form Submit | Form - Contact | +| Scroll | Scroll Depth | Scroll - 75% | +| Vis | Element Visibility | Vis - Video Player | + +### Examples +``` +PV - All Pages +PV - Thank You Page +DL - purchase +DL - add_to_cart +Click - CTA Button - Hero +Form - Contact Form +Scroll - 90% +``` + +## Variable Naming + +### Pattern +``` +[Type] - [Name/Path] +``` + +### Type Codes +| Code | Type | Example | +|------|------|---------| +| DLV | DataLayer Variable | DLV - ecommerce.value | +| CJS | Custom JavaScript | CJS - Item IDs Array | +| Const | Constant | Const - GA4 Measurement ID | +| LT | Lookup Table | LT - Page Type Mapping | +| URL | URL Variable | URL - Path | +| DOM | DOM Element | DOM - Product Title | + +### Examples +``` +DLV - event +DLV - ecommerce.transaction_id +DLV - ecommerce.items +CJS - Items for Meta +CJS - Formatted Price +Const - GA4 Measurement ID +Const - Meta Pixel ID +LT - Payment Method Mapping +``` + +## Folder Structure + +``` +📁 01. Configuration +📁 02. GA4 Events +📁 03. Google Ads +📁 04. Meta Pixel +📁 05. Kakao Pixel +📁 06. Other Platforms +📁 07. Utilities +📁 99. Deprecated +``` + +## Built-in Variables to Enable + +``` +Pages: ✅ Page URL, Path, Hostname, Referrer +Utilities: ✅ Event, Container ID, Random Number +Clicks: ✅ Element, Classes, ID, URL, Text +Forms: ✅ Element, Classes, ID, URL, Text +History: ✅ New/Old History Fragment/State +Videos: ✅ All YouTube variables +Scrolling: ✅ Depth Threshold, Units, Direction +Visibility: ✅ Percent Visible, On-Screen Duration +``` + +## Anti-patterns + +``` +❌ Tag 1, New Tag, Test +❌ GA4 purchase event (일관성 없음) +❌ G4-E-Pch (과도한 약어) +❌ Very Long Tag Name for Purchase Complete Event (너무 김) + +✅ GA4 - Event - purchase +✅ DL - purchase +✅ CJS - Items for Meta +``` + +## Version Notes + +``` +v[Major].[Minor] - [Description] +예: v12.1 - Added form_submit event + +## Changes +- Added: +- Modified: +- Removed: + +## Reason +[변경 이유] +``` diff --git a/custom-skills/62-gtm-validator/code/references/phase6-audit.md b/custom-skills/62-gtm-validator/code/references/phase6-audit.md new file mode 100644 index 0000000..fd1c26b --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/phase6-audit.md @@ -0,0 +1,215 @@ +# Phase 6: Progressive Audit & Update + +설정된 GTM Container에 대한 주기적 진단, 유효성 검증, 마이너 업데이트 및 태그 추가. + +## Objectives + +1. GTM 컨테이너 건강 상태 점검 +2. 태그 발화 및 데이터 정합성 검증 +3. 최신 요구사항 반영 업데이트 +4. D.intelligence GTM Toolkit 연계 자동화 + +## Audit Schedule + +| Frequency | Scope | Trigger | +|-----------|-------|---------| +| Weekly | Tag firing validation | 자동 스케줄 | +| Monthly | Full container review | 월간 리포트 | +| Quarterly | Architecture review | 분기 회의 | +| Ad-hoc | Issue investigation | 이슈 발생 시 | + +## Audit Checklist + +### 1. Container Health Check +- [ ] 버전 히스토리 확인 (최근 변경사항) +- [ ] 미사용 태그/트리거/변수 식별 +- [ ] 명명 규칙 준수 여부 +- [ ] 폴더 구조 정리 상태 + +### 2. Tag Firing Validation +- [ ] 모든 P1 태그 정상 발화 +- [ ] 트리거 조건 정확성 +- [ ] 변수 값 정확성 +- [ ] 차단 트리거 작동 + +### 3. Data Quality +- [ ] GA4 Realtime 데이터 확인 +- [ ] 전환 데이터 정합성 +- [ ] 파라미터 값 검증 +- [ ] 이상치 탐지 + +### 4. Platform Sync +- [ ] GA4 ↔ GTM 동기화 +- [ ] Google Ads 전환 데이터 +- [ ] Meta Events Manager 상태 +- [ ] Kakao Pixel 상태 + +## D.intelligence GTM Toolkit Integration + +### Repository +``` +https://github.com/ourdigital/dintel-gtm-toolkit +``` + +### Capabilities + +| Feature | Description | Use Case | +|---------|-------------|----------| +| Container Analysis | JSON 파싱, 구조 분석 | 컨테이너 리뷰 | +| Dependency Mapping | 태그↔트리거↔변수 관계 | 영향도 분석 | +| Version Diff | 버전 간 변경사항 비교 | 변경 추적 | +| Tag Validation | 발화 상태 자동 검증 | 정기 감사 | + +### Integration Workflow + +``` +1. GTM Container Export + └── JSON 파일 다운로드 + +2. D.intel Toolkit Analysis + ├── python analyze_container.py container.json + ├── Dependency graph 생성 + └── Issue detection + +3. Report Generation + └── Markdown/HTML 리포트 + +4. GTM Guardian Update + └── Notion에 리포트 저장 +``` + +### Sample Toolkit Commands + +```bash +# Container 분석 +python analyze_container.py GTM-XXXXXX.json --output report.md + +# 버전 비교 +python diff_versions.py v1.json v2.json --output diff.md + +# 태그 검증 +python validate_tags.py container.json --events events.csv + +# 미사용 요소 탐지 +python find_unused.py container.json --type all +``` + +## Audit Report Template + +```markdown +# GTM Audit Report + +## Summary +- **Container**: GTM-XXXXXX +- **Audit Date**: YYYY-MM-DD +- **Version Reviewed**: XX +- **Overall Status**: ✅ Healthy / ⚠️ Needs Attention / ❌ Critical + +## Findings + +### ✅ Passing +- [항목] + +### ⚠️ Warnings +| Issue | Impact | Recommendation | +|-------|--------|----------------| + +### ❌ Critical +| Issue | Impact | Action Required | +|-------|--------|-----------------| + +## Tag Firing Status + +| Tag | Expected | Actual | Status | +|-----|----------|--------|--------| +| GA4 - Event - purchase | Thank You | Thank You | ✅ | + +## Data Quality Check + +| Metric | Expected | Actual | Variance | +|--------|----------|--------|----------| +| Daily Purchases | ~50 | 48 | -4% | + +## Recommendations +1. +2. + +## Next Steps +- [ ] +- [ ] + +## Appendix +- Container JSON snapshot +- D.intel Toolkit output +``` + +## Update Procedures + +### Minor Update (태그 수정) +``` +1. 변경 필요 태그 식별 +2. Preview 모드에서 수정 +3. 테스트 완료 +4. Publish with version note +5. Notion 문서 업데이트 +``` + +### Major Update (신규 태그 추가) +``` +1. Phase 3-4 문서 업데이트 +2. DataLayer 요구사항 개발팀 전달 +3. GTM 태그/트리거/변수 설정 +4. QA 체크리스트 수행 +5. 단계적 배포 +6. Notion 문서 업데이트 +``` + +### Emergency Fix +``` +1. 이슈 원인 파악 +2. 최소 변경으로 수정 +3. Publish (emergency version note) +4. 근본 원인 분석 +5. 영구 수정 계획 +``` + +## Versioning Best Practices + +### Version Naming +``` +v[Major].[Minor] - [Description] +예: v12.1 - Added form_submit event +``` + +### Version Notes Template +``` +## Changes +- Added: [새로 추가된 항목] +- Modified: [수정된 항목] +- Removed: [삭제된 항목] + +## Reason +[변경 이유] + +## Testing +- [테스트 항목 및 결과] + +## Rollback Plan +[롤백 필요 시 절차] +``` + +## Monitoring Setup + +### GA4 Alerts +- 일일 전환 수 급감 (>30%) +- 세션 수 급감 (>50%) +- 이벤트 수집 오류 + +### Custom Monitoring +- DataLayer 오류 로깅 +- Tag Manager 오류 추적 +- 서버 사이드 태그 상태 (sGTM 시) + +## Next Phase + +주기적 감사 완료 후 → Phase 7: Lookup App (필요 시) diff --git a/custom-skills/62-gtm-validator/code/references/phase7-lookup-app.md b/custom-skills/62-gtm-validator/code/references/phase7-lookup-app.md new file mode 100644 index 0000000..0350783 --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/phase7-lookup-app.md @@ -0,0 +1,283 @@ +# Phase 7: Event Lookup & Parameter Library Web App + +Google Apps Script를 활용한 Event Taxonomy Sheet 기반 업무 지원용 앱 배포. + +## Objectives + +1. Event Taxonomy 데이터 조회 앱 +2. 실시간 파라미터 참조 도구 +3. 비개발자용 Self-service 도구 +4. 팀 간 일관된 이벤트 정보 공유 + +## App Architecture + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Google Sheets │────▶│ Apps Script │────▶│ Web App │ +│ (Taxonomy DB) │ │ (Backend) │ │ (Frontend) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +## Google Sheets Data Source + +### Required Sheets +- Events Master +- Parameters Reference +- Custom Definitions +- Platform Mapping + +### Column Requirements +→ Phase 4 참조: [phase4-taxonomy.md](phase4-taxonomy.md) + +## Apps Script Setup + +### 1. Project Creation +``` +1. Google Sheets 열기 +2. Extensions > Apps Script +3. 프로젝트 이름 설정 +``` + +### 2. Core Functions + +#### Data Retrieval +```javascript +function getEventsData() { + const sheet = SpreadsheetApp.getActiveSpreadsheet() + .getSheetByName('Events Master'); + const data = sheet.getDataRange().getValues(); + const headers = data[0]; + + return data.slice(1).map(row => { + const obj = {}; + headers.forEach((header, i) => { + obj[header] = row[i]; + }); + return obj; + }); +} + +function getParametersData() { + const sheet = SpreadsheetApp.getActiveSpreadsheet() + .getSheetByName('Parameters Reference'); + const data = sheet.getDataRange().getValues(); + const headers = data[0]; + + return data.slice(1).map(row => { + const obj = {}; + headers.forEach((header, i) => { + obj[header] = row[i]; + }); + return obj; + }); +} +``` + +#### Search Function +```javascript +function searchEvents(query) { + const events = getEventsData(); + const searchTerm = query.toLowerCase(); + + return events.filter(event => + event.event_name.toLowerCase().includes(searchTerm) || + event.event_category.toLowerCase().includes(searchTerm) || + event.notes.toLowerCase().includes(searchTerm) + ); +} + +function getEventDetails(eventName) { + const events = getEventsData(); + const params = getParametersData(); + + const event = events.find(e => e.event_name === eventName); + if (!event) return null; + + const eventParams = event.parameters.split(',').map(p => p.trim()); + const paramDetails = params.filter(p => + eventParams.includes(p.parameter_name) + ); + + return { + event: event, + parameters: paramDetails + }; +} +``` + +### 3. Web App Handler + +```javascript +function doGet(e) { + return HtmlService.createHtmlOutputFromFile('index') + .setTitle('GTM Event Lookup') + .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); +} + +function doPost(e) { + const action = e.parameter.action; + + switch(action) { + case 'search': + return ContentService.createTextOutput( + JSON.stringify(searchEvents(e.parameter.query)) + ).setMimeType(ContentService.MimeType.JSON); + + case 'details': + return ContentService.createTextOutput( + JSON.stringify(getEventDetails(e.parameter.eventName)) + ).setMimeType(ContentService.MimeType.JSON); + + default: + return ContentService.createTextOutput( + JSON.stringify({error: 'Invalid action'}) + ).setMimeType(ContentService.MimeType.JSON); + } +} +``` + +### 4. HTML Frontend (index.html) + +```html + + + + + + + +

🏷️ GTM Event Lookup

+ +
+ + + + +``` + +## Deployment + +### 1. Deploy as Web App +``` +1. Deploy > New deployment +2. Type: Web app +3. Execute as: Me +4. Access: Anyone within organization (또는 Anyone) +5. Deploy +``` + +### 2. Get Web App URL +``` +배포 후 제공되는 URL 복사 +https://script.google.com/macros/s/[ID]/exec +``` + +### 3. Share with Team +- URL을 Notion/Slack에 공유 +- 북마크 권장 + +## Features Roadmap + +### Phase 1 (MVP) +- [x] 이벤트 검색 +- [x] 파라미터 조회 +- [x] 우선순위 필터 + +### Phase 2 +- [ ] DataLayer 코드 스니펫 복사 +- [ ] 플랫폼별 코드 예시 +- [ ] 최근 조회 히스토리 + +### Phase 3 +- [ ] 이벤트 추가/수정 폼 +- [ ] 변경 이력 추적 +- [ ] Slack 알림 연동 + +## Maintenance + +### Data Update +1. Google Sheets 원본 데이터 수정 +2. Web App 자동 반영 (실시간) + +### Code Update +1. Apps Script 수정 +2. Deploy > Manage deployments +3. New version 배포 + +### Backup +- Google Sheets 자동 버전 히스토리 +- 주기적 수동 백업 권장 + +## Access Control + +| Role | Access Level | +|------|--------------| +| Admin | 시트 편집 + 스크립트 수정 | +| Editor | 시트 편집 | +| Viewer | Web App 조회만 | + +## Troubleshooting + +| Issue | Solution | +|-------|----------| +| 앱 로딩 느림 | 데이터 캐싱 구현 | +| 검색 결과 없음 | 검색어 확인, 데이터 존재 확인 | +| 권한 오류 | 배포 설정에서 접근 권한 확인 | +| 데이터 미반영 | 시트 새로고침, 캐시 클리어 | + +## Integration with Notion + +Web App URL을 Notion에 embed: +``` +/embed [Web App URL] +``` + +또는 iframe으로 직접 삽입. diff --git a/custom-skills/62-gtm-validator/code/references/platform-mapping.md b/custom-skills/62-gtm-validator/code/references/platform-mapping.md new file mode 100644 index 0000000..e8bbc18 --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/platform-mapping.md @@ -0,0 +1,125 @@ +# Platform Event Mapping Reference + +GA4, Google Ads, Meta Pixel, Kakao Pixel 간 이벤트 매핑. + +## E-commerce Events + +| User Action | GA4 | Meta | Kakao | Google Ads | +|-------------|-----|------|-------|------------| +| 상품 목록 조회 | view_item_list | ViewContent | viewContent | - | +| 상품 상세 조회 | view_item | ViewContent | viewContent | - | +| 상품 검색 | search | Search | search | - | +| 장바구니 담기 | add_to_cart | AddToCart | addToCart | - | +| 위시리스트 | add_to_wishlist | AddToWishlist | addToWishlist | - | +| 결제 시작 | begin_checkout | InitiateCheckout | beginCheckout | - | +| 배송정보 입력 | add_shipping_info | - | - | - | +| 결제정보 입력 | add_payment_info | AddPaymentInfo | addPaymentInfo | - | +| 구매 완료 | purchase | Purchase | purchase | purchase | + +## Lead Gen Events + +| User Action | GA4 | Meta | Kakao | Google Ads | +|-------------|-----|------|-------|------------| +| 회원가입 | sign_up | CompleteRegistration | completeRegistration | sign_up | +| 로그인 | login | - | login | - | +| 리드 생성 | generate_lead | Lead | participation | submit_lead_form | + +## Engagement Events + +| User Action | GA4 | Meta | Kakao | Google Ads | +|-------------|-----|------|-------|------------| +| 페이지 조회 | page_view | PageView | pageView | page_view | +| 검색 | search | Search | search | - | +| 공유 | share | - | - | - | + +## Parameter Transformation + +### GA4 → Meta +```javascript +// GA4 items[] → Meta content_ids[] +const contentIds = items.map(item => item.item_id); + +// Meta Purchase +fbq('track', 'Purchase', { + content_ids: contentIds, + content_type: 'product', + value: ecommerce.value, + currency: 'KRW', + num_items: items.length +}); +``` + +### GA4 → Kakao +```javascript +// GA4 items[] → Kakao products[] +const products = items.map(item => ({ + id: item.item_id, + name: item.item_name, + price: item.price, + quantity: item.quantity +})); + +// Kakao purchase +kakaoPixel('PIXEL_ID').purchase({ + total_price: ecommerce.value, + currency: 'KRW', + products: products +}); +``` + +## GTM Variables + +### CJS - Item IDs for Meta +```javascript +function() { + var items = {{DLV - ecommerce.items}} || []; + return items.map(function(item) { + return item.item_id; + }); +} +``` + +### CJS - Products for Kakao +```javascript +function() { + var items = {{DLV - ecommerce.items}} || []; + return items.map(function(item) { + return { + id: item.item_id, + name: item.item_name, + price: item.price, + quantity: item.quantity + }; + }); +} +``` + +## Deduplication + +### Event ID Pattern +```javascript +var eventId = 'evt_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); + +// Client-side +fbq('track', 'Purchase', {...}, {eventID: eventId}); + +// Server-side (CAPI) +// 동일한 eventId 사용 → Meta 자동 중복 제거 +``` + +## Platform-specific Notes + +### Meta Pixel +- content_type: 'product' (상품) / 'product_group' (변형) +- currency: ISO 4217 필수 +- value: 숫자 (소수점 가능) + +### Kakao Pixel +- Server-side 미지원 (Client-only) +- products[]: 최대 10개 권장 +- total_price: 숫자 + +### Google Ads +- Enhanced Conversions 권장 +- transaction_id 필수 (중복 제거용) +- value: KRW 정수 diff --git a/custom-skills/62-gtm-validator/code/references/qa-checklist.md b/custom-skills/62-gtm-validator/code/references/qa-checklist.md new file mode 100644 index 0000000..92bf407 --- /dev/null +++ b/custom-skills/62-gtm-validator/code/references/qa-checklist.md @@ -0,0 +1,149 @@ +# GTM Implementation QA Checklist + +태깅 구현 품질 검증 체크리스트. + +## 1. Pre-Implementation + +### Documentation +- [ ] Tagging Plan 승인 완료 +- [ ] DataLayer 스키마 개발팀 공유 +- [ ] 이벤트 택소노미 합의 완료 + +### Access +- [ ] GTM 컨테이너 접근 권한 +- [ ] GA4 속성 접근 권한 +- [ ] 광고 플랫폼 접근 권한 + +### Tools +- [ ] GTM Preview 모드 정상 +- [ ] GA4 DebugView 활성화 +- [ ] Chrome DevTools 준비 + +## 2. DataLayer Validation + +### Base Setup +- [ ] GTM 스니펫 이전 dataLayer 초기화 +- [ ] 페이지 로드 시 기본 데이터 push +- [ ] pageType, userId 등 기본 변수 존재 + +### Data Types +- [ ] 숫자 값이 Number 타입 +- [ ] 금액에 통화 코드 포함 (KRW) +- [ ] transaction_id 유니크 + +### E-commerce +- [ ] ecommerce: null 선행 push +- [ ] items[] 배열 구조 정확 +- [ ] 필수 파라미터 완비 + +### Console Check +```javascript +console.log(window.dataLayer); +dataLayer.filter(e => e.event === 'purchase'); +``` + +## 3. Tag Firing + +### GA4 +| Tag | Trigger | Status | +|-----|---------|--------| +| Config | All Pages | [ ] | +| view_item | Product page | [ ] | +| add_to_cart | Add button | [ ] | +| begin_checkout | Checkout start | [ ] | +| purchase | Thank you | [ ] | + +### Google Ads +| Conversion | Trigger | Status | +|------------|---------|--------| +| Purchase | DL - purchase | [ ] | +| Lead | DL - generate_lead | [ ] | + +### Meta Pixel +| Event | Trigger | Status | +|-------|---------|--------| +| PageView | All Pages | [ ] | +| ViewContent | Product | [ ] | +| AddToCart | Add | [ ] | +| Purchase | Thank you | [ ] | + +### Kakao Pixel +| Event | Trigger | Status | +|-------|---------|--------| +| pageView | All Pages | [ ] | +| purchase | Thank you | [ ] | + +## 4. Network Validation + +### Endpoints +``` +GA4: google-analytics.com/g/collect +GAds: googleads.g.doubleclick.net/pagead/conversion/ +Meta: facebook.com/tr/ +``` + +### Check Points +- [ ] 요청 전송됨 +- [ ] 파라미터 정확 +- [ ] 응답 성공 (200/204) + +## 5. Cross-browser Testing + +### Desktop +- [ ] Chrome +- [ ] Safari +- [ ] Firefox +- [ ] Edge + +### Mobile +- [ ] iOS Safari +- [ ] iOS Chrome +- [ ] Android Chrome + +## 6. Data Validation (Platform) + +### GA4 +- [ ] Realtime 보고서 이벤트 표시 +- [ ] 파라미터 정확히 수집 +- [ ] E-commerce 보고서 정확 + +### Google Ads +- [ ] 전환 액션 데이터 유입 +- [ ] 전환 값 정확 + +### Meta +- [ ] Events Manager 수신 확인 +- [ ] Event match quality 확인 + +## 7. Edge Cases + +- [ ] 빈 장바구니 결제 시작 처리 +- [ ] 0개 구매 처리 +- [ ] 쿠폰 없는 구매 +- [ ] 게스트 체크아웃 +- [ ] 새로고침 시 중복 방지 +- [ ] 뒤로가기 시 처리 + +## 8. Performance & Privacy + +### Performance +- [ ] 태그 로딩이 렌더링 차단 안 함 +- [ ] 비동기 로딩 + +### Privacy +- [ ] 동의 없이 태그 미발화 (CMP 시) +- [ ] PII 직접 수집 없음 + +## Sign-off + +| Role | Name | Date | ✓ | +|------|------|------|---| +| QA Lead | | | | +| Analytics Lead | | | | +| Dev Lead | | | | + +## Issues Log + +| # | Issue | Severity | Status | +|---|-------|----------|--------| +| 1 | | High/Med/Low | Open/Resolved |