---
# New oncall assign config (aisupport oncall v2 service).
#
# Mirrors assign.yml but every receiver that denotes a TEAM is the oncall-service
# team NAME (a string) instead of the legacy category id, so routing goes through
# the oncall service. The resolver runs this matcher to decide who to assign:
#
#   - a rule matched, receiver is a team name -> query that team's on-call
#   - a rule matched, receiver is an email    -> specific-person override
#   - nothing matched                         -> generic routing; the resolver
#       reads the oncall_team label directly (the old Section 2 was a pure echo
#       receiver==oncall_team, so it is not enumerated here)
#
# It then queries the oncall service and assigns the current on-call engineer.
# On empty/non-email/error it falls back to assign.yml.
#
# Sections:
#   1. special rules (summary/tenant/component/person overrides)
#   3. component-based fallback for alerts without oncall_team
# (Section 2, generic oncall_team routing, is handled in code via the label.)
#
# KEEP IN SYNC with assign.yml. This file is the primary routing; assign.yml is
# the fallback.
extractors:
  component: "{{ with .Fields.Components }}{{ (index . 0).Name }}{{ end }}"
  provider_type: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.provider_type }}"
  o11y_biz_type: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.o11y_biz_type }}"
  summary: "{{ .Fields.Summary }}"
  daytime: "{{if isDayTime}}day{{else}}night{{end}}"
  daytime16: "{{if isDayTime16}}day{{else}}night{{end}}"
  project: "{{ .Fields.Project.Key }}"
  priority: "{{ .Fields.Priority.Name }}"
  stability_governance: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.stability_governance }}"
  cluster_id: "{{ .Fields.Unknowns.customfield_10149 }}"
  tier: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.tier }}"
  cluster_name: "{{ .Fields.Unknowns.customfield_10162 }}"
  owner_id: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.owner_id }}"
  regions: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.regions }}"
  tenant_id: "{{ .Fields.Unknowns.customfield_10157 }}"
  assign: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.assign }}"
  job: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.job }}"
  isWeekday: "{{ if isWeekday }}true{{ else }}false{{ end }}"
  visibility: "{{ (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson).labels.visibility }}"
  isNightTime05: "{{ if isNightTime05 }}true{{ else }}false{{ end }}"
  isNightTime59: "{{ if isNightTime59 }}true{{ else }}false{{ end }}"
  isNightTime012: "{{ if isNightTime012 }}true{{ else }}false{{ end }}"
  oncall_tier: "{{ with .Fields.Unknowns.customfield_10164 }}{{ .value }}{{ end }}"
  # oncall_team MUST yield "" (never "<no value>") when the label is absent, so
  # the Section 3 `oncall_team: ^$` guards fire. Every level needs its own `with`:
  # the outer for a non-alert issue (no customfield_10160), the middle for a
  # present alert whose customfield has no `labels`, the inner for `labels`
  # without an `oncall_team` key (the common case). Dropping any level regresses
  # to "<no value>" and silently disables Section 3 (see #419). Covered by
  # matcher.TestProdAssignOncallSection3.
  oncall_team: "{{ with (.Fields.Unknowns.customfield_10160 | tryUnmarshalJson) }}{{ with .labels }}{{ with .oncall_team }}{{ . }}{{ end }}{{ end }}{{ end }}"
