# Tenant-grain data contract

Every region must emit **one row per tenant** with these fields so `universal/` scoring logic runs
unchanged. This mirrors the proven global view `vw_pql_candidate_facts`
(`gcp-martech-infra.plg_dashboard`, ~69k rows, validated). Regions may add columns; they must not
rename these.

## Identity & fit
| Field | Type | Notes |
|-------|------|-------|
| `tenant_id` | string | grain |
| `tenant_email`, `email_domain` | string | `email_domain` drives the free-email/corporate heuristic |
| `account_id`, `account_name` | string | nullable |
| `country`, `tenant_region` | string | ISO-2 country drives region/market filtering |
| `company_ai_category` | string | enrichment — `ai_core` / `ai_related` / `non_ai` / `institution` / `individual` / null |
| `account_segmentation` | string | nullable enrichment |

## Acquisition
| Field | Notes |
|-------|-------|
| `signup_date`, `signup_age_days` | recency |
| `ga_channel`, `ga_utm_source/medium/campaign` | attribution |
| `tenant_plan` | plan/tier |

## Behavior — lifecycle milestones (timestamps, nullable)
`first_cluster_created_at` · `first_query_executed_at` · `first_import_attempted_at` ·
`first_import_completed_at` · `payment_method_added_at` · `has_payment_method` (bool)

## Behavior — usage
`cluster_count` · `dedicated_cluster_count` · `logs_7d` · `logs_28d` · `active_days_28d` ·
`last_active_date` · `is_churned`

## Behavior — commercial / workload (often blocked; null until wired)
`tenant_avg_qps` · `spending_limit_updated_at` · `premium_intent_at` · **first-DDL timestamp** (new — from O11Y)

## CRM / connected state (write-back)
`track_step` (connected guard, NULL-safe) · `crm_lead_id` · `crm_contact_id` · `crm_account_id` ·
`crm_owner` · `crm_status`

## Freshness
`data_as_of` — required on every row; surface it on every triage number.

## Scoring outputs the model adds
`fit_level` (High/Unknown/Low) · `signal_level` (Strong/Moderate/Early) · `pql_tier` (P0/P1/P2/SUPPRESS) ·
`recommended_action` (token) · `signal_coverage` (0–1, fraction of signal fields populated) ·
`pql_confidence` (high/medium/low/pending — degrade when coverage is low).
