# Compatible uploaded-metrics dashboard URLs

## Problem and contract

Non-cloud Operator clusters return dashboard context before resolving the
uploaded package's Kubernetes cluster name. Their Operator dashboards therefore
miss `var-k8s_cluster` and can show no data. Moving all non-cloud uploads into
the Operator path previously broke TiUP dashboards.

- Non-cloud `tidb-operator`: keep Operator dashboards and the requested absolute
  time range. Resolve the Kubernetes name from a matching upload, falling back
  to the cluster name when no usable package name exists.
- Non-cloud TiUP and other deployment types: preserve Cluster dashboards and
  omit the Kubernetes variable, even when an upload exists.
- Cloud uploads: preserve the existing upload-specific Operator context.
- Cloud online data: preserve the cloud/nextgen dashboard selection, datasource
  variable, and relative time range.
- Do not change import formats, stored metrics, authorization, dashboard JSON,
  or package selection rules. This is independent of Prometheus versus VM input.

## Implementation and verification

1. Limit the new package lookup and Kubernetes-variable assignment to the
   existing non-cloud Operator branch of `resolveDashboardContext`.
2. Add regression cases covering Operator package names, metadata fallback,
   missing/out-of-range/incomplete uploads, TiUP with uploads, other non-cloud
   deployments, Cloud uploads, and Cloud online Dedicated/Premium contexts.
3. Run focused cluster tests and inspect the final diff and route consumers.
4. Before merging, validate a feature image in staging: inspect dashboard URLs
   for TiUP and Operator uploads plus Cloud online/upload examples. Check actual
   rendered metrics. Record unavailable checks rather than claiming deployment.

## Ownership and release

- Source: root Go module, `pkg/api/cluster`, consumed by `cmd/server/main.go` via
  `GET /clinic/api/v1/orgs/:oid/clusters/:cid/dashboard`.
- Build: `build-clinic-server` / `docker_build_server`, image `clinic`.
- Deployment: Clinic CD `components=clinic`; app-delivery `clinic-api`, workload
  Deployment `clinic`, staging namespace `clinic-staging` and production-cloud
  namespace `clinic-prod-cloud`. Image-only bump; no manifest changes required.
- No deployment of Grafana, importer, internal-api, cloud-server, NGM,
  data-service, or gateway is required by this change.
- This task authorizes a code PR, not merging or production deployment.

## Results

- Added six runtime lines, limited to the non-cloud Operator branch. Reviewed
  `ListDashboards`, its route registration, metadata selection, authorization,
  URL consumers, build targets, CD inputs, and app-delivery image/workload mapping.
  No schema, configuration, generated artifacts, or auth changes are needed.
- Go 1.24.2 test compilation passed. Focused tests passed, including 17 new
  compatibility cases and existing TiUP/name-resolution tests (108.724s).
- The unmodified test harness could not use Docker 29 because it hardcodes API
  1.39. Local validation used `go test -overlay` to change only the test Docker
  client to API 1.44, with real MySQL/OpenSearch test dependencies. No production
  code or test assertions were substituted; the overlay is not part of the PR.
- Command: `GOTOOLCHAIN=go1.24.2 go test
  -overlay=/private/tmp/clinic-dashboard-test-overlay.json -p 2 ./pkg/api/cluster
  -run 'TestResolveDashboardContext|TestDashboardK8sClusterVariable|TestUploadedMetricK8sClusterVariable'
  -count=1`.
- The affected production page was verified before the fix: adding only the
  Kubernetes variable to the generated URL restored both TiKV Duration charts.
  The new backend image has not been deployed to staging or production.
