배경
이슈 #140에서 미분석 거래를 매일 분류하여 TXN_ANALYSIS에 저장하는 일간 소비 분류 배치를 구현했습니다.
현재 처리 흐름은 다음과 같습니다.
매일 02:00
→ TXN_ANALYSIS가 없는 거래 조회
→ Spring 사전 분류 또는 FastAPI 소비 분류
→ 소비·비소비 분석 결과를 TXN_ANALYSIS에 저장
매월 1일 03:00
→ 전월 소비 데이터 집계
→ 월간 AI 리포트 생성
그러나 현재 월간 소비 집계는 #140에서 확정한 거래 유형별 TXN_ANALYSIS 저장 계약과 일부 일치하지 않습니다.
현재 MonthlyExpenseMapper에는 다음과 같은 기존 기준이 남아 있습니다.
LOAN 거래에 TXN_ANALYSIS가 생성되지 않는다는 전제
LOAN 정상 상환액 중 loan_interest_amount만 소비로 집계
INSTALLMENT 거래의 소비 금액 산정 시 in_amount가 아닌 out_amount 사용 가능성
LOAN을 TXN_ANALYSIS 결과가 아닌 별도 SQL 조건으로 집계
#140 이후에는 ORDINARY, INSTALLMENT, LOAN 거래의 소비 여부와 카테고리, 지출 유형이 TXN_ANALYSIS에 저장되므로 월간 소비 집계도 해당 분석 결과를 기준으로 통일해야 합니다.
관련 이슈
목표
월간 AI 리포트 생성 시 대상 연월의 TXN_ANALYSIS 결과를 기준으로 총소비, 고정지출 및 카테고리별 소비를 일관되게 집계합니다.
예를 들어 2026년 7월 1일에 월간 배치가 실행되면 다음 범위의 데이터를 사용합니다.
targetYearMonth = 2026-06
조회 시작: 2026-06-01 이상
조회 종료: 2026-07-01 미만
2026-06-01 <= tran_date < 2026-07-01
확정 집계 계약
공통 포함 조건
월간 소비 집계에는 다음 조건을 만족하는 거래만 포함합니다.
TXN_ANALYSIS 존재
AND TXN_ANALYSIS.is_consumption = TRUE
TXN_ANALYSIS가 없거나 is_consumption = FALSE인 거래는 월간 소비에서 제외합니다.
계좌가 이후 비활성화되었더라도 과거 소비 내역이 누락되지 않도록 현재 계좌 활성 상태는 조회 조건으로 사용하지 않습니다.
거래 유형별 소비 금액
| 거래 유형 |
월간 소비 집계 금액 |
ORDINARY |
out_amount |
INSTALLMENT |
in_amount |
LOAN 정상 상환 |
out_amount |
금액이 NULL인 경우에는 0으로 처리합니다.
ORDINARY
일반 출금 거래 중 TXN_ANALYSIS.is_consumption = TRUE인 거래의 out_amount를 소비로 집계합니다.
INSTALLMENT
적금·할부성 납입 거래는 거래 구조상 납입액이 in_amount에 저장되므로, TXN_ANALYSIS.is_consumption = TRUE인 거래의 in_amount를 소비로 집계합니다.
LOAN
정상 대출 상환 거래는 #140의 사전 분류 결과에 따라 다음과 같이 저장됩니다.
is_consumption = TRUE
category = FINANCE
expense_type = FIXED
월간 소비 집계에서는 정상 상환 거래의 out_amount 전체를 소비로 반영합니다.
대출 신규·실행·증액 등 비소비 거래는 다음과 같이 저장되므로 집계에서 제외됩니다.
is_consumption = FALSE
category = NULL
expense_type = NULL
따라서 월간 집계 SQL에서 대출 거래 여부를 키워드로 다시 판정하거나 loan_interest_amount만 별도로 합산하지 않습니다.
집계 항목
총소비
대상 연월의 소비 거래 금액을 거래 유형별 기준에 따라 합산합니다.
totalExpense
= ORDINARY 소비 out_amount 합계
+ INSTALLMENT 소비 in_amount 합계
+ LOAN 소비 out_amount 합계
고정지출
다음 조건을 만족하는 거래 금액을 거래 유형별 기준에 따라 합산합니다.
TXN_ANALYSIS.is_consumption = TRUE
AND TXN_ANALYSIS.expense_type = FIXED
카테고리별 소비
TXN_ANALYSIS.category를 기준으로 거래 유형별 소비 금액을 합산합니다.
GROUP BY TXN_ANALYSIS.category
소비 거래인데 카테고리가 NULL 또는 빈 값인 비정상 데이터가 존재하는 경우에는 기존 정책에 따라 ETC로 처리합니다.
다음 정합성을 만족해야 합니다.
월간 AI 리포트 연동 흐름
기존 월간 리포트 오케스트레이션의 연월 계산과 Client 호출 구조를 유지합니다.
MonthlyAiReportScheduler
→ MonthlyAiReportOrchestrationService.runLastMonthBatch()
→ Asia/Seoul 기준 전월 계산
→ MonthlyExpenseQueryClient.findMonthlyExpense(userId, targetYearMonth)
→ account-service 월간 소비 집계
→ 총소비·고정지출·카테고리별 소비 반환
→ AI 리포트 생성
예:
2026년 7월 1일 03:00 실행
→ targetYearMonth = 2026-06
→ 6월 1일 이상, 7월 1일 미만 거래 집계
전월 대비 소비 증감률 계산을 위해 기존과 같이 대상 월의 직전 월 데이터도 조회합니다.
현재 월: 2026-06
비교 월: 2026-05
구현 범위
account-service
MonthlyExpenseMapper의 거래 유형별 금액 계산 수정
TXN_ANALYSIS.is_consumption 기준으로 집계 조건 통일
LOAN 전용 이자 집계 및 키워드 판정 제거
- 총소비 집계 수정
- 고정지출 집계 수정
- 카테고리별 소비 집계 수정
- 반개구간 월 조회 조건 유지
ai-service
- 기존
MonthlyAiReportOrchestrationService의 전월 계산 및 Client 호출 구조 유지
- 대상 월과 비교 월 조회가 올바른지 회귀 테스트
- 수정된 소비 집계 결과가 리포트의 다음 항목에 반영되는지 검증
totalExpense
availableFunds
expenseChangeRate
topCategories
- FastAPI 요청의
categoryExpenses
제외 범위
이번 이슈에서는 다음 작업을 하지 않습니다.
- 일간 소비 분류 규칙 변경
- FastAPI 소비 분류 요청·응답 계약 변경
TXN_ANALYSIS 테이블 구조 변경
- 월간 AI 리포트 Scheduler 실행 시간 변경
- 월간 리포트 생성 대상 사용자 정책 변경
- PDF 레이아웃 변경
- 수동·자동 이메일 발송 로직 변경
- 발송 이력 및 재시도 기능 추가
- BFF API 계약 변경
- 카카오톡 발송 기능 추가
- 무관한
.idea 설정 변경
테스트 항목
월 범위
- 7월 1일 실행 시 6월 1일 이상, 7월 1일 미만 거래 집계
- 5월 31일 거래 제외
- 6월 1일 거래 포함
- 6월 30일 거래 포함
- 7월 1일 거래 제외
- 연말·연초 경계 처리
- 2027년 1월 실행 시 2026년 12월 집계
소비 여부
TXN_ANALYSIS.is_consumption = TRUE 거래 포함
is_consumption = FALSE 거래 제외
TXN_ANALYSIS가 없는 거래 제외
- 비활성 계좌의 과거 소비 거래 포함
거래 유형별 금액
ORDINARY 소비 거래의 out_amount 집계
INSTALLMENT 소비 거래의 in_amount 집계
LOAN 정상 상환 거래의 out_amount 전체 집계
LOAN 신규·실행·증액 비소비 거래 제외
- 거래 유형별 대상 금액이
NULL인 경우 0 처리
집계 정합성
- 총소비와 카테고리별 소비 합계 일치
expense_type = FIXED인 소비 거래만 고정지출에 포함
- 비소비 거래가 총소비·고정지출·카테고리별 소비에 포함되지 않음
category가 비어 있는 소비 거래의 ETC 처리
- 기존 일반 소비 카테고리 집계 회귀 검증
월간 AI 리포트
- 대상 월 소비 조회 결과가
totalExpense에 반영
availableFunds = totalIncome - totalExpense 검증
- 직전 월 소비와 비교한
expenseChangeRate 검증
- 전체 카테고리가 FastAPI 요청에 전달되는지 검증
- 상위 카테고리 및 기타 집계 결과 검증
완료 조건
검증 명령
./gradlew :services:account-service:test
./gradlew :services:ai-service:test
./gradlew :services:account-service:build
./gradlew :services:ai-service:build
필요한 경우 전체 조립 상태도 확인합니다.
./gradlew :common:test \
:services:account-service:test \
:services:ai-service:test \
:services:bff-service:test \
:api:test \
:api:war
참고 사항
현재 월 범위 계산과 오케스트레이션의 월별 소비 조회 호출은 이미 구현되어 있습니다.
이번 작업의 핵심은 오케스트레이션에 새로운 월 조회 구조를 추가하는 것이 아니라, account-service의 월간 소비 집계가 #140 이후의 TXN_ANALYSIS 계약과 일치하도록 수정하는 것입니다.
구현 완료 후 다음 문서도 함께 최신화합니다.
배경
이슈 #140에서 미분석 거래를 매일 분류하여
TXN_ANALYSIS에 저장하는 일간 소비 분류 배치를 구현했습니다.현재 처리 흐름은 다음과 같습니다.
그러나 현재 월간 소비 집계는 #140에서 확정한 거래 유형별
TXN_ANALYSIS저장 계약과 일부 일치하지 않습니다.현재
MonthlyExpenseMapper에는 다음과 같은 기존 기준이 남아 있습니다.LOAN거래에TXN_ANALYSIS가 생성되지 않는다는 전제LOAN정상 상환액 중loan_interest_amount만 소비로 집계INSTALLMENT거래의 소비 금액 산정 시in_amount가 아닌out_amount사용 가능성LOAN을TXN_ANALYSIS결과가 아닌 별도 SQL 조건으로 집계#140 이후에는
ORDINARY,INSTALLMENT,LOAN거래의 소비 여부와 카테고리, 지출 유형이TXN_ANALYSIS에 저장되므로 월간 소비 집계도 해당 분석 결과를 기준으로 통일해야 합니다.관련 이슈
목표
월간 AI 리포트 생성 시 대상 연월의
TXN_ANALYSIS결과를 기준으로 총소비, 고정지출 및 카테고리별 소비를 일관되게 집계합니다.예를 들어 2026년 7월 1일에 월간 배치가 실행되면 다음 범위의 데이터를 사용합니다.
확정 집계 계약
공통 포함 조건
월간 소비 집계에는 다음 조건을 만족하는 거래만 포함합니다.
TXN_ANALYSIS가 없거나is_consumption = FALSE인 거래는 월간 소비에서 제외합니다.계좌가 이후 비활성화되었더라도 과거 소비 내역이 누락되지 않도록 현재 계좌 활성 상태는 조회 조건으로 사용하지 않습니다.
거래 유형별 소비 금액
ORDINARYout_amountINSTALLMENTin_amountLOAN정상 상환out_amount금액이
NULL인 경우에는0으로 처리합니다.ORDINARY일반 출금 거래 중
TXN_ANALYSIS.is_consumption = TRUE인 거래의out_amount를 소비로 집계합니다.INSTALLMENT적금·할부성 납입 거래는 거래 구조상 납입액이
in_amount에 저장되므로,TXN_ANALYSIS.is_consumption = TRUE인 거래의in_amount를 소비로 집계합니다.LOAN정상 대출 상환 거래는 #140의 사전 분류 결과에 따라 다음과 같이 저장됩니다.
월간 소비 집계에서는 정상 상환 거래의
out_amount전체를 소비로 반영합니다.대출 신규·실행·증액 등 비소비 거래는 다음과 같이 저장되므로 집계에서 제외됩니다.
따라서 월간 집계 SQL에서 대출 거래 여부를 키워드로 다시 판정하거나
loan_interest_amount만 별도로 합산하지 않습니다.집계 항목
총소비
대상 연월의 소비 거래 금액을 거래 유형별 기준에 따라 합산합니다.
고정지출
다음 조건을 만족하는 거래 금액을 거래 유형별 기준에 따라 합산합니다.
카테고리별 소비
TXN_ANALYSIS.category를 기준으로 거래 유형별 소비 금액을 합산합니다.소비 거래인데 카테고리가
NULL또는 빈 값인 비정상 데이터가 존재하는 경우에는 기존 정책에 따라ETC로 처리합니다.다음 정합성을 만족해야 합니다.
월간 AI 리포트 연동 흐름
기존 월간 리포트 오케스트레이션의 연월 계산과 Client 호출 구조를 유지합니다.
예:
전월 대비 소비 증감률 계산을 위해 기존과 같이 대상 월의 직전 월 데이터도 조회합니다.
구현 범위
account-service
MonthlyExpenseMapper의 거래 유형별 금액 계산 수정TXN_ANALYSIS.is_consumption기준으로 집계 조건 통일LOAN전용 이자 집계 및 키워드 판정 제거ai-service
MonthlyAiReportOrchestrationService의 전월 계산 및 Client 호출 구조 유지totalExpenseavailableFundsexpenseChangeRatetopCategoriescategoryExpenses제외 범위
이번 이슈에서는 다음 작업을 하지 않습니다.
TXN_ANALYSIS테이블 구조 변경.idea설정 변경테스트 항목
월 범위
소비 여부
TXN_ANALYSIS.is_consumption = TRUE거래 포함is_consumption = FALSE거래 제외TXN_ANALYSIS가 없는 거래 제외거래 유형별 금액
ORDINARY소비 거래의out_amount집계INSTALLMENT소비 거래의in_amount집계LOAN정상 상환 거래의out_amount전체 집계LOAN신규·실행·증액 비소비 거래 제외NULL인 경우0처리집계 정합성
expense_type = FIXED인 소비 거래만 고정지출에 포함category가 비어 있는 소비 거래의ETC처리월간 AI 리포트
totalExpense에 반영availableFunds = totalIncome - totalExpense검증expenseChangeRate검증완료 조건
TXN_ANALYSIS저장 계약과 일치함ORDINARY,INSTALLMENT,LOAN의 소비 금액이 확정 계약대로 집계됨TXN_ANALYSIS.expense_type기준으로 계산됨.idea파일이 변경되지 않음검증 명령
필요한 경우 전체 조립 상태도 확인합니다.
참고 사항
현재 월 범위 계산과 오케스트레이션의 월별 소비 조회 호출은 이미 구현되어 있습니다.
이번 작업의 핵심은 오케스트레이션에 새로운 월 조회 구조를 추가하는 것이 아니라, account-service의 월간 소비 집계가 #140 이후의
TXN_ANALYSIS계약과 일치하도록 수정하는 것입니다.구현 완료 후 다음 문서도 함께 최신화합니다.