개발 워크플로 - 100-hours-a-week/KTB4-13th-wiki GitHub Wiki

개발 워크플로

담당자: Sevan · 상태: ✅ 적용 중 · 최종 수정: 2026-09-18 (§9 담당 경계 갱신)

AI 저장소에서 하루가 어떻게 돌아가는지. 브랜치·커밋·PR 규칙 자체는 팀 공통 문서를 따르고, 여기엔 실제 손 순서와 AI 저장소 고유 사항만 적는다.


목차

  1. 시작 전에 한 번만
  2. 하루 흐름
  3. 브랜치
  4. 커밋
  5. PR
  6. 리뷰
  7. 머지
  8. 충돌
  9. AI 저장소 고유 규칙

1. 시작 전에 한 번만

  1. 로컬 개발 환경 세팅을 따라 /health가 뜨는 것까지 확인
  2. 담당 범위 확인 (아래 §9)
  3. main에 브랜치 보호가 걸려 있다. 직접 push·force push·삭제가 막혀 있고 PR + 승인 1명 + Squash 머지만 허용된다. 규칙을 어기고 싶어도 못 어기니 외울 필요는 없다

2. 하루 흐름

아침 — 최신 main에서 시작

git checkout main && git pull
git checkout -b feature/5-search-api

git pull을 빼먹으면 어제 상대가 머지한 걸 모른 채 작업하게 된다. 나중에 충돌이 크게 터진다.

작업 중 — 의미 단위로 커밋

git add <파일> && git commit -m "feat: 키워드 검색 쿼리 추가"

하루를 넘기는 작업이면 중간에 한 번 최신 main을 얹는다.

git fetch origin && git rebase origin/main

자주 하면 충돌이 작고, 미루면 감당이 안 된다.

저녁 — push하고 PR까지

git push -u origin feature/5-search-api

PR을 올리고 리뷰 요청까지 걸어둔다. 여기서 멈추면 상대가 내일 아침에야 본다.

리뷰 대기 중 — 손 놓지 않기

다음 작업 브랜치를 미리 파도 된다. 머지된 뒤 rebase하면 된다.


3. 브랜치

이슈가 먼저다

브랜치 이름에 이슈 번호가 들어가므로 이슈 → 브랜치 순서다.

feature|fix|hotfix|refactor|chore|docs/<이슈번호>-<slug>
타입 언제
feature/ 새 기능
fix/ 결함 수정
refactor/ 동작 그대로, 구조만 개선
chore/ 설정·의존성·빌드
docs/ 문서만
hotfix/ 운영 중대 장애

예: feature/5-search-api, docs/1-feed-get-method

이슈는 가볍게 쓴다

제목 한 줄 + 본문 2~3줄이면 충분하다. 요구사항 정의서를 쓰는 곳이 아니다.

제목: 검색 API 구현
본문: 키워드 + 벡터 검색을 RRF로 결합. 명세 ①번.

"나중에 할 일"도 이슈로 던져둔다. 개발 로그의 「넘어간 것」·「외부에 물어봐야 하는 것」이 전부 이슈감이다.

짧게 유지한다

1~3일 안에 머지한다. 오래 갈라져 있을수록 합칠 때 아프다. 이건 리뷰 부담 때문만이 아니라 충돌 때문이다.


4. 커밋

<type>: <summary>
규칙
type feat fix refactor test docs chore build ci perf revert
마침표 붙이지 않는다
scope 저장소 이름을 쓰지 않는다 (feat(ai): ✗)
✅ feat: 키워드 검색과 벡터 검색을 RRF로 결합
✅ fix: 인기 데이터 없는 신간이 검색에서 누락되던 문제
✅ chore: 개발 로그 명령어와 PR 템플릿 추가

❌ 검색 기능 추가함.
❌ feat(ai-server): update
❌ 수정

update modify 작업 같은 말만 쓰지 않는다. 뭐가 어떻게 됐는지가 드러나야 한다.

어차피 Squash로 합쳐지지만 의미 단위로 나누면 되돌리기 쉽고 리뷰어가 덩어리별로 볼 수 있다.


