-
Notifications
You must be signed in to change notification settings - Fork 0
워크플로우 리포트
TravelMapper 프로젝트(부스트캠프 3주 개인 프로젝트, Week 14 / 2주차) 진행 중 Claude Code(Agent)를 활용한 개발 워크플로우를 정리하고, 1주차에서 발견하지 못한 마찰 지점과 향후 개선 방향을 도출한 문서입니다.
TravelMapper는 즉흥적인 여행자를 위한 유연한 여행 스케줄러로, Next.js 16, React 19, TypeScript, Tailwind CSS, Supabase/SQLite, Google Maps API 위에서 동작합니다. 이번 주(2주차)부터는 핵심 도메인 기능을 본격적으로 구현해야 했기 때문에, Agent와의 협업 방식을 단순한 "코드 생성 도구" 수준에서 "수직 슬라이싱 단위의 페어 프로그래밍 파트너"로 한 단계 끌어올리는 것을 목표로 삼았습니다.
핵심 원칙은 세 가지였습니다.
- GitHub Issue 단위로 작업의 경계를 명확히 한다.
- 하나의 feature 브랜치 안에서 Agent와 함께 UI → 상태 → API → DB까지 수직으로 끝낸다.
- PR 단계에서 사람이 다시 한 번 코드를 읽고 책임진다.
Agent를 신뢰하되 검증한다는 태도가 이번 주 작업의 기조였습니다.
전체 흐름은 아래와 같이 정형화되었습니다.
| 단계 | 행위 주체 | 산출물 |
|---|---|---|
| 1. Issue 작성 | 본인 | 사용자 스토리 + 수용 기준(AC) |
| 2. feature 브랜치 분기 | 본인 | feature/<issue-번호>-<요약> |
| 3. 컨텍스트 로딩 | Agent | 관련 파일 Read, 구조 파악 |
| 4. 구현 계획 수립 | Agent + 본인 | 변경 파일 목록과 순서 |
| 5. 수직 슬라이싱 구현 | Agent | UI → hook → API route → DB 순 |
| 6. 타입체크 / 수동 검증 | 본인 |
tsc --noEmit, 브라우저 확인 |
| 7. PR 생성 → dev 머지 | 본인 | PR 본문에 Issue 링크 + 스크린샷 |
특히 3, 4단계를 분리한 것이 효과적이었습니다. 곧바로 코드 생성을 시키지 않고 "먼저 관련 파일을 읽고 변경 계획을 세워달라"고 요청하면, 이후 생성되는 코드의 정합성이 눈에 띄게 좋아졌습니다.
1주차에 미리 정의해 두었던 네 가지 패턴(기능 구현, 버그 수정, 리팩토링, 컴포넌트 UI)은 대체로 유효했지만, 실전에서 다듬어진 부분이 있었습니다.
[목표] 여행 일정에 장소를 드래그앤드롭으로 재정렬할 수 있게 한다.
[제약] 기존 useItinerary 훅의 시그니처는 바꾸지 않는다.
[수직 슬라이스] UI 컴포넌트 → 훅 → /api/itinerary/reorder → Supabase RPC
[참고 파일] src/features/itinerary/*, src/lib/supabase/client.ts
→ 1주차의 패턴이 거의 그대로 적용 가능했고, "수직 슬라이스" 항목을 명시한 것이 가장 큰 차이였습니다.
[증상] 지도 마커가 일정 추가 직후 즉시 갱신되지 않는다.
[재현] /trip/[id] → 장소 추가 → 새로고침 전까지 마커 없음
[가설은 적지 않는다 — 먼저 원인을 찾아 보고해 달라]
→ 처음에는 가설까지 함께 적었지만, 가설을 제시하면 Agent가 그 가설을 검증하는 방향으로만 움직이는 경향이 있어 후반부에는 의도적으로 가설을 비웠습니다. 새롭게 발견한 패턴입니다.
[대상] src/features/map/MapView.tsx (350줄)
[원칙] 동작은 바꾸지 않는다. 외부에서 import하는 시그니처도 유지한다.
[목표] 마커 렌더링 / 카메라 제어 / 이벤트 핸들링 세 책임으로 분리
→ "동작 불변 / 시그니처 불변"을 명시하지 않으면 Agent가 리팩토링을 빌미로 동작까지 바꾸는 사례가 있었습니다.
[컴포넌트] <PlaceCard />
[입력] place: Place, onRemove?: () => void
[톤] Tailwind, rounded-2xl, shadow-sm, hover 시 살짝 떠오르는 느낌
[상태] loading / empty / error 세 상태를 모두 처리
→ 새롭게 추가한 항목은 "상태 3종 세트"입니다. 이 항목을 적기 시작한 뒤로는 빈 상태 UI를 따로 요청할 일이 거의 사라졌습니다.
Agent가 만든 코드를 그대로 머지하지 않기 위해, 아래 순서로 검증했습니다.
-
정적 검증:
tsc --noEmit,next lint로 타입과 린트 에러를 먼저 잡습니다. - 읽기 검증: PR을 올리기 전에 변경 파일을 한 번 처음부터 끝까지 직접 읽습니다. 자동완성으로 생긴 듯한 의미 없는 주석, 사용하지 않는 import, 과한 추상화를 이 단계에서 제거합니다.
- 수동 시나리오 테스트: Issue에 적힌 수용 기준(AC)을 그대로 체크리스트로 옮겨서 브라우저에서 직접 클릭합니다.
- 회귀 확인: 같은 모듈을 사용하는 기존 화면(특히 지도/일정 화면)을 함께 열어 동작을 비교합니다.
- 콘솔/네트워크 점검: 불필요한 리렌더링, 중복 호출, 깜박이는 마커 등은 코드만 봐서는 잘 보이지 않아 항상 마지막에 확인합니다.
자동화된 단위 테스트는 이번 주 범위에 포함되지 않았고, 그 공백을 "직접 읽고 직접 만져 본다"로 메꿨습니다.
솔직하게 정리하면 다음과 같은 마찰이 있었습니다.
- 큰 파일을 한 번에 수정 요청하면 품질이 떨어진다. 400줄이 넘는 컴포넌트를 한 번에 리팩토링해 달라고 했을 때, Agent가 일부 핸들러를 조용히 누락하거나, 동일 로직을 두 번 구현하는 경우가 있었습니다.
- 맥락이 부족한 프롬프트는 "그럴듯하지만 우리 코드베이스와는 어긋나는" 코드를 만든다. 특히 Supabase 클라이언트 인스턴스 위치, 서버/클라이언트 컴포넌트 경계가 흔히 어긋났습니다.
- 연속된 작은 수정의 누적 비용이 크다. "그러면 이 부분만 살짝 바꿔줘"가 다섯 번 반복되면, 결과적으로 의도하지 않은 방향으로 코드가 표류해 있는 경우가 있었습니다.
- PR 본문 작성을 Agent에게 맡기면 사실 관계가 과장된다. 실제로 구현하지 않은 케이스까지 "지원됨"으로 적히는 경우가 있어, PR 본문은 결국 직접 정리하는 편이 안전했습니다.
다음 프로젝트에서도 그대로 가져갈 베스트 프랙티스입니다.
- 작업을 시작하기 전에 Issue에 수용 기준(AC)을 먼저 적는다. 이것이 곧 프롬프트와 테스트 체크리스트가 된다.
- Agent에게 코드를 시키기 전, "먼저 관련 파일을 읽고 변경 계획을 세워 달라" 단계를 항상 둔다.
- 한 번의 요청에서 다루는 변경 범위를 300줄 / 5파일 이하로 제한한다. 넘어가면 슬라이스를 나눈다.
- 리팩토링 시에는 **"동작 불변 / 외부 시그니처 불변"**을 명시적으로 적는다.
- 버그 수정 프롬프트에서는 가설을 적지 말고 증상과 재현 경로만 적는다.
- UI 컴포넌트는 항상 loading / empty / error 세 상태를 함께 요구한다.
- PR 본문은 사람이 직접 쓴다. Agent는 초안만 만든다.
3주차에는 아래 세 가지를 시도할 예정입니다.
- 큰 변경은 "계획 PR → 구현 PR" 두 단계로 분리한다. 계획 PR에는 변경 파일 목록과 인터페이스만 담아 먼저 합의한다.
- 세션 끝에 짧은 회고를 Agent와 함께 남긴다. 어떤 가정이 틀렸는지, 어떤 파일을 더 일찍 읽었어야 했는지를 기록해 다음 세션의 컨텍스트로 사용한다.
- 수용 기준(AC)을 Playwright 시나리오로도 1~2개 자동화한다. 수동 검증에 의존하는 부분을 점진적으로 줄여 회귀 확인 비용을 낮춘다.
이번 주 워크플로우의 핵심은 "Agent를 빠른 손으로 쓰되, 경계와 검증은 사람이 잡는다"는 한 줄로 요약할 수 있습니다. Issue 단위의 작은 작업 경계, 수직 슬라이싱, 그리고 명시적인 프롬프트 패턴 덕분에 1주차보다 훨씬 안정적으로 기능을 쌓아 올릴 수 있었고, 동시에 큰 파일 일괄 수정이나 맥락 부족 같은 한계도 분명히 드러났습니다. 3주차에는 계획과 구현을 분리하고, 회고와 자동화를 더해 이 흐름을 한층 더 단단하게 만들어 보려 합니다.