claude-code-arcane 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.4.0](https://github.com/SebastianLuser/claude-code-arcane/compare/v1.3.0...v1.4.0) (2026-06-22)
2
+
3
+
4
+ ### Features
5
+
6
+ * **ecommerce:** add language-agnostic +ecommerce addon profile ([4ccfc38](https://github.com/SebastianLuser/claude-code-arcane/commit/4ccfc387e7ae48672a3ce5ddbc18bf778f68c883))
7
+
1
8
  # [1.3.0](https://github.com/SebastianLuser/claude-code-arcane/compare/v1.2.0...v1.3.0) (2026-06-21)
2
9
 
3
10
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Claude Code Arcane
2
2
 
3
- > **321 skills, 86 agents, 15 hooks and 19 rules for Claude Code — selective deploy by profile.**
3
+ > **333 skills, 87 agents, 15 hooks and 19 rules for Claude Code — selective deploy by profile.**
4
4
 
5
5
  A configuration harness installable via `npx`. Pick a **profile** that matches your stack and only the relevant tools get installed into your project's `.claude/` directory.
6
6
 
@@ -193,6 +193,7 @@ Once installed, manage the installation from within a Claude Code session:
193
193
  | `+marketing` | Content, growth, SEO/CRO, strategy, analytics | 44 | marketing |
194
194
  | `+regulatory` | ISO 13485, GDPR, FDA, SOC 2, ISMS, QMS, MDR | 13 | regulatory |
195
195
  | `+job-hunt` | Job search end-to-end — master profile, ATS CV, LinkedIn, portfolio, cover letters, outreach, interview prep | 12 | — |
196
+ | `+ecommerce` | Commerce end-to-end agnóstico de lenguaje — data model, checkout, inventario, órdenes, pagos, promociones, shipping/tax, listings, analytics, feeds, storefront, suscripciones | 12 | ecommerce |
196
197
  | `+self-improving` | Agent self-improvement and skill extraction | 2 | — |
197
198
  | `+statusline` | Claude Code status bar (branch, division, session info) | 0 | — |
198
199
 
@@ -347,7 +348,7 @@ claude-code-arcane/
347
348
  │ ├── manifest.ts # Read/write arcane-manifest.json
348
349
  │ ├── types.ts # TypeScript interfaces
349
350
  │ └── utils.ts # Cross-platform helpers
350
- ├── skills/ # 321 skills (flat, one dir per skill)
351
+ ├── skills/ # 333 skills (flat, one dir per skill)
351
352
  ├── profiles/ # 29 profiles (YAML)
352
353
  ├── agents/ # 13 dirs, 86+ agents (Markdown)
353
354
  ├── hooks/ # 15 lifecycle hooks (Bash)
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: ecommerce-architect
3
+ description: "E-Commerce Architect. Owner del dominio commerce: modelado de catálogo, selección de plataforma (headless vs monolito vs SaaS), y review de diseño de checkout, pagos, inventario y órdenes. Agnóstico de lenguaje/framework. Usar como punto de entrada para arquitectura de un storefront o marketplace."
4
+ tools: Read, Glob, Grep, Write, Edit, WebSearch
5
+ model: opus
6
+ maxTurns: 30
7
+ memory: project
8
+ disallowedTools: Bash
9
+ skills: [commerce-data-model, payments-architecture, order-lifecycle, inventory-stock, storefront-architecture]
10
+ ---
11
+
12
+ Sos el **E-Commerce Architect**. Tu rol: diseñar y revisar la arquitectura de dominio de un negocio de commerce — agnóstico de lenguaje, framework y plataforma. Decisiones de modelado y arquitectura, no código atado a un stack.
13
+
14
+ ## Responsabilidades
15
+
16
+ 1. **Domain modeling** — catálogo (product/variant/SKU), órdenes, inventario, pagos
17
+ 2. **Platform selection** — headless vs monolito vs SaaS vs composable, con trade-offs
18
+ 3. **Flow review** — checkout, pagos (idempotencia), inventario (overselling), órdenes (state machine)
19
+ 4. **Data integrity** — concurrencia, reservas, reconciliación de pagos
20
+ 5. **Routing** — derivar a la skill correcta según la necesidad
21
+
22
+ ## Routing Map
23
+
24
+ | Necesidad | Skill |
25
+ |-----------|-------|
26
+ | Modelar catálogo / variantes / taxonomía / facets | `commerce-data-model` |
27
+ | Carrito, checkout, abandoned-cart | `cart-checkout` |
28
+ | Stock, overselling, restock forecast | `inventory-stock` |
29
+ | Estados de orden, returns, refunds | `order-lifecycle` |
30
+ | Arquitectura de pagos, webhooks, PCI | `payments-architecture` |
31
+ | Implementación Stripe específica | `stripe-integration-expert` |
32
+ | Promos, cupones, gift cards | `promotions-discounts` |
33
+ | Envíos, impuestos, duties | `shipping-tax` |
34
+ | Listings / PDP / marketplace copy | `product-listing` |
35
+ | KPIs y eventos GA4 ecommerce | `commerce-analytics` |
36
+ | Feeds Google/Meta | `merchant-feed` |
37
+ | IA del storefront, páginas, headless | `storefront-architecture` |
38
+ | Suscripciones, dunning | `subscription-billing` |
39
+
40
+ ## Protocolo (non-negotiables)
41
+
42
+ 1. **Data model primero** — sin un modelo de catálogo sólido, no se diseña checkout ni feeds.
43
+ 2. **Idempotencia en pagos** — toda creación de cargo lleva idempotency key. No se discute.
44
+ 3. **Server-authoritative** — precios, stock, impuestos y promos se recalculan en el server antes de cobrar.
45
+ 4. **Money en minor units enteros** — nunca floats para dinero.
46
+ 5. **Estados separados** — order / payment / fulfillment son dimensiones independientes.
47
+ 6. **Agnóstico** — si el pedido empuja a un framework concreto, lo aclarás y derivás a la skill/implementador correspondiente; no atás el diseño a un stack salvo que el usuario lo decida.
48
+
49
+ ## Platform Decision Matrix
50
+
51
+ | Opción | Para | Costo |
52
+ |--------|------|-------|
53
+ | Monolito (SaaS/themed) | Time-to-market, catálogo estándar | Menos flexibilidad |
54
+ | Headless | UX custom, omnichannel, escala | Mayor build/ops |
55
+ | Composable | Enterprise, best-of-breed | Complejidad de integración |
56
+
57
+ ## Delegation
58
+
59
+ **Delegate to:** las skills del routing map según el área.
60
+ **Escala a humano:** decisiones de compliance fiscal (nexus, VAT) y selección final de PSP/plataforma — presentás opciones con trade-offs, decide el negocio.
@@ -1,6 +1,6 @@
1
1
  # Skills Catalog — Claude Code Arcane
2
2
 
3
- Catalogo completo de los 321 skills disponibles para proyectos consumidores. Organizados por division.
3
+ Catalogo completo de los 333 skills disponibles para proyectos consumidores. Organizados por division.
4
4
 
5
5
  ## Como ejecutar un skill
6
6
 
@@ -451,6 +451,25 @@ Desde cualquier proyecto que tenga Arcane configurado, escribi `/` seguido del n
451
451
 
452
452
  ---
453
453
 
454
+ ## E-Commerce (12 skills)
455
+
456
+ | Skill | Descripcion | Uso |
457
+ |-------|-------------|-----|
458
+ | `/commerce-data-model` | Modela y audita el dominio de catalogo: product/variant/SKU/option, collections, atributos, taxonomia, faceted search y paginacion | `[model\|audit\|taxonomy]` |
459
+ | `/cart-checkout` | Disena/audita carrito y checkout: estado del cart, multi-step vs one-page, guest checkout, abandoned-cart recovery | `[design\|audit\|abandoned]` |
460
+ | `/inventory-stock` | Inventario y stock: tracking, optimistic locking anti-overselling, reservas, multi-location, restock forecast (script) | `[design\|forecast\|audit]` |
461
+ | `/order-lifecycle` | State machine de ordenes: order/payment/fulfillment, returns/RMA, refunds, eventos/webhooks | `[design\|states\|returns]` |
462
+ | `/payments-architecture` | Arquitectura de pagos PSP-agnostica: payment intents, idempotencia, webhooks fiables, reconciliacion, PCI, fraude | `[design\|webhooks\|audit]` |
463
+ | `/promotions-discounts` | Motor de promociones: cupones, automaticos, BOGO, tiered, reglas de stacking/exclusividad, gift cards | `[design\|rules\|audit]` |
464
+ | `/shipping-tax` | Envios (zonas/rates/metodos) e impuestos (VAT/GST/nexus, duties, landed cost) calculados server-side | `[shipping\|tax\|audit]` |
465
+ | `/product-listing` | Optimiza PDP y listings de marketplace (Amazon A10/COSMO/Rufus), titulos, bullets, A+, copy en bulk | `[pdp\|marketplace\|bulk]` |
466
+ | `/commerce-analytics` | KPIs de commerce (CR, AOV, CLV, cohort) + spec de eventos GA4 ecommerce + validador de dataLayer (script) | `[kpis\|events\|audit]` |
467
+ | `/merchant-feed` | Feeds de producto Google Merchant / Meta Catalog: atributos requeridos, mapping y validacion (script) | `[validate\|generate\|map]` |
468
+ | `/storefront-architecture` | IA del storefront (home/PLP/PDP/cart/checkout/search/megamenu) + decision headless-vs-monolito + performance | `[design\|pages\|headless]` |
469
+ | `/subscription-billing` | Billing recurrente: modelos, ciclos, proration, trials, plan changes y dunning anti-churn involuntario | `[design\|dunning\|audit]` |
470
+
471
+ ---
472
+
454
473
  ## Skills internos de Arcane
455
474
 
456
475
  Estos skills son para mantener y desarrollar el propio repo Arcane:
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## What is Arcane?
4
4
 
5
- Arcane is a configuration harness for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It provides a curated library of **321 skills**, **86 agents**, **15 hooks**, and **19 rules** that you selectively deploy into any project. Instead of shipping everything to every project (wasting tokens and degrading performance), you pick a **profile** that matches your stack and only the relevant tools get installed.
5
+ Arcane is a configuration harness for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It provides a curated library of **333 skills**, **87 agents**, **15 hooks**, and **19 rules** that you selectively deploy into any project. Instead of shipping everything to every project (wasting tokens and degrading performance), you pick a **profile** that matches your stack and only the relevant tools get installed.
6
6
 
7
7
  ## Table of Contents
8
8
 
@@ -536,7 +536,7 @@ Yes, and it's recommended. This way everyone on the team gets the same Claude Co
536
536
 
537
537
  ### How many tokens does a profile consume?
538
538
 
539
- Each skill adds ~30-100 tokens to the system prompt. A typical base profile (20-30 skills) adds ~1-2k tokens. The core profile adds ~500 tokens. Compare that to loading all 321 skills, which is why selective deploy matters.
539
+ Each skill adds ~30-100 tokens to the system prompt. A typical base profile (20-30 skills) adds ~1-2k tokens. The core profile adds ~500 tokens. Compare that to loading all 333 skills, which is why selective deploy matters.
540
540
 
541
541
  ### Why replace instead of merge on install?
542
542
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-arcane",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Skills, agents, hooks and rules for Claude Code — installable via npx arcane",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,48 @@
1
+ name: ecommerce
2
+ description: "E-Commerce — dominio commerce end-to-end agnostico de lenguaje: data model, carrito/checkout, inventario, ordenes, pagos, promociones, shipping/tax, listings, analytics, feeds, storefront y suscripciones"
3
+ type: addon
4
+
5
+ skills:
6
+ # net-new (12)
7
+ - commerce-data-model
8
+ - cart-checkout
9
+ - inventory-stock
10
+ - order-lifecycle
11
+ - payments-architecture
12
+ - promotions-discounts
13
+ - shipping-tax
14
+ - product-listing
15
+ - commerce-analytics
16
+ - merchant-feed
17
+ - storefront-architecture
18
+ - subscription-billing
19
+ # reutilizadas (existentes, relevantes a e-commerce)
20
+ - stripe-integration-expert
21
+ - page-cro
22
+ - form-cro
23
+ - schema-markup
24
+ - seo-audit
25
+ - analytics-tracking
26
+ - pricing-strategy
27
+ - ab-test-setup
28
+ - referral-program
29
+
30
+ rules:
31
+ universal:
32
+ []
33
+ gamedev:
34
+ []
35
+
36
+ agents:
37
+ - ecommerce
38
+
39
+ permissions:
40
+ allow:
41
+ - "Bash(python *restock_forecast.py*)"
42
+ - "Bash(python3 *restock_forecast.py*)"
43
+ - "Bash(python *ga4_ecommerce_validate.py*)"
44
+ - "Bash(python3 *ga4_ecommerce_validate.py*)"
45
+ - "Bash(python *feed_validate.py*)"
46
+ - "Bash(python3 *feed_validate.py*)"
47
+ deny:
48
+ []
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: cart-checkout
3
+ description: "Design and audit cart and checkout flows — cart state, multi-step vs one-page checkout, guest checkout, address/shipping/tax/payment steps, and abandoned-cart recovery. Platform-agnostic conversion and correctness patterns. Triggers: designing a checkout, auditing drop-off, planning abandoned-cart flows."
4
+ argument-hint: "[design | audit | abandoned]"
5
+ category: "ecommerce"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep
8
+ ---
9
+
10
+ # Cart & Checkout
11
+
12
+ The highest-leverage surface in commerce: where intent becomes revenue. Design carts and checkouts that are correct under concurrency and optimized for completion — without prescribing a framework.
13
+
14
+ ## Before Starting
15
+
16
+ Gather: cart model (server-persisted vs client, guest vs account), checkout type (single vs multi-step), payment/shipping/tax requirements, and goal (design new flow, audit drop-off, or build abandoned-cart recovery).
17
+
18
+ ## How This Skill Works
19
+
20
+ | Mode | Trigger | Output |
21
+ |------|---------|--------|
22
+ | **Design** | `design` | Cart state model + checkout step flow + edge cases |
23
+ | **Audit** | `audit` | Friction/drop-off analysis with prioritized fixes |
24
+ | **Abandoned** | `abandoned` | Recovery sequence (triggers, timing, channels) |
25
+
26
+ ---
27
+
28
+ ## Phase 1 — Cart State
29
+
30
+ | Decision | Recommendation |
31
+ |----------|----------------|
32
+ | Persistence | Server-side cart keyed by session + user; merge on login |
33
+ | Pricing | **Re-price at checkout** — never trust cart-stored prices |
34
+ | Inventory | Soft-reserve at checkout start, not on add-to-cart |
35
+ | Identity | Allow guest carts; merge guest → account without losing items |
36
+
37
+ **Rule:** The cart is a draft, not a contract. Totals, stock, and promotions are recomputed server-side before payment.
38
+
39
+ ---
40
+
41
+ ## Phase 2 — Checkout Flow
42
+
43
+ Canonical steps: **Cart → Identity → Shipping address → Shipping method → Payment → Review → Confirmation.**
44
+
45
+ - **Guest checkout** is non-negotiable for B2C — forced account creation is the #1 avoidable drop-off.
46
+ - Collect email first (enables abandoned-cart + receipts).
47
+ - One-page vs multi-step: multi-step for complex shipping/tax; one-page for low-SKU/digital. Either way, show progress and never lose entered data on validation error.
48
+ - Recompute tax/shipping when the address changes; show the final total before the pay button.
49
+ - Make payment **idempotent** — a double-click must not double-charge (hand off to `payments-architecture`).
50
+
51
+ For the full step-by-step field list, error handling, and address validation patterns, see [references/checkout-flow-spec.md](references/checkout-flow-spec.md).
52
+
53
+ ---
54
+
55
+ ## Phase 3 — Abandoned-Cart Recovery
56
+
57
+ | Touch | Timing | Angle |
58
+ |-------|--------|-------|
59
+ | 1 | ~1h | Reminder ("you left these") |
60
+ | 2 | ~24h | Help/objection handling + reviews |
61
+ | 3 | ~72h | Incentive (discount) — only if margin allows |
62
+
63
+ Capture email as early as possible; suppress recovery once the order completes; respect consent and frequency caps.
64
+
65
+ ---
66
+
67
+ ## Output Artifacts
68
+
69
+ | Request | Output |
70
+ |---------|--------|
71
+ | Design flow | Cart model + annotated step diagram + edge-case list |
72
+ | Audit | Drop-off table with severity and READY-to-ship fixes |
73
+ | Abandoned | Trigger/timing/channel sequence + suppression rules |
74
+
75
+ A checkout is **READY** when guest checkout works, prices/stock are re-validated server-side, payment is idempotent, and data survives validation errors.
76
+
77
+ ---
78
+
79
+ ## Related Skills
80
+
81
+ - **payments-architecture**: owns the payment step (intents, idempotency, webhooks).
82
+ - **shipping-tax**: computes the shipping and tax shown at checkout.
83
+ - **promotions-discounts**: applies coupons/discounts at the cart.
84
+ - **page-cro** / **form-cro**: deeper conversion optimization of the checkout UI.
85
+ - **order-lifecycle**: takes over once the order is placed.
@@ -0,0 +1,50 @@
1
+ # Checkout Flow — Step-by-Step Spec
2
+
3
+ A platform-agnostic reference for a correct, conversion-optimized checkout. Adapt step granularity to your catalog (digital/low-SKU can collapse steps).
4
+
5
+ ## Steps, Fields & Validation
6
+
7
+ | Step | Fields | Validation / behavior |
8
+ |------|--------|-----------------------|
9
+ | **Cart** | line items, qty, totals | Editable qty; re-price + re-check stock server-side on load |
10
+ | **Identity** | email (required), login/guest | Collect email first; offer guest checkout prominently |
11
+ | **Shipping address** | name, address, country, postal | Inline validation; address autocomplete if available |
12
+ | **Shipping method** | method options + rates | Recompute on address change; show ETA + cost |
13
+ | **Payment** | payment method | Tokenized/hosted fields; idempotency key generated here |
14
+ | **Review** | full summary | Final total incl. tax/shipping/discounts before pay button |
15
+ | **Confirmation** | order number | Show + email receipt; clear cart; fire `purchase` event |
16
+
17
+ ## Server-Side Re-Validation (before charge)
18
+ Always recompute, never trust the client:
19
+ 1. Item availability (reserve with TTL)
20
+ 2. Prices (current catalog prices, not cart-stored)
21
+ 3. Promotions (re-evaluate eligibility + caps)
22
+ 4. Shipping + tax (against final address)
23
+ 5. Final total → only then create the payment intent
24
+
25
+ ## Error Handling
26
+ - Never clear entered fields on a validation error.
27
+ - Show errors inline next to the field, plus a summary.
28
+ - Payment decline → keep the order in a recoverable state; let the shopper retry without re-entering everything.
29
+ - Stock lost during checkout → tell the shopper exactly which line and offer alternatives.
30
+
31
+ ## Address Validation
32
+ - Normalize country to ISO code; postal format per country.
33
+ - Soft-validate (suggest correction) rather than hard-block where possible.
34
+
35
+ ## Abandoned-Cart Triggers
36
+ | Touch | Timing | Content |
37
+ |-------|--------|---------|
38
+ | 1 | ~1h | "You left these" + cart contents |
39
+ | 2 | ~24h | Objection handling, reviews, support offer |
40
+ | 3 | ~72h | Incentive (only if margin allows) |
41
+
42
+ Suppress all touches once `purchase` fires. Respect consent + frequency caps.
43
+
44
+ ## Verdict: READY when
45
+ - [ ] Guest checkout works end-to-end
46
+ - [ ] Email captured before payment
47
+ - [ ] All totals recomputed server-side pre-charge
48
+ - [ ] Payment is idempotent (no double-charge on retry/double-click)
49
+ - [ ] Entered data survives validation errors
50
+ - [ ] `purchase` event fires once with transaction id
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: commerce-analytics
3
+ description: "Define and audit e-commerce analytics — conversion rate, AOV, CLV, cohort/funnel metrics, and the standard GA4 ecommerce event spec (view_item, add_to_cart, begin_checkout, purchase). Includes a dataLayer event validator. Triggers: defining commerce KPIs, instrumenting GA4 ecommerce events, auditing tracking."
4
+ argument-hint: "[kpis | events | audit]"
5
+ category: "ecommerce"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Bash
8
+ ---
9
+
10
+ # Commerce Analytics
11
+
12
+ You cannot optimize what you mis-measure. Define the KPIs that actually move a store and instrument the standard ecommerce event spec correctly — platform-agnostic, with a validator for GA4 dataLayer events.
13
+
14
+ ## Before Starting
15
+
16
+ Gather: current tracking (GA4/GTM/other), business model (one-time vs subscription), key conversion actions, and goal (define KPIs, design/instrument events, or audit existing tracking).
17
+
18
+ ## How This Skill Works
19
+
20
+ | Mode | Trigger | Output |
21
+ |------|---------|--------|
22
+ | **KPIs** | `kpis` | KPI framework + dashboard spec |
23
+ | **Events** | `events` | Ecommerce event taxonomy + dataLayer spec |
24
+ | **Audit** | `audit` | Tracking gap + data-quality review |
25
+
26
+ ---
27
+
28
+ ## Phase 1 — Core KPIs
29
+
30
+ | Metric | Formula | Watch for |
31
+ |--------|---------|-----------|
32
+ | **Conversion rate** | orders / sessions | Segment by device/channel |
33
+ | **AOV** | revenue / orders | Moves with promos/bundles |
34
+ | **CLV** | avg order value × frequency × lifespan | The number that justifies CAC |
35
+ | **Cart abandonment** | 1 − (checkouts / carts) | Diagnoses checkout friction |
36
+ | **Repeat rate** | repeat customers / total | Retention health |
37
+ | **Sell-through** | units sold / units received | Feeds `inventory-stock` forecasts |
38
+
39
+ **Rule:** Pair every acquisition metric with a margin metric — revenue growth on negative contribution margin is a trap.
40
+
41
+ ---
42
+
43
+ ## Phase 2 — The Ecommerce Event Spec
44
+
45
+ The standard GA4 ecommerce funnel events, each carrying `currency` + an `items[]` array:
46
+
47
+ `view_item_list → view_item → add_to_cart → begin_checkout → add_shipping_info → add_payment_info → purchase` (plus `remove_from_cart`, `refund`).
48
+
49
+ Each `items[]` entry: `item_id`, `item_name`, `price`, `quantity` (+ optional `item_brand`, `item_category`, `item_variant`). `purchase` also needs `transaction_id` and `value`.
50
+
51
+ Validate a captured dataLayer against this spec:
52
+
53
+ ```bash
54
+ python skills/commerce-analytics/scripts/ga4_ecommerce_validate.py # demo events
55
+ python skills/commerce-analytics/scripts/ga4_ecommerce_validate.py events.json
56
+ ```
57
+
58
+ It reports PASS/FAIL per event with the missing required fields. For the full taxonomy and parameter reference, see [references/ga4-ecommerce-events.md](references/ga4-ecommerce-events.md).
59
+
60
+ ---
61
+
62
+ ## Phase 3 — Audit & Data Quality
63
+
64
+ Common faults: missing `transaction_id` (duplicate purchases), `value` excluding/including tax inconsistently, `items[]` absent on purchase, double-firing (GTM + hardcoded). Cross-check store revenue vs GA4 revenue — variance > 5% means a tracking bug.
65
+
66
+ ---
67
+
68
+ ## Output Artifacts
69
+
70
+ | Request | Output |
71
+ |---------|--------|
72
+ | KPIs | KPI framework + dashboard layout |
73
+ | Events | Event taxonomy + dataLayer spec |
74
+ | Audit | Gap analysis + data-quality scorecard |
75
+
76
+ Commerce tracking is **COMPLIANT** when the full funnel fires with valid `items[]` and `currency`, `purchase` carries a unique `transaction_id`, revenue reconciles within 5%, and KPIs pair growth with margin.
77
+
78
+ ---
79
+
80
+ ## Related Skills
81
+
82
+ - **analytics-tracking**: general GA4/GTM setup this builds on for SaaS-style funnels.
83
+ - **inventory-stock**: sell-through metrics feed restock forecasting.
84
+ - **commerce-data-model**: item taxonomy maps to `items[]` parameters.
85
+ - **ab-test-setup** / **campaign-analytics**: experimentation and campaign measurement.
@@ -0,0 +1,63 @@
1
+ # GA4 Ecommerce Event Taxonomy & Parameter Reference
2
+
3
+ The standard funnel. Fire these with a consistent `items[]` shape so reports, funnels, and audiences work. The `ga4_ecommerce_validate.py` script checks a captured dataLayer against this spec.
4
+
5
+ ## The funnel
6
+ ```
7
+ view_item_list → view_item → add_to_cart → view_cart → begin_checkout
8
+ → add_shipping_info → add_payment_info → purchase
9
+ ```
10
+ Plus: `select_item`, `remove_from_cart`, `refund`.
11
+
12
+ ## Required parameters per event
13
+ | Event | Required (beyond items[]) |
14
+ |-------|---------------------------|
15
+ | view_item | currency |
16
+ | add_to_cart / remove_from_cart / view_cart | currency |
17
+ | begin_checkout | currency |
18
+ | add_shipping_info | currency |
19
+ | add_payment_info | currency |
20
+ | purchase | currency, value, transaction_id |
21
+ | refund | currency, transaction_id |
22
+ | view_item_list / select_item | (item_list_id / item_list_name recommended) |
23
+
24
+ ## items[] object
25
+ | Field | Req? | Notes |
26
+ |-------|------|-------|
27
+ | item_id | yes | Map to SKU |
28
+ | item_name | yes | Product/variant name |
29
+ | price | recommended | Unit price (number) |
30
+ | quantity | recommended | Defaults to 1 |
31
+ | item_brand | optional | |
32
+ | item_category | optional | Up to item_category5 |
33
+ | item_variant | optional | e.g. "Red / M" |
34
+ | discount | optional | Per-unit discount |
35
+ | index | optional | Position in list |
36
+
37
+ ## Worked example — purchase
38
+ ```json
39
+ {
40
+ "event": "purchase",
41
+ "ecommerce": {
42
+ "currency": "USD",
43
+ "value": 42.00,
44
+ "transaction_id": "T-1001",
45
+ "tax": 3.50,
46
+ "shipping": 5.00,
47
+ "items": [
48
+ { "item_id": "ACME-TEE-RED-M", "item_name": "Acme Cotton Tee",
49
+ "item_variant": "Red / M", "price": 21.00, "quantity": 2 }
50
+ ]
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Common faults (audit checklist)
56
+ - [ ] `purchase` missing `transaction_id` → duplicate purchases on refresh
57
+ - [ ] `value` inconsistent about tax/shipping inclusion (pick one, document it)
58
+ - [ ] `items[]` absent or empty on funnel events
59
+ - [ ] Double-firing (GTM tag + hardcoded gtag)
60
+ - [ ] Currency missing → revenue not attributed
61
+ - [ ] Store revenue vs GA4 revenue variance > 5% → tracking bug
62
+
63
+ Verdict: **COMPLIANT** when the full funnel fires with valid `items[]` + `currency`, `purchase` has a unique `transaction_id`, and revenue reconciles within 5%.
@@ -0,0 +1,134 @@
1
+ """
2
+ ga4_ecommerce_validate.py — Validate a captured dataLayer against the GA4
3
+ standard ecommerce event spec.
4
+
5
+ Checks each event for: a known ecommerce event name, required top-level
6
+ parameters (currency/value/transaction_id where applicable), a non-empty
7
+ items[] array, and required per-item fields. No external dependencies.
8
+
9
+ Usage:
10
+ python ga4_ecommerce_validate.py # built-in demo events
11
+ python ga4_ecommerce_validate.py events.json # your captured dataLayer
12
+
13
+ Input JSON: either a single event object or an array of event objects, each:
14
+ {"event": "purchase", "ecommerce": {"currency": "USD", "value": 42.0,
15
+ "transaction_id": "T123", "items": [{"item_id": "SKU1",
16
+ "item_name": "Tee", "price": 21.0, "quantity": 2}, ...]}}
17
+
18
+ Some setups put params at the top level instead of under "ecommerce"; both
19
+ shapes are accepted.
20
+ """
21
+
22
+ import json
23
+ import sys
24
+
25
+
26
+ # event name -> required top-level (ecommerce) params beyond items[]
27
+ EVENT_REQS = {
28
+ "view_item_list": [],
29
+ "view_item": ["currency"],
30
+ "select_item": [],
31
+ "add_to_cart": ["currency"],
32
+ "remove_from_cart": ["currency"],
33
+ "view_cart": ["currency"],
34
+ "begin_checkout": ["currency"],
35
+ "add_shipping_info": ["currency"],
36
+ "add_payment_info": ["currency"],
37
+ "purchase": ["currency", "value", "transaction_id"],
38
+ "refund": ["currency", "transaction_id"],
39
+ }
40
+ EVENTS_REQUIRING_ITEMS = set(EVENT_REQS) - {"refund"}
41
+ ITEM_REQUIRED = ["item_id", "item_name"] # GA4 needs id or name; we require both for quality
42
+ ITEM_RECOMMENDED = ["price", "quantity"]
43
+
44
+
45
+ DEMO_EVENTS = [
46
+ {"event": "view_item", "ecommerce": {"currency": "USD",
47
+ "items": [{"item_id": "ACME-TEE", "item_name": "Acme Tee", "price": 21.0}]}},
48
+ {"event": "add_to_cart", "ecommerce": {"currency": "USD",
49
+ "items": [{"item_id": "ACME-TEE", "item_name": "Acme Tee", "price": 21.0, "quantity": 2}]}},
50
+ {"event": "purchase", "ecommerce": {"currency": "USD", "value": 42.0, "transaction_id": "T-1001",
51
+ "items": [{"item_id": "ACME-TEE", "item_name": "Acme Tee", "price": 21.0, "quantity": 2}]}},
52
+ # intentionally broken: missing transaction_id + value, item missing name
53
+ {"event": "purchase", "ecommerce": {"currency": "USD",
54
+ "items": [{"item_id": "ACME-MUG", "price": 9.0}]}},
55
+ {"event": "add_to_cart", "ecommerce": { # missing currency + empty items
56
+ "items": []}},
57
+ ]
58
+
59
+
60
+ def get_ecom(event):
61
+ """Return the param dict — under 'ecommerce' or at the top level."""
62
+ if isinstance(event.get("ecommerce"), dict):
63
+ return event["ecommerce"]
64
+ return {k: v for k, v in event.items() if k != "event"}
65
+
66
+
67
+ def validate_event(event, idx):
68
+ errors = []
69
+ name = event.get("event")
70
+ if not name:
71
+ return [f"event[{idx}]: missing 'event' name"], None
72
+ if name not in EVENT_REQS:
73
+ return [f"event[{idx}] '{name}': not a recognized GA4 ecommerce event"], name
74
+
75
+ ecom = get_ecom(event)
76
+
77
+ for param in EVENT_REQS[name]:
78
+ if param not in ecom or ecom[param] in (None, ""):
79
+ errors.append(f"missing required param '{param}'")
80
+
81
+ if name in EVENTS_REQUIRING_ITEMS:
82
+ items = ecom.get("items")
83
+ if not isinstance(items, list) or not items:
84
+ errors.append("missing or empty 'items[]'")
85
+ else:
86
+ for i, it in enumerate(items):
87
+ missing = [f for f in ITEM_REQUIRED if not it.get(f)]
88
+ if missing:
89
+ errors.append(f"items[{i}]: missing {', '.join(missing)}")
90
+ rec_missing = [f for f in ITEM_RECOMMENDED if it.get(f) in (None, "")]
91
+ if rec_missing:
92
+ errors.append(f"items[{i}]: (recommended) missing {', '.join(rec_missing)}")
93
+ return errors, name
94
+
95
+
96
+ def main():
97
+ if len(sys.argv) > 1:
98
+ path = sys.argv[1]
99
+ try:
100
+ with open(path, encoding="utf-8") as f:
101
+ data = json.load(f)
102
+ except (OSError, json.JSONDecodeError) as e:
103
+ print(f"[ERROR] cannot read {path}: {e}")
104
+ sys.exit(1)
105
+ else:
106
+ print("[INFO] No JSON given - using built-in demo events.\n")
107
+ data = DEMO_EVENTS
108
+
109
+ events = data if isinstance(data, list) else [data]
110
+
111
+ total_fail = 0
112
+ for idx, event in enumerate(events):
113
+ errors, name = validate_event(event, idx)
114
+ hard = [e for e in errors if "(recommended)" not in e]
115
+ if hard:
116
+ total_fail += 1
117
+ print(f"FAIL [{idx}] {name or '?'}")
118
+ for e in errors:
119
+ print(f" - {e}")
120
+ else:
121
+ warn = [e for e in errors if "(recommended)" in e]
122
+ print(f"PASS [{idx}] {name}")
123
+ for w in warn:
124
+ print(f" ~ {w}")
125
+
126
+ print()
127
+ passed = len(events) - total_fail
128
+ verdict = "COMPLIANT" if total_fail == 0 else "NON-COMPLIANT"
129
+ print(f"{verdict}: {passed}/{len(events)} events passed.")
130
+ sys.exit(0 if total_fail == 0 else 1)
131
+
132
+
133
+ if __name__ == "__main__":
134
+ main()