5. PR

템플릿은 자동으로 뜬다

.github/pull_request_template.md가 main에 있어서 PR을 열면 본문이 채워져 있다. 빈칸만 채우면 된다. 해당 없는 절은 통째로 지운다.

템플릿은 base 브랜치(main)의 것을 쓴다. 작업 브랜치에만 있으면 안 뜬다.

제목도 커밋과 같은 형식

GitHub이 브랜치 이름에서 제목을 자동 생성하는데(Feature/5 search api) 그대로 두면 컨벤션 위반이다. 반드시 고친다.

feat: AI 검색 API 구현

본문에서 중요한 것

절 왜
변경 이유 "무엇을"이 아니라 "왜". 코드를 보면 무엇을 했는지는 안다
제외 범위 리뷰어가 "이건 왜 안 했지?" 하지 않도록
검증 어떻게 확인했고 결과가 어땠는지
위험과 Rollback 되돌릴 방법. 장애 때 이걸 찾는다
Closes #5 머지되면 이슈가 자동으로 닫힌다

조건부 절 세 개는 해당할 때만 남긴다 — API 변경 / DB 변경 / AI 설정 변경.

크기

400줄 권장. uv.lock 같은 Lockfile은 기준에서 제외된다. 넘으면 분리하지 못한 이유와 리뷰 순서를 적는다.


6. 리뷰

우리는 2명이다

서로가 유일한 리뷰어다. 자기 PR은 자기가 승인할 수 없으므로, 상대가 안 봐주면 머지가 통째로 멈춘다.

  • 리뷰 시간을 정한다 — 예: 오전 10시, 오후 4시. "언제 봐주려나" 기다리는 시간이 사라진다
  • PR을 작게 올린다 — 작으면 5분이면 봐주지만 1,000줄이면 계속 미뤄진다
  • Self Review 먼저 — 올리기 전에 자기 diff를 한 번 읽는다. 오타·디버그 코드가 여기서 걸린다

뭘 보나

  1. 기능이 요구사항대로인가
  2. 보안·데이터 손실 가능성
  3. API·DB 하위 호환
  4. Rollback 가능한가
  5. 운영·관측 가능한가
  6. 테스트와 예외 처리
  7. 가독성

새 커밋이 붙으면 승인이 무효화된다

브랜치 보호에 걸려 있다. 승인받은 뒤 몰래 커밋을 추가할 수 없다.


7. 머지

Squash Merge만 가능하다. 다른 방식은 버튼 자체가 안 보인다.

최종 메시지를 정리한다

커밋이 여러 개면 그대로 합칠 때 지저분해진다. main의 커밋 하나가 완결된 변경을 설명해야 한다.

feat: AI 서버 초기 환경 구성

- AI Postgres 스키마(테이블 8개·인덱스 17개)
- 설정 로딩·DB 연결 풀·health 엔드포인트
- 개발 로그 명령어와 PR 템플릿

Closes #2

머지 후

git checkout main && git pull
git branch -d feature/5-search-api

원격 브랜치는 자동 삭제된다.


8. 충돌

어디서 나는지 이미 안다

담당이 나뉘어 있어 대부분은 안 부딪힌다. 문제는 이 셋뿐이다.

파일 언제 둘 다 건드리나
app/main.py 라우터를 등록할 때
app/core/config.py 환경변수를 추가할 때
.env.example 위와 같이

대응은 둘이다.

  • 짧게 만지고 바로 머지한다. 라우터 한 줄 등록하는 커밋을 며칠 묵히지 않는다
  • 미리 말한다. "오늘 main.py에 검색 라우터 등록할게" 한마디면 상대가 피한다

났을 때

git fetch origin && git rebase origin/main
# 충돌 파일 수정 후
git add <파일> && git rebase --continue
git push --force-with-lease

--force-with-lease를 쓴다. 그냥 --force는 상대가 그사이 올린 걸 덮어쓸 수 있다.


9. AI 저장소 고유 규칙

담당 경계 (2026-09-18 갱신)

