9 Commits

Author SHA1 Message Date
c964572a9c Replace point ledger with wallet engine and rework reward earning
- 지갑 문서(users/{uid}/wallet/current)와 문서 ID=멱등키 원장(pointLedger/{txId})으로 포인트 엔진 교체 — 기존 balanceAfter 최신 row 조회 방식 폐기
- 모든 포인트 변경은 pointService.applyPointChangesTx 단일 경로로 처리, available+reserved == totalEarned-totalSpent 불변식을 매 커밋 검증
- 출석 리워드 개편: 일일 20P, 연속 5일 +50P(사이클당 1회), 10일 단위 +100P — attendance/state 문서에 스트릭 상태 저장, 주간·월간 보너스 폐기
- 승부예측 일일 리워드 정산 신설: 전체 참여 50P + 성공 100P + 퍼펙트 50P, judgeDay 이후 voteHistory.rewardSettledAt 플래그와 원장 멱등키로 배치 재실행에도 중복 지급 차단
- 관리자 포인트 지급·회수(adminPointService)와 수동 재정산 디버그 라우트(/debug/settle-reward) 추가
- 소비처 없던 티켓 시스템(dailyAllKill·weeklyMaster)과 위클리마스터 판정 흐름 전체 제거 — StatsResponse.tickets 필드 삭제로 클라 응답 스키마 변경
2026-07-16 14:25:42 +09:00
de35ef21ce Align final score order with team name order in tool output
- 종료 스코어를 "원정:홈" 위치 표기에서 팀명 순서(우리팀:상대)로 정렬 — 순서 불일치로 모델이 홈 승리(8:3)를 "3:8 패배"로 오독하고 패배 서사까지 지어내던 문제 수정
- formatLineupResult 종료 스코어에 승패 명기 추가(기존엔 승패 표기 없음)
- 원정 관점 회귀 테스트 추가. 프로브 실측: 동일 질문 5회 중 오독 2회 → 0회
2026-07-03 16:42:33 +09:00
148e26d1bb Add head-to-head record lookup to rank snapshot tool
- get_team_rank_snapshot에 vs 인자 추가 — 순위표의 팀간 승패표(vsRecords)에서 두 팀의 올 시즌 맞대결 승패무를 반환
- formatH2hResult 순수 함수 분리 및 단위 테스트 추가
- 오늘 상대가 아닌 임의 팀과의 상대 전적 질문을 도구 1회 호출로 처리(일정→전적 체이닝도 가능). 기존에는 vsRecords가 도구 계층에서 버려져 모델이 접근할 경로가 없었음
2026-07-03 16:41:44 +09:00
4d1a46e587 Implement soft-delete for user accounts and add account purge job
- 회원 탈퇴 시 즉시 삭제 대신 `active: false` 및 `deactivatedAt`을 기록하여 30일간 데이터를 유예하는 소프트 삭제 방식을 도입했습니다.
- 경기 취소 시 투표를 삭제하는 대신 `cancelled: true`로 마킹하여 참여 흔적을 보존하고, 통계 집계에서만 제외하도록 로직을 변경했습니다.
- 유예 기간이 지난 비활성 계정을 영구적으로 파기하는 `accountPurge` 스케줄러를 추가했습니다.
2026-07-02 11:29:40 +09:00
6d78ef5c7a Consolidate KST date helpers and fix tuesdayOf timezone leak
- dayOfWeekKst → dayOfWeek, addDaysKst → addDays: 결과가 타임존과 무관한 헬퍼라 이름에서 KST 제거(요일·달력 산술은 TZ 불변)
- tuesdayOf: 로컬 Date 생성(new Date(y,m-1,d-offset))을 제거하고 dayOfWeek·addDays 기반으로 재작성 — 런타임 TZ에 따라 하루 어긋나던 잠재 버그 수정(UTC+14에서 검증)
- 호출처(attendance·dailyArchive·chat·judgment·stats 및 테스트) 일괄 갱신
2026-06-27 00:20:35 +09:00
5f519afcbf Add human-readable labels to chat tool calls for UI rendering.
- `ChatToolCallInfo` 타입에 `label` 필드를 추가하여 클라이언트가 도구 호출을 직관적인 칩 형태로 표시할 수 있도록 개선했습니다.
- `chatToolService`에 도구별 라벨 매핑 테이블(`TOOL_LABELS`)과 이를 적용하는 `withToolLabels` 함수를 구현하여, API 응답 시점에만 라벨이 동적으로 결합되도록 설계했습니다.
- 기존 저장소(Firestore) 로직에는 영향을 주지 않으면서, 메시지 조회 및 전송 결과 반환 시점에 라벨을 주입하여 표현 계층의 유연성을 확보했습니다.
- 테스트 코드를 수정하여 도구 호출 응답 및 이력 조회 시 라벨이 정확하게 포함되는지 검증했습니다.
2026-06-26 09:22:08 +09:00
1ab744e660 Add AI chat tools for team standings, attendance, and predictions.
순위(get_team_rank_snapshot)·출석(get_my_attendance_this_month)·예측 복기
(get_prediction_breakdown_date) 도구를 추가하고, 상대 날짜(dayOffset)와
리그 전체 로스터 조회를 지원한다.

모델이 호출한 도구(이름·인자)를 전송 응답과 메시지 이력에 함께 실어
클라이언트가 나중에 활용할 수 있게 한다.
2026-06-16 16:51:53 +09:00
360c0d356e Add AI chat tools to fetch KBO game standouts and refine model providers.
- 특정 경기에서 활약한 선수(WPA 상위)를 조회하는 `get_game_standouts` 도구를 추가하고, 시스템 프롬프트에 과거 기록 검증 로직을 강화했습니다.
- Gemini 3.0 이상 모델의 Thinking 설정을 지원하도록 Provider 계층을 개선하여 모델 세대별 최적의 추론 환경을 구성했습니다.
- 도구 우선 사용 원칙을 구체화하여 AI가 경기 데이터의 사실 관계를 스스로 확인하고 답변하도록 환각 방지 로직을 보완했습니다.
2026-06-16 08:36:16 +09:00
b126c05c82 Add AI chat tools to fetch KBO game lineups and player roster records.
- KBO 경기 라인업(타순) 및 선수 기록을 실시간으로 조회하는 AI 도구(Function Calling) 체계를 구현했습니다.
- Anthropic 및 Google Gemini 모델의 Tool-loop를 지원하도록 Provider 계층을 개선하여, 시점 의존적인 데이터를 모델이 필요할 때만 스스로 조회하도록 최적화했습니다.
- 시스템 프롬프트에 '도구 우선 사용' 원칙을 추가하여 환각(Hallucination) 현상을 방지하고, 미발표 정보나 경기 미진행 시 정확한 사실 확인 로직을 강화했습니다.
2026-06-15 15:44:38 +09:00