# TiCDC Essential Serverless Routing

## Background

The Clinic Data Service TiCDC metadata API previously classified every
non-Dedicated cluster as Dataflow-NG. Canonical metadata for an Essential
cluster is `deployType=shared` and `deployTypeV2=essential`, but Essential
changefeeds are owned by `serverless-service`, not Dataflow-NG. This resulted
in a successful Dataflow-NG RPC with an empty list rather than the Essential
changefeeds.

DevOps PR 1487 establishes the shared DTO and Dedicated/Dataflow-NG
aggregation behavior. Its current follow-up implementation adds an Essential
branch which calls Serverless `ChangefeedOpsService.ListClusterChangefeeds`
and `GetChangefeed`.

## Upstream routing

| Canonical cluster class | Upstream owner |
| --- | --- |
| Dedicated | Dataflow |
| Premium, BYOC, shared pool | Dataflow-NG |
| Essential (`deployTypeV2=essential`, including legacy `deployType=shared`) | Serverless `ChangefeedOpsService` |
| Unrecognized non-Dedicated, non-Essential legacy value | Dataflow-NG compatibility fallback |

## Goal and contract

- Resolve `deployTypeV2=essential` before the legacy deploy type and route it
  to a new `essential` architecture. The complete upstream mapping is the
  table above; do not classify every non-Dedicated cluster as Dataflow-NG.
- Keep public TiCDC APIs Dedicated-only; Essential is available through the
  existing internal API only.
- Use Serverless list limit `1000` and offset `0`; return the existing stable
  Clinic changefeed DTO with the Serverless string ID as both `id` and
  `display_id`.
- Detail accepts the opaque Essential changefeed ID and verifies the returned
  source cluster ID equals the request cluster before responding.
- Do not attach Dataflow impersonation metadata to Serverless RPCs. Do not
  log credentials or full upstream payloads.

## Scope

Affected source module: `clinic_data_service`, especially `pkg/ticdc`,
`pkg/handlers`, `pkg/config`, and `cmd/api/main.go` route initialization.
The executable remains `clinic_data_service/cmd/api/main.go`, producing the
`clinic/data-service` image.

Affected deployment configuration: app-delivery `clinic-data-service` Data
Proxy config for dev, staging, and prod-cloud gains
`ticdc.serverless_addr` using the existing PrivateLink endpoint on port
`10101`. No new endpoint or Gateway change is required.

## Implementation

1. Add `ArchitectureEssential`, resolve Essential by `deployTypeV2`, and add
   a Serverless ChangefeedOps gRPC client.
2. Add the required Serverless endpoint configuration and validate all three
   TiCDC endpoint addresses at startup.
3. Implement Essential List and Detail conversion from the Serverless allowlist
   response. Preserve the request timeout, safe structured lifecycle logs, and
   source-cluster fail-closed checks.
4. Change Detail's internal service boundary to retain opaque Essential IDs,
   while continuing to require a positive numeric kernel ID for Dedicated and
   Dataflow-NG.
5. Add focused configuration, routing, service, and handler tests. Run focused
   Go tests and build the Data Service binary.

## Compatibility and exclusions

- Existing Dedicated and Dataflow-NG API paths, request contracts, Dataflow
  authorization metadata, and public Gateway rules are unchanged.
- This does not add TiCDC mutations or public Essential access.
- The returned Serverless response is an explicit field conversion; it does
  not serialize a protobuf or expose sink credentials.

## Staging and release

Deploy the feature image through the dedicated Clinic Data Service CD workflow
to staging after the matching app-delivery configuration is merged. Validate
Essential internal List and Detail, as well as one Dedicated and one NextGen
regression request. Production remains an explicit separately authorized
release.
