<!-- task=m-external-integration/02_jira_adapter plan=1 tag=REVIEW_JIRA -->

# Jira Adapter Follow-up Plan

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

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 구현 후 검증 명령을 실행하고 실제 stdout/stderr를 붙여 넣은 뒤 active 파일을 그대로 둔 채 리뷰 준비를 보고한다. 사용자 결정, 사용자 소유 외부 환경, scope 충돌 없이는 안전하게 진행할 수 없는 경우에는 review stub의 `사용자 리뷰 요청` 섹션에 근거를 남기고 멈춘다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- Task ids:
  - `jira-adapter`: Jira issue 조회, comment, status transition adapter 구현
- Completion mode: check-on-pass

## 배경

첫 리뷰(`code_review_local_G07_0.log`)는 기능 검증 통과를 확인했지만, PASS 전에 정리해야 할 Suggested 항목을 남겼다. 이 follow-up은 Jira adapter 동작을 바꾸는 큰 확장이 아니라, config edge case 보강과 task 산출물 품질 정리를 닫는 범위다.

## 범위 결정 근거

- Jira live smoke, Jira HTTP endpoint 추가, provider registry 확장은 범위 밖이다.
- `services/core/server`는 빌드 산출물이므로 제거만 하고 대체 파일을 만들지 않는다.
- 검증 출력 공백은 후속 구현자가 같은 명령을 재실행해 actual stdout/stderr를 review stub에 남기면 닫을 수 있으므로 USER_REVIEW 대상이 아니다.

## 빌드 등급

- build lane/grade: `local-G07` - deterministic Go cleanup plus adapter edge-case tests.
- review lane/grade: `local-G07` - bounded source changes and verification evidence review.

## 구현 체크리스트

- [x] [REVIEW_JIRA-1] Jira adapter WARN follow-up을 정리한다.
- [x] `cd services/core && go test ./...`를 실행한다.
- [x] `cd services/core && go vet ./...`를 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

## [REVIEW_JIRA-1] Jira adapter WARN follow-up

문제:

- `services/core/internal/adapters/jira/client.go`는 config validation에서 trim한 값을 실제 endpoint/auth 구성에 쓰지 않는다. BaseURL에 공백이나 trailing slash가 있으면 요청 생성 실패 또는 `//rest/api/3/...` 경로가 생길 수 있다.
- `gofmt -l`이 `services/core/internal/adapters/jira/client.go`, `services/core/internal/adapters/jira/client_test.go`, `services/core/cmd/server/main.go`, `services/core/internal/http/handlers.go`를 보고한다.
- `services/core/server` 23 MB 실행 파일이 untracked build artifact로 남아 있다.
- 이전 review stub의 검증 결과가 `(output)` placeholder로 남아 있어 구현 증거가 불완전하다.

해결 방법:

- Jira client에 Plane adapter와 같은 방식의 normalized config helper를 추가하거나 동등한 구조로 정리한다.
  - before: `validateConfig()`는 trim한 로컬 변수만 검사하고, request path는 `c.cfg.BaseURL + "/rest/..."`를 사용한다.
  - after: request helpers use `strings.TrimRight(strings.TrimSpace(BaseURL), "/")`, `strings.TrimSpace(Email)`, and `strings.TrimSpace(APIToken)` consistently.
- `FetchWorkItem`, `AppendComment`, `ProjectStatus`, `setAuthHeader`가 normalized values만 사용하게 한다.
- httptest 기반 테스트를 추가해 trailing slash와 whitespace config에서도 `/rest/api/3/...` 경로와 Basic auth가 정상 생성되는지 확인한다.
- 변경된 Go 파일에 `gofmt -w`를 적용한다.
- `services/core/server`를 제거하고 `git status --short -- services/core/server`에서 남지 않는지 확인한다.
- follow-up `CODE_REVIEW-local-G07.md`의 검증 결과에 실제 stdout/stderr를 붙여 넣는다.

수정 파일 및 체크리스트:

- [ ] `services/core/internal/adapters/jira/client.go`: normalized config helper and request/auth usage.
- [ ] `services/core/internal/adapters/jira/client_test.go`: trailing slash/whitespace config test.
- [ ] `services/core/cmd/server/main.go`, `services/core/internal/http/handlers.go`: gofmt only, unless compile requires more.
- [ ] `services/core/server`: remove generated executable.
- [ ] `agent-task/m-external-integration/02_jira_adapter/CODE_REVIEW-local-G07.md`: record actual verification outputs.

중간 검증:

```bash
gofmt -l services/core/internal/adapters/jira/client.go services/core/internal/adapters/jira/client_test.go services/core/cmd/server/main.go services/core/internal/http/handlers.go
test ! -e services/core/server
cd services/core && go test ./internal/adapters/jira ./internal/config ./cmd/server ./internal/http
```

기대: `gofmt -l` outputs nothing, `test ! -e` exits 0, and targeted tests pass.

## 최종 검증

```bash
cd services/core && go test ./...
cd services/core && go vet ./...
git status --short -- services/core/server services/core/internal/adapters/jira/client.go services/core/internal/adapters/jira/client_test.go services/core/cmd/server/main.go services/core/internal/http/handlers.go
```

기대: Go test/vet exit 0. `services/core/server` does not appear in git status; source files only show intentional tracked modifications.
