Daily email performance metrics for AI-enabled Warby Parker agents. Each row represents one agent's aggregate email activity for a calendar day. The view is the direct data source for the wbp_xoos_analytics_push Airflow DAG, which queries it every morning to push daily and weekly metrics to the XOOS analytics ingest API.
Dynamic Tables use target_lag = DOWNSTREAM — refreshed on-query by Snowflake
Dynamic Table latency note: WARBYPARKER_CONTACTS_MODEL and ROSTER_WARBYPARKER both use target_lag = DOWNSTREAM. This means they are refreshed lazily by Snowflake when the view is queried by the DAG, not on a fixed schedule. Freshness depends on when the upstream HISTORICAL Bronze tables were last loaded.
Throughput: fulfilled emails per hour of active time
WAVE_PERIOD
CASE WHEN wave='Wave 1' AND date >= '2026-01-21' THEN 'Post-Wave' WHEN wave='Wave 2' AND date >= '2026-02-02' THEN 'Post-Wave' ELSE 'Pre-Wave' END
Pre/post AI enablement classifier
SLA %
SLA_MET / SLA_ELIGIBLE
Compute in BI layer — denominator = contacts_fulfilled
AHT sources: Two AHT columns exist because Gladly has two grains — contact-level handle time (summed across all agents who touched the contact) and work-session-level handle time (this agent's sessions only). AGENT_AHT_MIN is generally preferred for per-agent performance.
Hardcoded agent list: The ai_agents CTE is a VALUES literal in the view SQL. Adding or removing agents requires editing R__warbyparker_rpt_email_daily.sql and redeploying via schemachange. A TODO in the SQL notes the future intent to replace this with a roster AA_STATUS = 'Enabled' filter once that field is reliably populated.
HISTORICAL table latency: The three Bronze HISTORICAL tables (CONTACT_TIMESTAMPS, WORK_SESSIONS, AGENT_DURATIONS) are loaded by separate Airflow pipelines on their own schedules. The wbp_xoos_analytics_push DAG at 7 AM EST assumes upstream data for the previous day is already present.
Dynamic Table DOWNSTREAM lag chain: WARBYPARKER_CONTACTS_MODEL and ROSTER_WARBYPARKER are both target_lag = DOWNSTREAM. They refresh lazily when queried. If Bronze tables are delayed, the Snowflake refresh triggered by the DAG query will read stale data silently — no error is raised.
No AA_STATUS filtering yet: ROSTER_WARBYPARKER includes all active roster rows. The view currently uses the hardcoded agent list as a proxy for "AI-enabled." Future work (see SQL TODO) will filter by AA_STATUS.
EID / ACCOUNT_EMAIL can be null: The roster join is a LEFT JOIN on GLADLY_NAME. Agents not matched in the roster will have null for these columns, which breaks the XOOS RECORD_KEY (EID || date || client_id). Monitor for null EIDs in the push task output.
CONTACTS_WORKED ≠ CONTACTS_FULFILLED: CONTACTS_WORKED counts contacts where the agent sent at least one message. CONTACTS_FULFILLED counts contacts the agent was the fulfilling agent. An agent may message a contact without being the one to fulfill it.