Refactor/25/matching consistency 매칭 정합성 보강 및 주문 처리 흐름 문서화#26
Conversation
1. 오더북 롤백 불일치 — planMatch/applyMatchPlan 분리 DB 롤백 시 in-memory 큐가 이미 변경된 상태로 남는 문제 해소. afterCommit() 훅으로 applyMatchPlan() 호출을 커밋 이후로 보장. 2. 오더북 동시 읽기 — marketLock 재사용 REST 오더북 조회 시 marketLock 없이 PriorityQueue를 stream()하면 ConcurrentModificationException 발생. MarketController에서 기존 OrderService.marketLock을 획득한 뒤 조회하도록 수정. 3. Maker order row lock 누락 — SELECT FOR UPDATE 적용 settle() 내 maker 조회를 findByIdWithLock()으로 교체, fill 이전 isCancelable() 상태 재검증 추가. 4. DepositRequest 입력 검증 누락 — @notblank / @pattern 추가 null·빈 문자열 입력 시 NPE/NumberFormatException 방지. WalletController에 @Valid 추가.
- DomainEventRecorder.save(): payload를 schemaVersion+occurredAt 엔벨로프로 래핑 - DomainEventRepository: findAllByPublishedFalseOrderByIdAsc() 추가 (발행순서 보장) - V5__create_processed_events.sql: 컨슈머별 중복 처리 방지용 테이블 생성
- OrderController: @validated + limit(@min(1)@max(200))/offset(@min(0)) 파라미터 추가 - OrderService.getOrders(): PageRequest.of(offset/limit, limit) 적용 - OrderRepository: 목록 조회 메서드 Pageable 파라미터 추가 - TradeRepository: userId 조회를 keyset 페이지네이션으로 변경 (lastFillId > :lastFillId ORDER BY id ASC) - TradeController.getFills(): lastFillId/limit 파라미터 추가
- MatchingSettlementTest/DomainEventTest @beforeeach: domain_events → wallet_ledgers → trades → orders → wallets → users 순서로 deleteAllInBatch() 호출 - 테스트 간 데이터 간섭 제거, 외래 키 제약 위반 방지
- docker-compose.yml: MySQL 8.0 + Zookeeper + Kafka(confluentinc/cp-kafka:7.6.0) 구성 추가 - application.properties: DB_PASSWORD 기본값을 빈 문자열에서 coinflow로 변경 (docker-compose 설정과 일치)
- cancelOrder() 오더북 변경을 afterCommit()으로 이동 — DB 롤백 시 in-memory 불일치 방지 - OffsetBasedPageRequest 도입으로 주문 목록 offset 처리 수정 - TradeController limit/lastFillId 파라미터 유효성 검증 추가 (@Min/@max) - GlobalExceptionHandler에 ConstraintViolationException 핸들러 추가 - 테스트 3종 @beforeeach에 DB 전체 클린업 추가 (FK 순서 준수) - docker-compose MYSQL_PASSWORD → DB_PASSWORD 통일
Zero-quote 체결 — DB 제약 위반 가능성 정리 rounding 후 quoteAmount가 0인 체결이 생성되면 trades.quote_amount > 0 제약을 위반하는 문제를 문서화. Dust maker 잔존 — 체결 불가능 주문이 오더북에 남는 문제 정리 체결 후 maker 잔량의 quote value가 0이 되는 경우 자동 취소가 필요함을 명시. Deposit API 운영 노출 — MVP 범위와 보안 위험 정리 입출금은 MVP 제외 범위인데 운영 프로필에서 deposit endpoint가 열려 있는 문제를 BLOCKER로 분류. API/락/복구/인프라 불일치 — 후속 정리 항목 문서화 Market/Fills/OrderBook 응답 명세, cancel row lock, wallet lock ordering, afterCommit 복구, Kafka KRaft compose 불일치를 우선순위별로 정리.
Zero-quote 체결 — planMatch 단계에서 매칭 중단 DOWN(price * matchedQuantity, amountScale) 결과가 0이면 MatchResult를 생성하지 않고 매칭을 중단하도록 수정. Dust maker 잔존 — 자동 취소 및 locked balance 해제 체결 후 maker 잔량의 quote value가 0이면 maker를 CANCELED 처리하고 남은 locked balance를 ORDER_CANCEL_RELEASE로 반환. Cancel order row lock — SELECT FOR UPDATE 적용 cancelOrder() 트랜잭션 내부 주문 조회를 findByIdAndUserIdWithLock()으로 교체해 취소 대상 order row를 잠그도록 수정. Wallet lock ordering — (userId, asset) 정렬 적용 정산 중 여러 wallet을 잠글 때 (userId, asset) 오름차순으로 잠그도록 lockWalletsInOrder() 추가. afterCommit 실패 복구 — DB 기반 오더북 재빌드 추가 applyMatchPlan() 실패 시 failure metric을 증가시키고 OPEN/PARTIALLY_FILLED 주문으로 오더북을 재빌드. Dead code — MemoryOrderBook.match() 제거 planMatch/applyMatchPlan 흐름으로 대체된 stateful match() 메서드 제거.
Deposit API 운영 노출 — prod 프로필 제외 POST /api/v1/wallets/deposit을 WalletController에서 분리하고 DevWalletController에 @Profile("!prod") 적용. MVP 범위 불일치 — seed API를 개발/테스트 용도로 제한 입출금은 MVP 제외 범위이므로 운영 환경에서 인증 사용자가 임의로 잔액을 증가시킬 수 없도록 수정. Ledger 조회 limit — Pageable 조회 적용 GET /api/v1/wallets/ledgers?limit=50 명세에 맞게 repository와 service에 Pageable 기반 조회 추가. 회귀 테스트 — ledger limit 검증 추가 원장 조회 시 limit 값만큼 결과가 제한되는지 테스트 추가.
Market response 필드 불일치 — market/amountScale/cancelOnly 추가
API.md 명세에 맞게 symbol 응답을 market으로 변경하고 amountScale, cancelOnly 필드를 추가.
OrderBook 가격 레벨 — 같은 가격 주문 수량 합산
개별 주문을 그대로 노출하던 응답을 가격별 합산 수량으로 변경.
OrderBook depth — 가격 레벨 개수 제한 추가
GET /api/v1/markets/{market}/orderbook?depth=10 파라미터를 지원하도록 수정.
Fill response 명세 불일치 — side/settled/M·T liquidity 적용
사용자 관점 체결 응답에 side와 settled=true를 추가하고 liquidity 값을 MAKER/TAKER에서 M/T로 변경.
Fill orderId 필터 — 사용자 주문 검증 추가
GET /api/v1/fills?orderId=... 필터를 추가하고 본인 주문이 아니면 ORDER_NOT_FOUND를 반환하도록 수정.
회귀 테스트 — API 명세 정합 검증 추가
market 응답 필드, orderbook 합산/depth, fill 응답 필드, orderId 필터 테스트 추가.
Kafka 구성 불일치 — Zookeeper 기반 compose 제거 v2 문서는 KRaft Kafka를 전제로 하지만 docker-compose는 Zookeeper 기반으로 구성되어 있던 문제 수정. KRaft 단일 노드 — broker/controller 통합 설정 추가 KAFKA_PROCESS_ROLES, KAFKA_CONTROLLER_QUORUM_VOTERS, KAFKA_CONTROLLER_LISTENER_NAMES 등 KRaft 필수 설정 추가. Local state — kafka_data volume 추가 Kafka 로컬 데이터 보존을 위한 kafka_data volume 추가. Compose 검증 — docker compose config 통과 변경된 compose 파일이 정상 파싱되는지 확인.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (32)
📝 WalkthroughWalkthroughThis PR implements a two-phase order matching architecture with market-level locking, dust maker auto-cancellation during settlement, comprehensive API contract alignment (endpoints, DTOs, repositories), wallet deposit endpoint restructuring, and Docker Compose infrastructure for MySQL/Kafka. All referenced priority issues (1–9) from the issues log are addressed via code refactoring and new features. ChangesOrder Matching, Settlement, and Market Locking
API Endpoints, DTOs, and Repository Updates
Infrastructure, Configuration, and Database
Test Infrastructure, Cleanup, and Coverage
Issue Documentation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
작업 내용
관련 이슈
closes #이슈번호
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Chores