[STK5-04] 계좌 목록·선택 API + 매수가능·매도가능·수수료 조회 API
작업 내용 (설계 의도)
변경 사항
account 도메인을 외부로 노출하는 UseCase·Controller를 구성한다. STK5-02 완료 후 착수한다. STK5-05·STK5-06과 독립적인 파일(account 패키지 컨트롤러)이므로 병렬 진행 가능하다.
구성 범위:
- application UseCase:
ListAccountsUseCase,SelectAccountUseCase,GetPurchasableAmountUseCase,GetSellableQuantityUseCase,GetTradingFeeUseCase - presentation:
AccountApiController - application dto:
TradableAmountResponse,TradingFeeResponse
API 엔드포인트:
GET /api/v1/accounts— 계좌 목록 조회 (Toss fetch → MySQL upsert → 응답)PUT /api/v1/accounts/{accountNumber}/select— 활성 계좌 선택GET /api/v1/accounts/purchasable?symbol=&quantity=&price=— 매수 가능 금액GET /api/v1/accounts/sellable?symbol=&quantity=— 매도 가능 수량GET /api/v1/accounts/fee?symbol=&quantity=&price=&orderType=— 수수료 조회
가능금액·수수료 3개 API는 MySQL 저장 없이 Toss API를 즉시 프록시한다.
다이어그램
처리 흐름 (계좌 목록 조회)
sequenceDiagram participant C as AccountApiController participant U as ListAccountsUseCase participant DS as AccountDomainService participant G as AccountGateway participant R as AccountRepository C->>U: execute() U->>DS: listAccounts() DS->>G: fetchAccounts() G-->>DS: List<AccountData> DS->>R: upsertAll(accounts) R-->>DS: List<Account> DS-->>U: List<Account> U-->>C: List<AccountResponse>
처리 흐름 (활성 계좌 선택)
sequenceDiagram participant C as AccountApiController participant U as SelectAccountUseCase participant DS as AccountDomainService participant R as AccountRepository C->>U: execute(accountNumber) U->>DS: selectAccount(accountNumber) DS->>R: findSelected() R-->>DS: previousAccount or null alt 기존 선택 계좌 존재 DS->>R: save(previousAccount.deselect()) end DS->>R: findBy(accountNumber) DS->>R: save(account.select()) R-->>DS: Account DS-->>U: Account U-->>C: 200 OK
클래스 의존
flowchart LR subgraph Presentation["presentation"] AC[AccountApiController] end subgraph Application["application"] LAU[ListAccountsUseCase] SAU[SelectAccountUseCase] PAU[GetPurchasableAmountUseCase] SEU[GetSellableQuantityUseCase] FEU[GetTradingFeeUseCase] end subgraph Domain["domain"] ADS[AccountDomainService] TQS[TradableQueryService] end AC --> LAU AC --> SAU AC --> PAU AC --> SEU AC --> FEU LAU --> ADS SAU --> ADS PAU --> TQS SEU --> TQS FEU --> TQS
테스트 케이스
PUT /api/v1/accounts/{accountNumber}/select호출 후GET /api/v1/accounts를 조회하면 해당 계좌만selected=true이고 나머지는false이다.- 존재하지 않는 계좌번호로
PUT /api/v1/accounts/{accountNumber}/select를 호출하면 404를 반환한다. GET /api/v1/accounts/purchasable?symbol=005930&quantity=10&price=75000은 Toss API 결과를 그대로 응답하고 MySQL에 저장하지 않는다.- Toss API가 오류를 반환할 때
GET /api/v1/accounts/purchasable은 500을 반환한다. GET /api/v1/accounts/fee?symbol=005930&quantity=10&price=75000&orderType=BUY는 수수료 금액과 수수료율을 포함한 응답을 반환한다.