담당 엔드포인트 주로 만질 파일
결정적 경로 (LLM 미사용) ① /search ② /embeddings ④ /recommendations/feed ⑥ /preferences/profile routers/search.py, routers/embeddings.py, routers/feed.py, routers/profile.py
대화형 경로 (LLM 사용) ③ /recommendations/chat (텍스트+이미지 턴 전체) ⑤ /preferences/extractions ⑦ /agent/act routers/chat.py, routers/extractions.py, routers/agent.py

③은 텍스트 턴과 이미지 턴을 나누지 않는다. 같은 핸들러가 후보검색·카드생성 파이프라인을 공유해서, 나누면 둘이 같은 코드를 동시에 건드리게 된다.

진짜 의존성 하나만 있다: ⑦의 "골라 담기"는 ④와 같은 취향 스코어링을 재사용한다(recommendations.candidates). 그래서 get_personalized_candidates(user_id, limit, exclude_book_ids) -> list[{book_id, match_score}] 시그니처만 먼저 계약으로 정해두고, ④ 담당자의 실제 구현이 끝나기 전까지는 스텁으로 대체해 ⑦을 개발한다.

공통 계층(설정·DB·예외 핸들러·미들웨어·게이트웨이 인터페이스)은 한 사람이 먼저 깔고 머지한 뒤 갈라진다.

DB는 각자 것이다

로컬 DB는 각자 노트북에 따로 있다. 이름만 같고 완전히 별개다. 공유되는 건 마이그레이션 파일뿐이다.

  • 손으로 ALTER TABLE을 치지 않는다. 내 DB만 바뀌고 팀원 DB는 그대로다
  • 스키마 변경은 새 마이그레이션 파일로 추가한다. 001_init.sql을 고치지 않는다
  • 머지 후 팀원에게 알린다 — "마이그레이션 생겼어요, 적용하세요"
  • 파일 이름은 날짜로 (20260918_add_something.sql). 둘 다 002_를 쓰면 충돌한다

데이터는 부분집합으로

카탈로그 57만 권을 매번 넣을 필요는 없다. 개발용은 1만 건이면 검색 테스트에 충분하고 1분이면 끝난다. 전량은 성능을 잴 때만.

모델·프롬프트를 바꾸는 PR

PR 본문 「AI 설정 변경」 절을 채운다 — Provider, Model ID, Prompt Version, 고정 Dataset 검증 결과, 응답 시간·비용 변화, Timeout·Fallback 영향.

고정 질의 세트를 만들어 두고 같은 세트로 재야 비교가 된다.

벡터 차원이 바뀌면 단독 배포

book_embeddings·taste_profile 전량 재생성이 필요하고, taste_profile은 BE가 전 사용자 ⑥을 재호출해야 한다. 일반 기능 배포에 섞지 않는다.

계약은 임의로 바꾸지 않는다

API 명세와 ERD가 단독 소스다. BE와 합의된 계약이라 혼자 바꾸면 연동이 깨진다. 바꿔야 하면 먼저 얘기하고, PR 본문 「API 변경」 절에 변경 전후·호환 여부·배포 순서를 적는다.


10. 막힐 때

상황
환경이 안 뜬다 로컬 개발 환경 세팅 §8 자주 겪는 문제
명세가 애매하다 혼자 판단하지 말고 얘기한다. 계약은 BE와 묶여 있다
리뷰가 안 온다 리뷰 시간을 정해둔다. 그동안 다음 브랜치를 판다
충돌이 크다 rebase를 미룬 것이다. 다음부터 하루 한 번

하루 요약

아침   git checkout main && git pull → 브랜치 파기
작업   의미 단위 커밋 · 하루 넘기면 rebase
저녁   push → PR → 리뷰 요청
수시   상대 PR 리뷰

원칙 셋:

  1. 파일이 안 겹치게 나눈다 (담당 경계 = 모듈 경계)
  2. 브랜치를 묵히지 않는다 (1~3일)
  3. 공통 파일을 건드릴 땐 미리 말한다

← AI Wiki

⚠️ **GitHub.com Fallback** ⚠️