3.1 KiB
Architecture Conventions
Deployment Conventions
Multi-brand testing requirement
Any code change to shared services (audit pipeline, site-tag-analytics, synthesizers, categorizers, conversion type registry) must be verified against at least:
- One medical brand (cardiology or imaging) for dense events, multi-language data shapes, and HIPAA-relevant surfaces
- One service brand (lawn care portfolio) for high-volume events and multi-domain reconciliation
- One B2B brand (TPAction / AiGrowth360) for low-event-volume edge cases and lead gen flows
- One ecommerce brand if available for product schema and checkout flows
Verification recipes must specify at least two brands of different verticals. "Verify on cardiology" alone is insufficient.
Single-brand verification was the root cause of the Phase 19A.16 missed form_filled crash on Fairway Lawns (May 27, 2026).
Conversion type registration requirement
Before merging any change to shared event or conversion categorization code, run the comprehensive type discovery SQL:
SELECT "brandId", "conversionType", COUNT(*)
FROM "SiteConversion"
WHERE timestamp >= NOW() - INTERVAL '30 days'
AND "conversionType" NOT IN (
'appointment_booked','form_submitted','phone_call','email_contact',
'sms_contact','purchase','appointment_attempted','form_started',
'appointment_intent','chat_initiated','newsletter_signup','add_to_cart',
'checkout_started','file_download','waitlist_signup','form_filled',
'form_submit','form_submission','phone_number_click','click_to_call',
'calendly','booking_confirmed','booking_attempt','email_click',
'sms_click','phone_copy','phone_input','form_iframe_present',
'error_count_update'
)
GROUP BY "brandId", "conversionType"
ORDER BY count DESC;
Confirm zero rows returned, or explicitly handle every type returned before shipping.
New types must be registered in:
SITE_CONVERSION_TYPESinsrc/lib/services/site-tag-analytics.ts(query allowlist -- unregistered types are silently dropped)CONVERSION_TIERSinsrc/lib/conversions/tiers.ts(tier mapping -- unregistered types crash route.ts via undefined key lookup)
The defensive guard at src/app/api/site-tag/analytics/route.ts around
the tierTotals[cfg.tier] access will log a warning and skip rather than
crash for any future type that slips through, but the correct fix is always
to register the type proactively.
Tier assignment guidelines
| Tier | Description | isCounted | Examples |
|---|---|---|---|
| completed | Definitive conversion action | true | form_submit, phone_call, appointment_booked, purchase |
| intent | Started a conversion flow | false | form_filled, appointment_attempted, checkout_started |
| signal | Engagement only (no conversion flow) | false | phone_copy, phone_input, form_iframe_present |
The DEFAULT_COUNTED_TIERS constant controls which tiers roll up into the
headline conversion count and conversion rate. Only "completed" is counted
by default. Brand-level overrides via BrandConversionConfig.isCounted can
promote intent signals to counted status for specific brands.