routes:
  # ============================================================
  # Section 1: Special rules (mirror assign.yml; team ids rewritten to
  # team names, person emails kept as-is).
  # ============================================================

  - receiver: br
    match:
      summary: TiDBClusterLogBackupLagHigh$

  # TCOC oncall tier routing
  - receiver: serverless
    match:
      project: TCOC
      oncall_tier: Serverless
      component: ^(TiDB Cloud|core-svc|Cloud Service|Cluster Service|kubernetes|node|infra-api|tidb-cluster|cert-manager|infra-provider|etcd|dbaas-proxy|tidb-auditlog|tidb-operator|nginx-ingress|cluster-autoscaler|eks-provider|gke-provider|quota-exporter|chaos-svc|chaos-provider|k8s-pod|cluster management|Tools)$
  - receiver: premium
    match:
      project: TCOC
      oncall_tier: "TiDB X"
      component: ^(TiDB Cloud|core-svc|Cloud Service|Cluster Service|kubernetes|node|infra-api|tidb-cluster|cert-manager|infra-provider|etcd|dbaas-proxy|tidb-auditlog|tidb-operator|nginx-ingress|cluster-autoscaler|eks-provider|gke-provider|quota-exporter|chaos-svc|chaos-provider|k8s-pod|cluster management|Tools)$

  # Serverless changefeed creating too long → data-replication
  - receiver: tidb_x_tools
    match:
      summary: ChangefeedCreatingTooLong$
      provider_type: ^aws-free-tier$

  # BizChangefeed summary-based → resilience daytime
  - receiver: resilience
    match:
      summary: (BizChangefeedIsFailedByKernelStatus|BizChangefeedIsWarningByKernelStatus|TiKVSideCDCSinkMemoryHighUsage|BizChangefeedCheckpointHighDelay1h|BizChangefeedCheckpointHighDelay2h|BizChangefeedCheckpointHighDelay3h)$
      daytime: ^day$
  - receiver: resilience
    match:
      summary: (BizChangefeedIsFailedByKernelStatus|BizChangefeedIsWarningByKernelStatus|TiKVSideCDCSinkMemoryHighUsage|BizChangefeedCheckpointHighDelay1h|BizChangefeedCheckpointHighDelay2h|BizChangefeedCheckpointHighDelay3h)$
      daytime: ^night$

  # Serverless ticdc - yuping all shifts
  - receiver: yuping@pingcap.com
    match:
      component: ^ticdc$
      "!summary": ChangefeedCreatingTooLong$
      daytime: ^day$
      provider_type: ^aws-free-tier$
  - receiver: yuping@pingcap.com
    match:
      component: ^ticdc$
      "!summary": ChangefeedCreatingTooLong$
      isNightTime05: ^true$
      provider_type: ^aws-free-tier$
  - receiver: yuping@pingcap.com
    match:
      component: ^ticdc$
      "!summary": ChangefeedCreatingTooLong$
      isNightTime59: ^true$
      provider_type: ^aws-free-tier$

  # P999 NextGen nighttime
  - receiver: wuxuelian@pingcap.com
    match:
      isNightTime59: ^true$
      summary: TiDBP999LatencySurgeNextGen
  - receiver: stanley.huang@pingcap.com
    match:
      isNightTime05: ^true$
      summary: TiDBP999LatencySurgeNextGen

  # TiKV kernel nighttime critical
  - receiver: zhangbokang@pingcap.com
    match:
      oncall_team: ^tikv_unified$
      daytime16: ^night$
      priority: Critical$
      isWeekday: ^true$
  - receiver: zhangbokang@pingcap.com
    match:
      oncall_team: ^serverless$
      component: ^tikv$
      daytime16: ^night$
      priority: Critical$
      isWeekday: ^true$
  - receiver: zhangjinpeng@pingcap.com
    match:
      oncall_team: ^tikv_unified$
      daytime16: ^night$
      priority: Critical$
      isWeekday: ^true$

  # Plaud external
  - receiver: serverless
    match:
      visibility: ^external$
      tenant_id: ^1372813089209291473$

  # Japan tenant kernel → mock
  - receiver: mock@pingcap.com
    match:
      tenant_id: ^(1372813089191061283|1372813089201471287)$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$

  # WeTech test
  - receiver: zhangming@pingcap.com
    match:
      summary: For2mForWeTechTest$

  # ResourcePoolIdle
  - receiver: resilience
    match:
      owner_id: ^1372813089194331289$
      summary: (ResourcePoolIdleFor12Hours|ResourcePoolIdleFor36Hours)$
  - receiver: premium
    match:
      owner_id: ^(1372813089209272198|1372813089209271775)$
      summary: (ResourcePoolIdleFor12Hours|ResourcePoolIdleFor36Hours)$
  - receiver: operator
    match:
      owner_id: ^1372813089209281154$
      summary: (ResourcePoolIdleFor12Hours|ResourcePoolIdleFor36Hours)$
  - receiver: global_control
    match:
      summary: (ResourcePoolIdleFor12Hours|ResourcePoolIdleFor36Hours)$

  # WeTech poc clusters
  - receiver: dedicated_service
    match:
      cluster_id: ^(10957523948617165785|10507769162283759836|10956278120794001035|10892745802387698762)$

  # PDLeaderChange/PDTSOFailed → pd team
  - receiver: pd
    match:
      summary: (PDLeaderChange|PDTSOFailed)$

  # worker-tidb owned by SQL when the alert is labeled as tidb_executor.
  - receiver: tidb_sql
    match:
      oncall_team: ^tidb_executor$
      component: ^worker-tidb$

  # No Section 2 here: the generic oncall_team routing is a pure echo
  # (receiver == oncall_team), so the resolver reads the oncall_team label
  # directly when no special rule above matches.

  # ============================================================
  # Section 3: component-based fallback for alerts WITHOUT oncall_team.
  # Mirrors assign.yml Section 3, but receivers are oncall team NAMES so
  # these route via the oncall service too. Changes vs assign.yml:
  #   - receiver category ids rewritten to team slugs (36 -> frontend)
  #   - day/night-split resilience rules collapsed (schedule handles time)
  #   - the SQL/Optimizer/Compute continue chain (which combined 3 teams)
  #     -> single virtual team tidb_common
  #   - the ng-auto-scaler -> sunyishen rule dropped
  # Every rule is guarded with `oncall_team: ^$` so it only applies when the
  # alert has NO oncall_team label; an explicit oncall_team always takes
  # precedence (matching the legacy Section 2 > Section 3 ordering).
  # Anything not resolvable here falls back to assign.yml.
  # ============================================================

  # next-gen data tools (dataflow / ticdc / br / export)
  - receiver: tidb_x_tools
    match:
      oncall_team: ^$
      component: ^(dataflow-service-ng|ticdc|next-gen-br|next-gen-export)$
      tier: ^next-gen$
  # Serverless free-tier tools
  - receiver: tidb_x_tools
    match:
      oncall_team: ^$
      component: ^(dm|export|import|br)$
      provider_type: ^aws-free-tier$
  # TEST / resilience component (day/night collapsed)
  - receiver: resilience
    match:
      oncall_team: ^$
      component: ^(TEST|resilience)$
      "!provider_type": ^aws-free-tier$
      "!o11y_biz_type": ^prod-devtier$

  # next gen related
  - receiver: pd
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^pd$
  - receiver: tidb_executor
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^tidb$
  - receiver: tidb_optimizer
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^tidb-optimizer$
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^tikv$
  - receiver: ingress_service
    match:
      oncall_team: ^$
      component: ^(tidb-sql-data|tidb-worker)$
  - receiver: tiflash
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^tiflash$
  - receiver: tiproxy
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^(tiproxy|TiProxy)$
  - receiver: ticdc
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^ticdc-kernel$
  - receiver: tidb_txn
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^tidb-txn$
  - receiver: br
    match:
      oncall_team: ^$
      tier: next-gen
      component: ^(br|next-gen-br-kernel)$

  # kernel governance
  - receiver: tidb_sql
    match:
      oncall_team: ^$
      component: ^tidb-sql$
  - receiver: tidb_sql
    match:
      oncall_team: ^$
      component: ^tidb-sql-data$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tidb_executor
    match:
      oncall_team: ^$
      component: ^tidb-executor$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tidb_txn
    match:
      oncall_team: ^$
      component: ^tidb-txn$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tidb_optimizer
    match:
      oncall_team: ^$
      component: ^tidb-optimizer$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tiflash
    match:
      oncall_team: ^$
      component: ^tiflash$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      component: ^tikv$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: tidb_x_tools
    match:
      oncall_team: ^$
      component: ^ticdc$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$
  - receiver: pd
    match:
      oncall_team: ^$
      component: ^pd$
      stability_governance: ^(kernel-tcocp|kernel-governance|errorlog-governance|errorlog-tcocp|capacity)$

  # serverless related
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
      component: ^tiflash$
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      o11y_biz_type: ^prod-devtier$
      component: ^tiflash$
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
      component: ^tikv$
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      o11y_biz_type: ^prod-devtier$
      component: ^tikv$
  - receiver: serverless
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
      component: ^ecosystem-server$
  - receiver: serverless
    match:
      oncall_team: ^$
      o11y_biz_type: ^prod-devtier$
      component: ^ecosystem-server$
  - receiver: tiflash
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
      component: ^tiflash-autoscale$
  - receiver: o11y
    match:
      oncall_team: ^$
      component: ^(o11y|vmagent)$
  - receiver: tidb_x_tools
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
      component: ^(lightning|data-migration)$
  - receiver: serverless
    match:
      oncall_team: ^$
      provider_type: ^aws-free-tier$
  - receiver: serverless
    match:
      oncall_team: ^$
      o11y_biz_type: ^prod-devtier$
  - receiver: serverless
    match:
      oncall_team: ^$
      component: ^(serverless-svc|Serverless|Serverless Cluster)$
  - receiver: clinic
    match:
      oncall_team: ^$
      component: ^(Clinic|clinic|cicd)$

  # resilience: kernel alert (day/night collapsed)
  - receiver: resilience
    match:
      oncall_team: ^$
      component: ^(metrics-integration|tidb|tiflash|tikv|Alert|Ops Portal)$
  - receiver: resilience
    match:
      oncall_team: ^$
      component: ^pd$
      "!summary": (PDLeaderChange|PDTSOFailed)$

  # ci cd
  - receiver: operator
    match:
      oncall_team: ^$
      project: ^(TCOC|O11Y)$
      component: ^(dataplane-controller|goldpinger)$
  # dataflow service
  - receiver: tidb_x_tools
    match:
      oncall_team: ^$
      project: ^(TCOC|O11Y)$
      component: ^(TiKV CDC|TiCDC|ticdc|dataflow-server|dataflow-service|dadaflow-worker|TiDB Lightning|TiDB Binlog|sync-diff-inspector|Cloud DM|import/export|Cloud Import|Dumpling|lightning|data-migration|tcidm-regional|import-controller|Quota|br|BR|TiKV BR|Import/Export|Backup/Restore|Data Migration)$
  # DM/DDL OP
  - receiver: ingress_service
    match:
      oncall_team: ^$
      project: ^GTOC$
      component: ^(Tools|TiDB Lightning|TiDB Binlog|sync-diff-inspector|DM|Import/Export|Lightning|Dumpling|lightning|data-migration|Data Migration)$
  # Regional Service
  - receiver: global_control
    match:
      oncall_team: ^$
      component: ^(cost-provider-server|OpenAPI|network|api-gateway|Dashboard|dataservice|Dataservice|Global Control)$
  - receiver: global_control
    match:
      oncall_team: ^$
      component: tidb-management-service
      "!job": dedicated-global-service
  # O11Y
  - receiver: o11y
    match:
      oncall_team: ^$
      component: ^(metering-server|Monitoring|Prometheus|thanos|alertmanager|prometheus|logging|o11y|metrics-server|vmagent|loki|observability-global-server|observability-regional-server|ngmonitoring|O11Y)$
  # ci cd for auditlog (next-gen)
  - receiver: operator
    match:
      oncall_team: ^$
      project: ^(TCOC|O11Y)$
      tier: next-gen
      component: tidb-auditlog
  # Cluster service
  - receiver: dedicated_service
    match:
      oncall_team: ^$
      project: ^(TCOC|O11Y)$
      component: ^(TiDB Cloud|core-svc|dedicated-regional-server|Cloud Service|Cluster Service|GitOps|kubernetes|node|infra-api|tidb-cluster|cert-manager|infra-provider|etcd|dbaas-proxy|tidb-auditlog|tidb-operator|nginx-ingress|cluster-autoscaler|eks-provider|gke-provider|quota-exporter|chaos-svc|chaos-provider|gitops|config-manager|k8s-pod|cluster management|Tools|Dedicated Cluster)$
      "!o11y_biz_type": prod-tidbcloud-nextgen
  - receiver: dedicated_service
    match:
      oncall_team: ^$
      project: ^(TCOC|O11Y)$
      component: tidb-management-service
      job: dedicated-global-service
  # Billing
  - receiver: billing
    match:
      oncall_team: ^$
      component: ^(billing-server|Billing)$
  # Account
  - receiver: account
    match:
      oncall_team: ^$
      component: ^(account-server|central-server|Account)$
  - receiver: tiproxy
    match:
      oncall_team: ^$
      component: ^(tiproxy|TiProxy)$
  # TiSpark
  - receiver: serverless
    match:
      oncall_team: ^$
      component: ^(ecosystem-server|TiSpark)$
  # FE
  - receiver: frontend
    match:
      oncall_team: ^$
      component: ^(DBaaS Frontend|frontend)$
  - receiver: pd
    match:
      oncall_team: ^$
      component: ^PD$
  # TiDB kernel common — was SQL(2)+Optimizer(3)+Compute(4) combined via
  # continue; now a single virtual team that holds those people.
  - receiver: tidb_common
    match:
      oncall_team: ^$
      component: ^(DDL|TiDB|TiDB connection|TiDB partitions|TiDB charsets|TiUP|Performance Tuning|TiDB Optimizer|TiDB OOM|TiDB Compute)$
  - receiver: tidb_txn
    match:
      oncall_team: ^$
      component: ^TiDB Transaction$
  # Operator
  - receiver: operator
    match:
      oncall_team: ^$
      component: ^(TiDB-Operator|TiDB Operator)$
  - receiver: tiflash
    match:
      oncall_team: ^$
      component: ^TiFlash$
  # TiKV
  - receiver: tikv_unified
    match:
      oncall_team: ^$
      component: ^(TiKV|PiTR)$
  # CDC OP
  - receiver: ticdc
    match:
      oncall_team: ^$
      project: ^(GTOC|O11Y)$
      component: ^(TiKV CDC|TiCDC|ticdc-kernel)$
  # BR OP
  - receiver: br
    match:
      oncall_team: ^$
      project: ^GTOC$
      component: ^(BR|TiKV BR|Backup/Restore)$
  - receiver: premium
    match:
      oncall_team: ^$
      project: ^(O11Y|TCOC)$
      component: ^(next-gen-import|cluster-ng-service|NextGen Cluster)$
  - receiver: premium
    match:
      oncall_team: ^$
      project: ^O11Y$
      o11y_biz_type: prod-tidbcloud-nextgen
  - receiver: security
    match:
      oncall_team: ^$
      project: ^O11Y$
      component: ^security$
