구매기업이 공급사와 직접 거래하는 트랙을, 이미 운영 중이던 대행(agency) 트랙 위에 얹은 기능. 신규 개발이 아니라 돌아가는 파이프라인에 대한 개조였다. 운영사가 거래 당사자에서 빠지므로, 판정 → 장바구니 → 주문 → 정산 → 클레임 → 통계까지 전 계층에서 운영사를 걷어내야 한다.
2축 판정
판정 3값
운영사 API 0개
잔차 0 청구 축
200개 테스트
고객사 연결 × 품목 소유자
직거래 / 대행 / 차단
격리를 필터가 아닌 부재로
라인합계를 그대로 청구
31개 파일 (단위·슬라이스)
왜 이 설계가 필요했는가 (Problem)
검토했던 판정 축 (Analyze)
“이 주문이 직거래인가”를 무엇으로 판정할지 — 이 선택이 나머지 전부를 결정했다.
대안
장점
기각 사유
선택
1. 상품 테이블에 직거래 여부 컬럼
조회 단순, 인덱스 1개면 끝
같은 상품이 기업마다 다른 트랙이다 — 표현 불능
❌
2. 공급사 단위 플래그
쌍 단위라 관리 지점이 적음
같은 공급사도 품목별로 소유자가 갈린다
❌
3. 주문 시점에 사용자가 선택
구현 최단, 판정 로직 불필요
오지정 한 번에 정산 축이 통째로 틀어지고 사후 감사가 불가능
❌
4. (고객사 연결 × 표준품목 소유자) 2축 판정
기업별·품목별 차이를 정확히 표현, 원자료가 남아 감사 가능
조인 깊이 증가 · 목록 판정 시 N+1 위험
✅ 선택
핵심 설계 결정
1. 2축 판정 — 6개 조건이 전부 AND
6개 조건은 어느 하나만 흘려도 판정이 반대로 뒤집힌다. 그래서 AND 묶음을 한 번에 검증하지 않고, 조건별로 쪼개 각각 독립 테스트로 고정했다.
2. 트랙 순도 — 2단 가드
3. 격리는 조인이 아니라 스냅샷 등호
4. 운영사용 직거래 API 를 0개로 둔 것
5. 공급사 청구 축 = 라인합계 (개당 축 금지)
6. 연결·초대 생명주기
상황
처리
사업자번호 일치 공급사 1곳
연결요청 + 사업자번호 스냅샷
복수 공급사와 일치
임의 선택하지 않고 초대로 전환 — 오연결 방지
미가입 사업자번호
초대 + 토큰 발급 → 가입 후 이메일 매칭으로 소진
연결 해제
행을 지우지 않고 사용 여부만 끈다 (다른 출처 행은 불변)
재연결
해제된 직거래 행을 다시 켠다 — 새 행을 만들지 않음
승인 시 수동 등록 행이 이미 있음
출처를 직거래로 승격 (목록·해제 토글 정합)
7. 예산 환원 — 직거래 원장만
설계가 만든 결과 (Result)
계층별 검증 분포
계층
대표 테스트
고정한 불변식
판정
자동승인 판정 쿼리 (15) 판정 서비스 (9)
6개 AND 조건 각각 독립 검증 · 고객사 소유 + 연결 없음 → 차단(대행 폴백 금지) · 목록 판정 쿼리 1회(N+1 금지) · 트랙이 비어 들어와도 예외 없이 대행
트랙 순도
주문 트랙 (22) 장바구니 순도 (6)
혼합 거부 · 차단 단독도 거부(스냅샷 역산 전제 보호) · 선택 해제는 미검사 · 1건 이하는 판정 미호출
운영사 격리
격리 가드 (4) 주문 목록 쿼리 · 카탈로그 숨김 (6)
직거래 라인 혼입 시 404(존재 미누설) · 대행 전용은 통과(positive control) · 목록·카운트·요약·엑셀 어디에도 노출 안 됨 · 카탈로그 self-map·0-노출은 숨기지 않음(공허참 방지)
정산 축
공급가 청구 축 (6) 공급사 정산 쿼리 (4)
잔차 0 · 전량 취소 시 최종 청구액 정확히 0 · 대행 주문에 닿지 않음(fail-closed) · 타 공급사 조회 0건
연결·초대
초대 수락 (10) 연결요청 생성 (10)
다른 이메일 수락 불가(링크 유출 방어) · 복수 후보는 초대로 · 기연결이면 초대도 차단 · 만료 초대는 상태·토큰 무변경
예산 환원
예산 환원 (8)
여신 원장 오복원 가드 · 순잔액 상한 · 전량 복원 후 재집행 멱등
통계·클레임
통계 차원 (2) 클레임 환불 (3)
적재 5문 전부가 차원을 싣는다 · 병합은 주문 헤더 조인(라인 축 금지) · 마이너스 PO 가 트랙을 승계
괄호 안 숫자는 대표 테스트의 개수다(합계 105개). 전체 200개 중 계층마다 대표만 추렸다.
회귀로 고정한 위험 지점
동시성 결함 — 연결요청 중복 가드 (미수정)
이 검증이 말하지 않는 것
데이터 구조
데이터
역할
연결요청
요청 / 초대 · 사업자번호 스냅샷
초대 토큰
미가입 공급사 초대 · 만료·소진 관리
정산 헤더·라인
고객사 × 과세형태로 그룹 분할
거래명세서 헤더·라인
당사자 스냅샷
명세서 상태 이력
상태 변경 이력
세금계산서
금액·당사자를 명세서에서 복사(수기 입력 아님)
입금 이력
헤더 입금상태를 합계 기준으로 재계산
이 외에 주문·발주·클레임·장바구니·기업 등 기존 테이블에 직거래 여부 스냅샷 컬럼을 추가했다.