# Changefeed OpenAPI Adapter Design

## 1. Objective

Implement the current Dedicated Changefeed OpenAPI contract by routing all endpoints through the existing `biz_changefeed` model layer, with a thin endpoint-level adapter in between.

This iteration will:

1. Cover the full API surface, including internal `GetEventFilters`/`SetEventFilters`.
2. Switch directly to the model-adapter path (no fallback branch to the old connector API path).
3. Implement `dry_run` for create/edit through model precheck logic without persistence side effects.
4. Implement contract-level pagination (`page_size` + `page_token`) for `ListChangefeeds`.

## 2. Scope

### In Scope

- `ListChangefeeds`
- `GetChangefeed`
- `CreateChangefeed`
- `EditChangefeedDownstreamConfig`
- `DeleteChangefeed`
- `PauseChangefeed`
- `ResumeChangefeed`
- `ScaleChangefeed`
- `ListChangefeedRCUs`
- internal `GetEventFilters`
- internal `SetEventFilters`

### Out of Scope

- Building a reusable cross-module generic adapter framework.
- Feature-flag dual-path rollout in this iteration.
- Non-changefeed OpenAPI services.

## 3. Architecture

Adopt a thin, endpoint-level adapter:

`OpenAPI Service -> Changefeed Adapter (thin) -> BizChangefeedModel`

### Responsibilities

- **OpenAPI Service**
  - RBAC checks
  - request orchestration
  - calling adapter entrypoints
- **Thin Adapter**
  - type conversion (OpenAPI string IDs <-> model `uint64`)
  - pagination token encode/decode
  - downstream config mapping (`oneof` + top-level `table_config`/`start_position`)
  - endpoint-to-model call bridging
- **BizChangefeedModel**
  - business validation and status matrix checks
  - persistence/workflow operations
  - downstream precheck/connection validation integrations

## 4. Endpoint Mapping

| OpenAPI RPC | Model Path | Adapter Notes |
|---|---|---|
| `ListChangefeeds` | `ListBizChangefeeds` | Decode `cluster_id`, `page_token` -> `page`; map response + `next_page_token` |
| `GetChangefeed` | `GetBizChangefeed` | Decode `changefeed_id`; map model status/fields to OpenAPI `Changefeed` |
| `CreateChangefeed` | `CreateBizChangefeed` / dry-run precheck path | Build downstream params from oneof + top-level `table_config` + `start_position` |
| `EditChangefeedDownstreamConfig` | `EditBizChangefeed` / dry-run edit precheck path | Build edit downstream params + top-level `table_config`; `start_position` remains immutable |
| `DeleteChangefeed` | `DeleteBizChangefeed` | Decode ID and call model |
| `PauseChangefeed` | `PauseBizChangefeed` | Decode ID and call model |
| `ResumeChangefeed` | `ResumeBizChangefeed` | Decode ID and call model |
| `ScaleChangefeed` | `ScaleBizChangefeed` | Map `replication_capacity` -> specification code |
| `ListChangefeedRCUs` | existing model instance-type capability | Map instance type results into OpenAPI `ChangefeedRCU` |
| internal `GetEventFilters` | read from current downstream params | Extract `table_config.event_filters` |
| internal `SetEventFilters` | edit path reuse | Patch `table_config.event_filters` and call edit path (paused constraints preserved) |

## 5. Data Conversion Rules

### 5.1 IDs and Numeric Fields

- OpenAPI IDs remain strings on the wire.
- Adapter performs strict parsing:
  - invalid numeric string -> parameter error.
- Model-facing requests use `uint64`.

### 5.2 Pagination Token

- `page_token` is an opaque token encoded from internal paging state.
- Initial implementation uses deterministic encoded page state (page index), reversible by adapter.
- Invalid/expired format -> parameter error.

### 5.3 Downstream Config Assembly

- OpenAPI request uses:
  - top-level `table_config`
  - top-level `start_position` (create only)
  - downstream `oneof` body (`kafka/mysql/s3/gcs/azure_blob`)
- Adapter assembles model-compatible downstream parameter structs by sink type.
- `Edit` does not accept mutable `start_position`; immutable semantics are enforced.

## 6. Dry-Run Design

`dry_run=true` must execute validation only and produce no persistence/workflow side effects.

### 6.1 Create Dry-Run

- Add model-level dry-run entrypoint.
- Internally reuse `preCheckCreateBizChangefeed` path:
  - upstream checks
  - quota/spec checks
  - downstream connection + parameter prechecks
- No entity insert/update.
- No workflow creation.

### 6.2 Edit Dry-Run

- Add model-level dry-run entrypoint for edit.
- Flow:
  1. Load existing changefeed.
  2. Apply edit-merge logic (same shape as real edit merge).
  3. Run paused/state constraints.
  4. Reuse downstream precheck flow (create-style precheck inputs assembled from merged state).
- No entity update.
- No kernel modify call.
- No workflow side effects.

## 7. Behavioral Constraints

- `table_config` remains editable only when changefeed is paused (enforced by model status matrix + precheck).
- `start_position` is immutable after creation.
- internal event-filter operations stay internal use and should not be publicly exposed.

## 8. Error Handling

- Adapter conversion failures -> parameter errors with explicit field context.
- Model `bizerr` is passed through/mapped while preserving existing code semantics and key messages.
- No silent fallback between paths.

## 9. Testing Strategy

1. **Adapter unit tests**
   - ID conversion
   - downstream mapping per sink type
   - top-level `table_config`/`start_position` assembly
2. **Pagination tests**
   - token encode/decode round-trip
   - boundary and invalid token cases
3. **Dry-run tests**
   - create/edit dry-run trigger precheck calls
   - assert no persistence/workflow side effects
4. **Endpoint tests**
   - full endpoint coverage for model-adapter path
   - internal `Get/SetEventFilters`
5. **Constraint tests**
   - edit requires paused + kernel stopped
   - immutable `start_position` behavior

## 10. Risks and Mitigations

- **Risk:** behavior drift from old connector-based path.  
  **Mitigation:** endpoint-level regression tests on response shape and error semantics.

- **Risk:** validation gaps in edit dry-run.  
  **Mitigation:** model dry-run explicitly reuses precheck logic on merged effective config.

- **Risk:** token handling incompatibility.  
  **Mitigation:** keep token opaque and adapter-owned with strict validation.

## 11. Definition of Done

- All listed endpoints are routed through `Service -> thin adapter -> BizChangefeedModel`.
- Pagination token flow is functional for list API.
- Create/Edit dry-run is implemented with no side effects.
- Internal event-filter endpoints work through edit/read adapter logic.
- Tests cover mapping, pagination, dry-run, and key state constraints.
