<!-- task=m-external-integration/01_provider_intake_registry plan=1 tag=REVIEW_REFACTOR -->

# Provider Intake Registry Follow-up Plan

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-local-G05.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 코드 변경, 검증 실행, 실제 stdout/stderr 기록을 끝낸 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 종결 판정, log rename, `complete.log`, task archive 이동은 code-review 스킬만 수행한다. 구현 중 사용자만 결정할 수 있는 범위 변경, 사용자 소유 외부 환경, secret, 서비스 준비 없이는 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 근거를 남기고 멈춘다. 후속 에이전트가 명령 재실행이나 증거 수집으로 닫을 수 있는 검증 공백은 사용자 리뷰 요청이 아니다.

## 배경

첫 번째 리뷰(`code_review_local_G05_0.log`)는 registry/generic handler 구현의 큰 방향은 확인했지만, legacy Plane endpoint의 미구성 provider 응답 계약이 깨졌고, 이번 task target 밖의 roadmap 항목이 완료로 바뀌었으며, `NewHandler`의 실제 registry 조립 테스트와 invalid body 테스트가 빠졌다고 판정했다. 이 후속 작업은 해당 Required 이슈만 닫는다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- Task ids:
  - `provider-intake-registry`: Plane 전용 task intake handler를 provider-neutral registry/generic route 또는 동등한 조립 구조로 정리
- Completion mode: check-on-pass

## 분석 결과

### 기준 로그

- Archived plan: `agent-task/m-external-integration/01_provider_intake_registry/plan_local_G06_0.log`
- Archived review: `agent-task/m-external-integration/01_provider_intake_registry/code_review_local_G05_0.log`
- Verdict: FAIL

### Required 이슈

- `services/core/internal/http/handlers.go:124`의 legacy Plane route가 generic registry lookup에 바로 위임되어 Plane provider 미구성 시 기존 `503 plane client is not configured` 대신 `400 unknown or unconfigured provider`를 반환한다.
- `agent-roadmap/phase/external-integration/milestones/external-integration.md`에서 이번 task target이 아닌 `plane-adapter-expand`, `jira-adapter`, `mattermost-adapter`가 완료 처리되었다.
- `services/core/internal/http/handlers_test.go:37`의 `TestNewHandlerRegistersConfiguredWorkItemProviders`가 `NewHandler`를 호출하지 않아 실제 `NewHandler` registry 조립을 검증하지 않는다.
- generic route 테스트에 invalid JSON/body 케이스가 없어 request parser의 400 계약을 검증하지 않는다.

### 범위 결정 근거

- registry/generic route의 기본 성공 경로는 유지한다.
- roadmap은 이번 task target 밖 변경만 원복한다. `provider-intake-registry` 완료 체크는 code-review PASS 이후 런타임 이벤트가 처리할 대상이므로 구현 에이전트가 직접 체크하지 않는다.
- live Plane/Jira/Mattermost smoke는 필요 없다. 이 follow-up은 local unit test와 diff inspection으로 닫는다.

## 구현 체크리스트

- [ ] legacy `/api/integrations/plane/tasks`가 Plane provider 미구성 시 기존 `503 plane client is not configured` 응답을 유지하도록 고치고 테스트를 복원한다.
- [ ] `agent-roadmap/phase/external-integration/milestones/external-integration.md`의 이번 task target 밖 완료 체크와 근거 추가분을 원복한다.
- [ ] `NewHandler`가 Plane/Jira reader를 registry에 등록하고 nil reader는 제외하는 실제 조립 테스트를 추가하거나 기존 테스트를 의미 있게 고친다.
- [ ] generic `/api/integrations/{provider}/tasks` invalid JSON/body 400 테스트를 추가한다.
- [ ] `cd services/core && go test -count=1 ./internal/http ./internal/workitempipeline ./internal/workitem`를 통과시킨다.
- [ ] `cd services/core && go test ./...`를 통과시킨다.
- [ ] `git diff --check`를 통과시킨다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REFACTOR-1] Legacy Plane Unconfigured Compatibility

문제: legacy Plane endpoint는 기존에 Plane pipeline이 없으면 503과 `"plane client is not configured"`를 반환했다. 현재 implementation은 generic lookup을 재사용하면서 이 경로를 400으로 바꿨다.

해결 방법:

- `CreatePlaneTask` 또는 그 위임 경로에서 provider=`plane` 미구성 상태를 legacy 계약대로 503으로 처리한다.
- generic `/api/integrations/{provider}/tasks`의 unknown/unconfigured provider 400 테스트는 유지한다.
- `TestCreatePlaneTaskReturns503WhenPipelineNotConfigured` 또는 동등 테스트를 복원한다.

중간 검증:

```bash
cd services/core && go test -count=1 ./internal/http
```

### [REVIEW_REFACTOR-2] Roadmap Scope Restoration

문제: active milestone 문서에서 이번 task target이 아닌 `plane-adapter-expand`, `jira-adapter`, `mattermost-adapter`가 완료 처리되고 별도 완료 근거가 추가되었다. 현재 루프의 `Roadmap Targets`는 `provider-intake-registry` 하나뿐이다.

해결 방법:

- `agent-roadmap/phase/external-integration/milestones/external-integration.md`에서 위 세 Task의 `[x]`를 원래 `[ ]`로 되돌린다.
- 이번 implementation에서 추가한 해당 완료 근거 bullet과 검증 명령 bullet을 제거한다.
- `provider-intake-registry`는 직접 완료 체크하지 않는다.

중간 검증:

```bash
git diff -- agent-roadmap/phase/external-integration/milestones/external-integration.md
```

### [REVIEW_REFACTOR-3] NewHandler Registry Assembly Test

문제: 현재 `TestNewHandlerRegistersConfiguredWorkItemProviders`는 `newHandlerForTest`가 만든 map을 검사할 뿐 `NewHandler`를 통과하지 않는다.

해결 방법:

- `workflow.NewService(nil, nil, nil)`과 fake `workitem.Reader`를 사용해 `NewHandler(nil, workflowService, planeReader, jiraReader, nil)`가 `plane`/`jira` provider를 registry에 등록하는지 검증한다.
- nil reader 또는 nil workflow service일 때 registry entry가 생기지 않는지 함께 검증한다.
- direct registry injection helper 테스트는 필요하면 유지하되, 이름이 실제 동작을 과장하지 않도록 정리한다.

중간 검증:

```bash
cd services/core && go test -count=1 ./internal/http
```

### [REVIEW_REFACTOR-4] Generic Invalid Body Test Coverage

문제: plan/review checklist는 provider mismatch와 invalid body 테스트를 함께 요구했지만, 현재 테스트는 malformed JSON 또는 필수 neutral field 누락을 검증하지 않는다.

해결 방법:

- generic route에 malformed JSON body가 들어오면 400과 `"invalid JSON body"`를 반환하는 테스트를 추가한다.
- 또는 tenant/project/id 누락 body가 400과 `"tenant, project, and id are required"`를 반환하는 테스트를 추가한다. 가능하면 두 케이스를 table-driven test로 묶는다.

중간 검증:

```bash
cd services/core && go test -count=1 ./internal/http
```

## 최종 검증

```bash
cd services/core && go test -count=1 ./internal/http ./internal/workitempipeline ./internal/workitem
cd services/core && go test ./...
git diff --check
```
