feat(S15P11A705-397): 나의 활동 기록 집계 조회 API를 추가한다 - #207
Merged
Conversation
GET /v1/me/activity 하나로 totals·months·areas·counts·highlights 다섯 덩어리를 내려준다. 기간은 전체 누적 고정이며 기간 파라미터를 두지 않는다. 새 테이블·인덱스· 마이그레이션은 없다. 날짜 경계를 전부 KST로 고정했다. created_at이 TIMESTAMPTZ라 date_trunc를 그냥 쓰면 서버 타임존을 타고, KST 자정 직후에 남긴 기록이 전날에 붙어 "가장 붐빈 하루"가 하루씩 밀린다. 경계에 걸친 시각을 넣은 테스트로 고정했다. 빈 달 채우기는 SQL이 아니라 서비스가 한다. 구간의 끝인 "이번 달"을 SQL에서 정하면 DB 서버의 시계가 응답을 좌우한다. areas의 동점 정렬에 COLLATE "C"를 명시했다. 한글 이름을 DB 기본 collation으로 정렬하면 운영 DB와 테스트 컨테이너의 locale이 달라 순서가 갈린다(388에서 같은 함정을 만나 그때는 이름 정렬 자체를 피했다). 엔티티를 거치지 않는 SQL이라 @SQLRestriction이 걸리지 않는다 — JPA 리포지토리와 반대로 deleted_at IS NULL을 직접 적었다. 명세: Team-PinLog/docs#54 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
무엇을
GET /v1/me/activity하나를 더합니다. 내 기록을 집계해 활동 기록 화면에 한 번에 내려줍니다.totalsmonthsareascountshighlights기간은 전체 누적 고정이며 기간 파라미터를 두지 않습니다. 새 테이블·인덱스·마이그레이션 없습니다.
명세: Team-PinLog/docs#54 (머지됨, §3.7)
판단한 것
날짜 경계를 전부 KST로 고정했습니다.
created_at이TIMESTAMPTZ라date_trunc를 그냥 쓰면 서버 타임존을 탑니다. KST 5/18 00:30 = UTC 5/17 15:30이라 "가장 붐빈 하루"가 하루씩 밀립니다. 그 경계에 걸친 시각을 넣은 테스트(dayBoundaryFollowsSeoulTime)로 고정했습니다 — UTC로 끊는 구현이면 실패합니다.빈 달 채우기를 SQL이 아니라 서비스에서 합니다. 구간의 끝이 "이번 달"인데
generate_series로 채우면 DB 서버의 시계와 타임존이 응답을 좌우합니다. SQL은 기록이 있는 달만 주고YearMonth.now(KST)가 채웁니다.areas동점 정렬에COLLATE "C"를 명시했습니다. 한글 이름을 DB 기본 collation으로 정렬하면 운영 DB와 테스트 컨테이너의 locale이 달라 순서가 갈립니다 — S15P11A705-388이 같은 함정을 만나 그때는 이름 정렬 자체를 피했습니다(keywordId로 끊음). 여기서는 파생 문자열이라 끊을 키가 이름뿐이라, 피하는 대신 collation을 박아 고정했습니다.@SQLRestriction이 걸리지 않는 경로입니다. 엔티티를 거치지 않는 SQL이라 JPA 리포지토리와 반대로deleted_at IS NULL을 직접 적었습니다. 맥락 메모·컬렉션 카운트는 JPA 파생 쿼리라 그쪽은 적지 않았습니다.집계를 한 쿼리로 묶지 않았습니다. 서로 다른 테이블의 독립 집계라 조인이 카운트를 곱합니다.
MemberSummaryService가 같은 이유로 이미 카운트 넷을 따로 내고 있고, 진입당 1회 호출 경로에서 인덱스를 타는 집계 여섯은 그 복잡도를 살 이유가 되지 않습니다. 대신 대상 집합 정의는MY_RECORDSCTE 한 곳에 뒀습니다.범위 밖
ai스키마 소관이라 쓰지 않습니다(4.3을 씁니다)core.place에 category 컬럼이 없습니다알려진 한계
areas의 시·구는place.address를 공백으로 끊은 두 번째 조각입니다. 행정구역 컬럼이 없어서인데, 도로명·지번이 섞이거나 형식을 벗어난 주소에서는 정확하지 않고 조각을 못 뽑는 주소는 집계에서 제외됩니다. 명세 §3.7에도 같은 내용을 적었습니다.검증
./gradlew clean check --no-daemon통과 — 698 테스트 0 실패 0 에러(checkstyle·jacoco 포함).dev리베이스 후 다시 돌린 결과입니다. 새 테스트 13개는MeActivityApiTests에 있고, 구현 전 red(12 failed)도 확인했습니다.🤖 Generated with Claude Code