AI와 함께 수직 통합형 커머스 시스템을 구축하며 우연히 발견한 4가지 거버넌스 패턴
요약
비전공자가 Claude와 페어 프로그래밍을 통해 수직 통합형 커머스 시스템을 구축하며 발견한 4가지 거버넌스 패턴을 소개합니다. AI 세션의 컨텍스트 유지를 위해 마크다운 기반의 패턴 기록이 왜 중요한지 설명합니다.
핵심 포인트
- AI 페어 프로그래밍 시 프로젝트 내 마크다운 패턴 기록의 중요성
- 데이터 동기화 오류를 방지하기 위한 거버넌스 패턴의 필요성
- 비전공자도 AI를 활용해 복잡한 시스템을 유지 관리할 수 있는 가능성
- Claude Code를 활용한 대규모 코드베이스(14,000+ 파일) 관리 경험
2026년 5월 · 시리즈 "Trace Lock — 코드를 작성하기 위해 AI와 페어 프로그래밍하며 얻은 거버넌스 노트" · 9개 포스트 중 1번째 (메타)
2026년 5월, Claude(나의 AI 페어 프로그래밍 도구)와 나는 진심으로 예상치 못했던 일을 해냈습니다.
우리는 "버그 수정 → 또 다른 버그 발생 → 그것을 수정 → 또 다른 버그 발생"이라는 6개월간의 루프 속에서 4가지 방법론 패턴(가칭 — 그 이유는 잠시 후에 설명하겠습니다)을 천천히 추출해 냈습니다.
나는 바리스타입니다. 나는 AI와 페어 프로그래밍(pair-programming)을 하며 직접 구축한 수직 통합형(vertically-integrated) 커머스 시스템을 유지 관리하고 있습니다. 내가 이 9개 포스트 시리즈를 쓰는 데에는 세 가지 이유가 있습니다.
- 나는 왜 이런 방식으로 설계했는지 3개월 뒤면 잊어버릴 것입니다.
- 모든 새로운 AI 세션은 제로(zero) 상태에서 시작됩니다. 패턴을 프로젝트 내에 마크다운(markdown)으로 작성해 두면, 다음 대화 시 자동으로 온보딩(onboarding)이 이루어집니다 (우리가 시작하기 전에 AI가 이를 읽습니다).
- 우리와 같은 사람들—컴퓨터 과학(CS) 배경이 없지만, AI와 페어 프로그래밍을 하며, 중간 정도의 복잡성을 가진 시스템을 혼자 유지 관리하는 사람들—이 점점 더 많아져야 합니다. 만약 이 시리즈가 단 한 명이라도 1년 동안 시행착오를 겪는 것을 줄여줄 수 있다면, 쓸 가치가 있습니다.
이 포스트는 시리즈의 메타(meta) 항목입니다 — 맥락, 왜 이러한 패턴들이 나타났는지, 그리고 4가지 패턴이 무엇인지에 대해 다룹니다. "실제로 어떻게 하는가"에 대한 내용은 다음 8개의 포스트에서 다룹니다.
내 시스템은 무엇인가
- 지난 7년 동안 나는 내 사업을 운영하기 위해 여러 기성 SaaS(포스(POS), 회원 시스템, 스프레드시트 더미 등)를 짜깁기해 왔습니다.
- 2024년에 나는 수직 통합형(vertically-integrated) 시스템을 직접 구축하기로 결정했습니다 — 제품 / 주문 / 재고 / 회원 / 로스팅 스테이션 / 패키징 스테이션 / 배송이 모두 하나로 연결된 시스템입니다.
- 스택(Stack): Vue 3 프론트엔드(frontend), Supabase 백엔드(backend), 페어 프로그래밍(pair-programming)을 위한 Claude Code
- 규모(Scale): 14,000개 이상의 파일, 40,000개 이상의 코드 관계 (인덱싱 도구의 수치)
내가 계속해서 발견한 패턴
6개월 동안 나는 동일한 유형의 버그에 계속 부딪혔습니다:
"데이터가 쓰기 측(write-side)에서 렌더링 측(render-side)으로 흐르는데, 중간 어딘가에서 한 레이어(layer)가 동기화(sync)를 잊어버립니다. 그러면 무언가 고장 납니다."
구체적인 예시:
- 주문 결제 상태(Order payment status)가 주문 상태(order status)와 동기화되지 않았습니다. 고객은 결제를 완료했다고 생각하지만, 백엔드(backend)에는 미결제(unpaid)로 표시됩니다.
- 선불 충전(Stored-value top-up) 플랜이 실수로 포장 작업 시트(packaging worksheet)에 포함되었습니다. 로스터(roaster)는 "스토어 크레딧(store credit)을 어떻게 포장하라는 거지?"라며 혼란스러워했습니다.
- 13개의 커피 제품이 스토어프론트(storefront)에서는 소비자에게 "품절(out of stock)"로 표시되었지만, 관리자 백엔드(admin backend)에서는 정상으로 표시되었습니다 (관리자/익명 뷰 불일치 (admin / anon view discrepancy)).
- 한 VVIP 고객이 5,000달러를 충전했으나 잘못된 보너스 금액을 받았습니다.
- "미디엄-다크(medium-dark)" 로스트 등급을 추가한 후, UI에 영문 열거형 코드(English enum code)가 그대로 표시되었습니다 (번역 누락).
- 한 고객이 "0.5파운드 제품의 드립백 변형(drip-bag variant of a half-pound product)"을 주문했는데, 단 1팩만 주문할 수 있었습니다 (시스템이 이를 0.5파운드 그램(grams)으로 계산함).
각 수정 작업에는 35시간이 소요되었습니다. 6개월 동안 동일한 유형의 버그가 56번 발생했습니다.
고통스러운 점은 수정 작업 그 자체가 아닙니다. 근본 원인(root cause)이 해결되지 않았기 때문에, 수정하고 한 달 뒤에 유사한 버그(sibling bug)가 다시 나타난다는 점입니다. 제대로 된 팀이라면 이러한 문제를 잡아내기 위해 QA / SRE / PM / 코드 리뷰(code review)를 운영하겠지만, 저에게는 그런 것이 없습니다.
모든 것을 바꾼 대화
5월 25일, 저는 또 다른 유사한 문제를 맞닥뜨렸습니다. 고객의 스크린샷 내용: "'로스팅 완료(complete roasting)' 버튼이 멈춰 있고, '로스트 레벨 불일치(roast level mismatch)'라고 뜹니다.
저는 평소처럼 해결하려 했습니다. RAISE 문 하나를 주석 처리하고 끝내는 방식 말이죠. 하지만 Claude에게 한 가지 질문을 던졌습니다:
"지난 6개월 동안 이런 문제를 5번이나 해결했습니다. 지금 멈춰서 **이와 동일한 형태의 모든 누수(leaks)**를 찾아 한꺼번에 해결해야 할까요?"
Claude는 다음과 같이 제안했습니다: 먼저 전체 비즈니스 흐름(business flow)을 감사(auditing)하는 데 1시간을 쓰세요. 어떤 체인 노드(chain nodes)가 보호되지 않고 있는지 목록을 만드세요. 그런 다음 무엇을 먼저 수정할지 결정하세요.
저는 Claude와 함께 1시간 동안 흐름을 매핑(mapping)했습니다. 그 결과 다음과 같은 사실을 발견했습니다:
- 비즈니스 흐름 내 11개의 체인 노드(chain nodes)
- 5개는 이미 잘 보호되고 있음
- 2개는 부분적으로 보호되고 있음
- 4개는 완전히 보호되지 않은 차단 요소(BLOCKERs)
그 4개의 차단 요소(BLOCKERs)에는 "주문 취소 / 환불 흐름(order cancel / refund flow)", "로스팅 완료 단계(roasting completion stage)", "FIFO 원재료 소비(FIFO ingredient consumption)", "포장 스테이션 작업 상태(packaging station task state)"가 포함되어 있었습니다. 각각은 "다음 고객이 여기서 걸려 넘어지면 나에게 3~5시간의 비용을 발생시킨다"는 지뢰와 같았습니다.
그 후 Claude와 저는 7시간 동안 4가지 차단 요소(BLOCKERs)를 한꺼번에 해결했습니다. 게다가 향후 관련 코드를 수정할 때 자동으로 나에게 알려주는 메커니즘도 구축했습니다.
과정 중에 나타난 4가지 패턴
이 4가지 패턴은 그 7시간 동안 점진적으로 저에게 다가왔습니다. 미리 알고 있었던 것이 아닙니다. 사후에 복기하면서 구체화되었습니다.
패턴 1: "버그 수정"과 "체인 감사"는 근본적으로 다른 사고 모드이다
버그 수정 (Fix a bug) = 고객이 보고한 특정 증상에서 시작하여, 외부로 추적하며 근본 원인을 수정하는 것.
체인 감사 (Audit a chain) = 비즈니스 흐름의 진입점부터 종료점까지 걸어가며, 각 노드(node)가 보호되고 있는지 목록을 작성하는 것.
지난 6개월 동안 저는 첫 번째 방식만 해왔습니다. 첫 번째 방식의 문제는 보고된 버그만 수정한다는 점입니다. 보고되지 않은 버그들은 계속 숨어 있습니다.
두 번째 방식은 더 많은 작업(1시간의 감사)처럼 보이지만, 아직 나타나지 않은 문제들을 드러내기 때문에 투자 대비 효율(ROI)이 훨씬 높습니다.
저는 이 두 가지 사고 모드에 작업 명칭을 붙였습니다: "외부에서 내부로 (outside-in, 전체 체인을 외부에서 바라보기) vs 내부에서 외부로 (inside-out, 특정 버그에서 외부로 추적하기) 디버깅." 하지만 이는 저만의 명칭일 뿐입니다. 정식 소프트웨어 공학(software engineering)에는 아마 이미 더 정확한 용어들이 있겠지만, 확실하지는 않습니다.
패턴 2: 고객이 있는 자리에서 내린 결정은 3개월 후에 잊혀진다
이 4가지 차단 요소(BLOCKER) 수정은 모두 비즈니스 결정과 관련이 있었습니다:
- 환불 시 현금을 먼저 돌려줄 것인가, 보너스를 먼저 돌려줄 것인가? (저는 현금 우선을 선택했습니다. 원래 로직은 보너스를 먼저 차감했으므로, 현금 우선 역산(reversal)을 통해 균형을 유지합니다.)
- "굽기 정도 불일치"가 발생했을 때 운영자를 차단할 것인가, 아니면 경고를 작성하고 계속 진행하게 할 것인가? (운영 스테이션이 멈추는 것을 방지하기 위해 후자를 선택했습니다.)
- 포장 작업이 "건너뜀(skipped)" 상태를 지원해야 하는가? (상태 머신(state-machine)의 폭발을 방지하기 위해 아니오를 선택했습니다.)
이러한 결정들은 그 순간에는 당연하게 느껴지지만, 3개월 후에 저나 다른 엔지니어(또는 AI)가 코드를 읽을 때는 "이 로직은 이상하네, 정리 좀 해야겠다"라고 생각할 수도 있습니다.
Claude의 제안: 그러한 결정 사항들을 인시던트 고정 주석이 포함된 테스트 케이스 (test cases with incident-pinning comments)(즉, "왜"라는 설명이 포함된 테스트)로 작성하십시오. 6개월 후, 누군가 코드를 수정할 때 테스트가 빨간색(fail)으로 실패하게 함으로써, 그들이 원래의 결정 맥락을 강제로 확인하게 만드는 것입니다.
저는 이 관행에 "결정 고정 (Decision Pinning)"이라는 작업 명칭을 붙였습니다. 같은 내용이지만, 제가 임시로 붙인 이름입니다. 업계에 더 표준화된 용어가 있는지는 모르겠습니다.
패턴 3: 계층 간 의존성 (Cross-layer dependencies)은 자산(assets)으로 관리되어야 한다
소프트웨어 시스템은 "A를 변경하면 반드시 B도 변경해야 한다"는 식의 계층 간 의존성 (cross-layer dependencies)으로 가득 차 있습니다. 예를 들어:
- RPC 반환 형태(return shape) 변경 → 정규화 함수(normalize function)의 화이트리스트(whitelist) 동기화 필요 → UI 렌더링(render) 측 동기화 필요
- SSOT(단일 진실 공급원) 필드 변경 → 모든 호출자(caller) 동기화 필요
역사적으로 이러한 관계는 오직 제 머릿속에만 존재했습니다. 3개월 후, 이를 잊어버린다는 것은 "A는 변경했지만 B는 잊어버렸다"는 것을 의미합니다.
Claude와 저는 "트레이스 락 (Trace Lock)"(다시 한번 임시 명칭입니다)이라고 부르는 것을 설계했습니다:
- 각 계층 간 관계를 마크다운(markdown) 테이블에 등록
- 현재의 올바른 동작을 고정하는 "퓨즈 테스트 (fuse test)"와 쌍을 이룸
- 회귀(regression)를 차단하는 두 가지 "자동 검사기 (auto-inspectors)"(거버넌스 규칙)와 쌍을 이룸
- "AI 리마인더 (AI reminder)"(영향을 받는 파일을 편집하려 할 때 Claude Code가 자동으로 알려줌)와 쌍을 이룸
이 설정은 현재까지 잘 작동하고 있습니다. Claude와 저는 이번 감사(audit) 중에 sql-only-trace(순수 DB 로직을 위한 테스트 접근 방식)라는 새로운 하위 카테고리를 추가하여 이를 확장했습니다.
패턴 4: 공격(Offense) + 방어(Defense)를 이중 모드로 운용
패턴 1과 패턴 3을 결합하면 더 큰 패턴이 드러납니다:
- 공격 모드 (Offense mode) (감사 + N개 항목을 한 번에 수정) = 선제적으로 공격하여 새로운 보호 장치를 구축
- 방어 모드 (Defense mode) (트레이스 락 + 자동 트리거) = 수동적으로 방어하며 회귀(regression)를 차단
둘 중 하나만으로는 충분하지 않습니다:
- 공격이 없다면 → 보호 범위가 확장되지 않아 버그가 계속 쌓임
- 방어가 없다면 → 기존의 보호 장치가 부식됨
- 둘을 함께 사용하면 → 시스템의 "엔트로피 (entropy)"가 감소하는 방향으로 움직임
물리학에서 엔트로피 (entropy, "무질서"라고 생각하면 됩니다)가 단조 증가하는 것은 "자연스러운" 현상입니다. 엔트로피를 감소시키려면 지속적으로 에너지를 주입해야 합니다. 소프트웨어 버그의 개수도 동일한 논리를 따른다고 생각합니다 (이는 제가 개인적으로 이해하는 방식일 뿐이며, 엄밀한 비유라고 주장하는 것은 아닙니다).
이 시리즈에서 다룰 내용
다음 내용들을 작성할 계획입니다:
- A1 Defensive Trace Lock: 단일 교차 계층 관계 (cross-layer relationship)를 어떻게 잠글 것인가 (미래의 나를 위해; 컴퓨터 과학 학위 없이도 읽을 수 있도록 작성)
- B1 Offensive audit: 전체 비즈니스 흐름을 어떻게 주기적으로 감사 (audit)할 것인가 (미래의 나를 위해; 컴퓨터 과학 학위 없이도 읽을 수 있도록 작성)
- C1 Offense + Defense combined: 이 둘이 어떻게 결합되는가 (미래의 나를 위해)
- D sql-only-trace: 순수 DB 로직을 어떻게 테스트할 것인가 (엔지니어 대상의 기술적 세부 사항)
- A2 / B2 / C2 Engineer versions: 위 3가지 항목의 엔지니어링 등급 버전 (관심 있는 엔지니어들을 위해, 코드 샘플 및 프로젝트 간 재사용 매트릭스 포함)
- Index post: 독자들을 위한 "어떤 글을 먼저 읽어야 하는가"에 대한 지도
만약 하나만 읽는다면, A1 (방어적 방식)을 추천합니다. 이 모든 것이 시작된 지점이기 때문입니다.
관련 글
- A1 · Defensive Trace Lock (시리즈의 다음 글)
- 시리즈 인덱스 (읽기 지도)
- 中文版 (중문판)
이 글에 대하여
이 글은 2026년 5월 동안 Claude (AI 페어 프로그래밍 도구)와 나누었던 대화들을 정리한 기록입니다. 미래의 참고를 위해 간직할 만한 몇 가지 패턴을 발견했고, Claude에게 이를 글로 구조화하도록 요청했습니다.
제가 주장하지 않는 몇 가지 사항:
- 이 글에서 사용된 용어들 (Decision Pinning / Trace Lock / outside-in vs inside-out / offense vs defense / sql-only-trace)은 제가 직접 붙인 임시 명칭이며, 업계 표준 용어가 아닙니다.
- 제 시스템은 특정한 형태를 띠고 있습니다 (1인 유지보수, 많은 교차 계층 의존성, 모호한 비즈니스 계약). 따라서 이 패턴들이 귀하의 상황에는 적용되지 않을 수 있습니다.
- 저는 소프트웨어 엔지니어가 아닙니다. 그저 AI와 페어 프로그래밍을 하며 코드를 작성하는 바리스타일 뿐입니다.
만약 전문 엔지니어가 오용 사례를 발견하거나, 이러한 개념 중 어떤 것에 대해 이미 더 표준적인 명칭이 존재한다면, 저는 진심으로 수정을 환영합니다.
본문은 제 블로그에 게재되었습니다: I built a vertically-integrated commerce system with AI — and accidentally discovered 4 governance patterns
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기