- member 테이블: extra_wallet_slots, ai_stat_credits 컬럼 추가(ALTER IF NOT EXISTS)
- MemberMapper: 상점 관련 5개 메서드 추가(getExtraWalletSlots/getAiStatCredits/incrementExtraWalletSlots/addAiStatCredits/decrementAiStatCredit)
- ShopService: buyWalletSlot(500P, max 3개), buyAiStatPack(1000P→10회) 구현
- ShopController: GET /api/account/shop/status, POST /api/account/shop/buy
- AccountService.freeWalletLimit: bonus=0 TODO → memberMapper.getExtraWalletSlots 실제 조회
- AccountService.aiComment: FREE 회원 크레딧 차감 로직 추가, 소진 시 402 반환
- AccountController.aiComment: current 파라미터 전달
- WebConfig: /api/account/ai-comment 를 premiumInterceptor 에서 제거(서비스 레이어에서 처리)
- BackupController: @DeleteMapping import 누락 수정
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 기존 대출 수정 시 월 상환금(loanPayment)이 저장되지 않던 문제
(create 는 toWallet 로 반영됐으나 update 는 개별 setter 에서 누락)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 원리금균등 상환표를 은행 조회액과 정확히 맞추기 위한 고정 월 상환금 선택 저장
- wallet.loan_payment 컬럼(ALTER IF NOT EXISTS), 도메인·DTO·매퍼 반영
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- createWallet 에 premium 여부 전달, 무료는 종류별 countByType >= 한도면 400
- 한도 계산을 freeWalletLimit 한 곳에 모음(추후 포인트 상점의 영구 보너스 슬롯 최대 5까지 확장 지점)
- 복원(BackupService)은 본인 데이터 복구라 한도 우회
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
내역 저장 시 현재 월 모든 날에 기록이 있으면 월 1회 랜덤 1~100P 지급.
전월 소급 입력 파밍 방지(현재 월만 인정), 화면 안내 없음(포인트 내역에만).
- AccountEntryMapper.countDistinctEntryDays, PointMapper.countByReason
- PointService.awardMonthComplete(reason=MONTH_COMPLETE_yyyyMM 로 월 1회)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
이번 달 집계(수입·지출·전월대비·예산·분류별)만 Claude Haiku에 보내 2~3개 코멘트 생성.
POST /account/ai-comment(유료 게이트), 거래 원문 미전송. 미설정/실패 시 빈 코멘트→카드 숨김.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- AiEntryParser: /v1/messages(Haiku) 호출로 '어제 스타벅스 5천원'→{type,amount,merchant,date} 추출
- AccountService.parseText: AI 우선 시도, 미설정/실패/미인식 시 기존 규칙기반 파서로 폴백(무중단)
- app.anthropic-api-key/anthropic-model 설정(키 없으면 AI 비활성)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JDBC driver마다 column alias의 대소문자를 다르게 반환할 수 있어
entryId → entry_id, tagName → tag_name 으로 소문자 통일.
NPE 방지를 위한 null 체크도 추가.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
list() 에서 항목마다 findTagNamesByEntryId() 를 개별 호출하던 N+1 을
findTagsByEntryIds() 배치 쿼리 1회로 대체.
항목 수가 많을 때 타임아웃/과부하 방지.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RepaymentRequest.annualFee 추가, repay()에서 연회비>0이면 EXPENSE(분류=연회비) 생성
- 연회비는 카드 대상에만 허용(대출 입력 시 400)
- 원금/이자/연회비 중 하나는 필수로 완화
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 파서: 입금→수입, 출금/이체→지출, 카드 승인→지출, 카드 취소/환불→수입(환불)
은행 거래는 은행(BANK) 지갑에, 카드는 카드(CARD) 지갑에 매칭(matchWalletId 일반화)
- createFromNotification: 파싱된 수입/지출 타입·지갑종류로 생성
- 파서 테스트 갱신(은행 입금/출금 케이스 포함)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CardIssuerMatcher: 공백·접미사(카드/은행/페이/뱅크) 제거 + 별칭 통합(KB↔국민, 농협↔NH, 비씨↔BC, 씨티↔시티)
· KB카드/국민카드/KB국민/국민 어떻게 등록해도 KB국민카드 알림에 자동 매칭
- AccountService.overlaps 가 CardIssuerMatcher 사용
- 단위테스트 4 추가
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 관리자 회원가입 허용 토글(app_setting), 공개 GET /auth/signup-enabled
- 회원가입 봇차단: 허니팟(website) + IP 레이트리밋(Redis, 1h 5회)
- 카드 알림: 현금 오선택 보정(카드 양방향 매칭+단일카드 자동), 광고 푸시 차단(승인신호 없는 광고성 표현 무시)
- @MapperScan 에 admin.mapper 추가
- account.sql: 매 기동 wallet MODIFY 제거(라이브 락 위험) — CREATE 정의에 255 반영됨
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- account_entry pending/notif_key 컬럼 추가(멱등 마이그레이션)
- CardNotificationParser: 카드사·금액·가맹점·승인/취소 파싱
- POST /entries/notification(미확인 지출 생성, 중복방지, 카드 자동매칭)
- POST /entries/{id}/confirm(확정), GET /entries/pending/count
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- invest_trade.quantity BIGINT→DECIMAL(18,6): 평단·원가·평가/실현손익 계산을 BigDecimal로 전환 (금액은 원단위 정수 유지)
- account_entry.installment_months 추가: 카드 지출 2~24개월 할부 기록(일시불 null), 응답에 포함
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 예상 수입: budget_income(연·월별) 로 변경, GET/PUT 에 year·month
- 계좌: wallet.sort_order + reorder 엔드포인트, 생성 시 맨 뒤 배치
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>