
[둥지] Claude Routines로 일일 PR 자동 리뷰 루틴 구축하기
Claude Code의 Routines 기능으로 Doongzi GitHub PR을 매일 아침 자동 코드 리뷰하고 카카오톡 나에게보내기로 수신하는 루틴을 구축한 과정을 공유합니다.

Claude Code의 Routines 기능으로 Doongzi GitHub PR을 매일 아침 자동 코드 리뷰하고 카카오톡 나에게보내기로 수신하는 루틴을 구축한 과정을 공유합니다.
GET /api/til/{summaryId}/recall-cards 구현 과정에서 결정한 사항들 — LIMIT 대신 threshold 기반으로 전환한 이유, 코사인 거리 0.3의 의미, LazyInitializationException 원인과 @Transactional 해결까지 기록합니다.
GlobalExceptionHandler가 필요한 이유, ErrorCode 인터페이스로 도메인별 에러코드를 일원화하는 방법, @ModelAttribute 검증 실패가 500을 반환한 원인과 BindException 단일 핸들러로 통합하기까지 정리합니다.
AsyncJobProcessor 인터페이스를 구현한 클래스에 @Async를 붙였을 때 @TransactionalEventListener handle() 메서드를 프록시에서 찾지 못해 기동이 실패한 원인과 해결 과정을 기록합니다.
GET /api/search 구현 과정에서 결정한 사항들 — Scrap을 검색 풀에서 제외한 이유, AiEmbeddingClient 인터페이스 분리 전략, @ModelAttribute 검증 실패가 500을 던진 원인과 BindException 핸들러 통합, CGLIB 프록시 기동 실패까지 기록합니다.

워커 사망, IROS 잔액 부족, OpenAI quota 초과 등 즉각 대응이 필요한 운영 이벤트를 Discord 웹훅으로 알림 받도록 구현한 과정을 기록합니다. 알림 채널 선택, 공통 모듈 설계, 트리거 포인트 결정 근거를 중심으로 정리합니다.
pgvector 기반 유사도 검색 엔진을 설계하면서 마주친 ERD 제약 — knowledge_cards의 user_id 부재, float[] 직렬화 문제, NOT IN 빈 리스트 SQL 오류 — 을 어떻게 풀었는지 의사결정 과정을 기록합니다.
MVP 단계에서 Kafka 없이 Spring Event로 비동기 파이프라인을 구현한 이유를 정리합니다. 이벤트 기반 구조의 결합도 분리, @TransactionalEventListener AFTER_COMMIT 타이밍 문제, 스레드 풀 분리, Short Polling 선택까지 의사결정 과정을 기록합니다.

TIL 페이지 하단 리콜 카드 목록을 설계하면서 생긴 의문점들 — DB 저장 vs 실시간 조회, 어떤 임베딩 기준으로 추출할지, 임베딩 테이블 분리 안티패턴, NULL 허용 여부 — 의사결정 과정을 기록합니다.

async_jobs 단일 테이블로 여러 비동기 작업을 관리하는 DB 설계를 기록합니다. target_id에 FK를 걸지 않은 이유(다형적 연관관계), error_message를 파일 로그 대신 DB에 저장하는 이유를 중심으로 정리합니다.