Skip to content

[Feat] #20 트래킹 세션 종료 시 하이킹 기록 생성#54

Merged
JangInho merged 5 commits into
feat/#19-tracking-gpsfrom
feat/#20-tracking-record-finalize
May 21, 2026
Merged

[Feat] #20 트래킹 세션 종료 시 하이킹 기록 생성#54
JangInho merged 5 commits into
feat/#19-tracking-gpsfrom
feat/#20-tracking-record-finalize

Conversation

@JangInho

@JangInho JangInho commented May 19, 2026

Copy link
Copy Markdown
Contributor

🧾 요약

  • 트래킹 세션 종료 시 수집된 GPS 통계 데이터를 기반으로 HikingRecord를 자동 생성하도록 구현했습니다.

🔗 이슈

✨ 변경 내용

  • 트래킹 세션 종료 시 HikingRecord 자동 생성 로직 추가
  • HikingRecord 엔티티 확장
  • 세션 통계 계산 보강 및 GPS 포인트 처리 흐름 정리

기타사항

  • DB 마이그레이션 스크립트(002_hiking_record_extension.sql) 추가한건 머지할때 빼겠습니다 !
  • complete() 시 Redis Stream race 로 마지막 GPS 점 누락 / 빈 Hash 빈 기록 생성 가능
  • HikingRecord max_altitude · calories NOT NULL + 0 fallback → nullable 화 필요

✅ 확인

  • 빌드 OK
  • 테스트 OK

Summary by CodeRabbit

  • New Features
    • Tracking sessions now automatically generate and save hiking records upon completion, eliminating manual entry
    • Expanded tracking metrics including distance, elevation gain/loss, paused time, session timestamps, and maximum altitude are now captured and stored for each activity

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b120ef86-32a9-4f91-aff3-0238a1bfa395

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main feature: automatic creation of hiking records when a tracking session ends, which aligns with the primary objective of the PR.
Linked Issues check ✅ Passed The PR implements key requirements from issue #20: distance calculation via tracking stats [TrackingSessionStatsService adds distance tracking], elevation change [ascent/descent computed], elapsed time [duration calculated from startedAt/endedAt minus paused seconds], and DB persistence [HikingRecord created and saved at session termination]. Polyline storage is not addressed but is marked incomplete in the issue.
Out of Scope Changes check ✅ Passed All changes are within scope: HikingRecord entity extended to track GPS-derived metrics, TrackingSessionResponse updated to expose hiking record linkage, TrackingSessionService orchestrates record creation, TrackingSessionStatsService computes required metrics, and the DB migration supports the new schema. No unrelated changes detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#20-tracking-record-finalize

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/resources/db/migration/002_hiking_record_extension.sql`:
- Around line 45-53: Add a DB-level uniqueness guard so each tracking_session_id
maps to at most one hiking_records row: in the migration that alters table
hiking_records (currently adding fk_hiking_records_tracking_session and creating
idx_hiking_records_tracking_session), also create a UNIQUE constraint or UNIQUE
INDEX on hiking_records(tracking_session_id) (e.g. name it
uq_hiking_records_tracking_session or
unique_idx_hiking_records_tracking_session) using the same IF NOT EXISTS pattern
so retries/concurrent runs are safe; ensure the UNIQUE creation follows/avoids
conflict with the existing fk_hiking_records_tracking_session and
idx_hiking_records_tracking_session.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2ce8896c-99e6-4ec1-86de-f1a680da581b

📥 Commits

Reviewing files that changed from the base of the PR and between c0509d0 and 1b1d692.

📒 Files selected for processing (5)
  • src/main/java/com/semosan/api/domain/hiking/entity/HikingRecord.java
  • src/main/java/com/semosan/api/domain/tracking/dto/response/TrackingSessionResponse.java
  • src/main/java/com/semosan/api/domain/tracking/service/TrackingSessionService.java
  • src/main/java/com/semosan/api/domain/tracking/service/TrackingSessionStatsService.java
  • src/main/resources/db/migration/002_hiking_record_extension.sql

Comment on lines +45 to +53
ALTER TABLE hiking_records
ADD CONSTRAINT fk_hiking_records_tracking_session
FOREIGN KEY (tracking_session_id) REFERENCES tracking_sessions(id);
END IF;
END$$;

-- 6) 조회 인덱스 (HikingRecord 로 트래킹 세션 역방향 찾을 일은 거의 없으나, 디버그/분석용)
CREATE INDEX IF NOT EXISTS idx_hiking_records_tracking_session
ON hiking_records (tracking_session_id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enforce one-record-per-session at DB level.

tracking_session_id currently has FK + index only, so duplicate hiking_records per session are still possible under retries/concurrency. Add a unique constraint (or unique index) on tracking_session_id to protect data integrity.

Suggested migration adjustment
 DO $$
 BEGIN
     IF NOT EXISTS (
         SELECT 1
         FROM information_schema.table_constraints
         WHERE table_name = 'hiking_records'
           AND constraint_name = 'fk_hiking_records_tracking_session'
     ) THEN
         ALTER TABLE hiking_records
             ADD CONSTRAINT fk_hiking_records_tracking_session
             FOREIGN KEY (tracking_session_id) REFERENCES tracking_sessions(id);
     END IF;
 END$$;

-CREATE INDEX IF NOT EXISTS idx_hiking_records_tracking_session
-    ON hiking_records (tracking_session_id);
+CREATE UNIQUE INDEX IF NOT EXISTS uq_hiking_records_tracking_session
+    ON hiking_records (tracking_session_id)
+    WHERE tracking_session_id IS NOT NULL;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ALTER TABLE hiking_records
ADD CONSTRAINT fk_hiking_records_tracking_session
FOREIGN KEY (tracking_session_id) REFERENCES tracking_sessions(id);
END IF;
END$$;
-- 6) 조회 인덱스 (HikingRecord 로 트래킹 세션 역방향 찾을 일은 거의 없으나, 디버그/분석용)
CREATE INDEX IF NOT EXISTS idx_hiking_records_tracking_session
ON hiking_records (tracking_session_id);
ALTER TABLE hiking_records
ADD CONSTRAINT fk_hiking_records_tracking_session
FOREIGN KEY (tracking_session_id) REFERENCES tracking_sessions(id);
END IF;
END$$;
-- 6) 조회 인덱스 (HikingRecord 로 트래킹 세션 역방향 찾을 일은 거의 없으나, 디버그/분석용)
CREATE UNIQUE INDEX IF NOT EXISTS uq_hiking_records_tracking_session
ON hiking_records (tracking_session_id)
WHERE tracking_session_id IS NOT NULL;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/db/migration/002_hiking_record_extension.sql` around lines
45 - 53, Add a DB-level uniqueness guard so each tracking_session_id maps to at
most one hiking_records row: in the migration that alters table hiking_records
(currently adding fk_hiking_records_tracking_session and creating
idx_hiking_records_tracking_session), also create a UNIQUE constraint or UNIQUE
INDEX on hiking_records(tracking_session_id) (e.g. name it
uq_hiking_records_tracking_session or
unique_idx_hiking_records_tracking_session) using the same IF NOT EXISTS pattern
so retries/concurrent runs are safe; ensure the UNIQUE creation follows/avoids
conflict with the existing fk_hiking_records_tracking_session and
idx_hiking_records_tracking_session.

@JangInho
JangInho force-pushed the feat/#20-tracking-record-finalize branch from 1b1d692 to 7a65656 Compare May 19, 2026 13:15

@pooreumjung pooreumjung left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다,,!


-- 6) 조회 인덱스 (HikingRecord 로 트래킹 세션 역방향 찾을 일은 거의 없으나, 디버그/분석용)
CREATE INDEX IF NOT EXISTS idx_hiking_records_tracking_session
ON hiking_records (tracking_session_id);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기 unique 제약 필요할 듯!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가완료

/** 등산 중 도달한 최고 고도 (m) */
/** 등산 중 도달한 최고 고도 (m). */
@Column(name = "max_altitude", nullable = false)
private Double altitude;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 columne name이랑 entity 필드 명이랑 불일치

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정완료!

return TrackingSessionResponse.from(session);

TrackingSessionStatsService.Stats stats = statsService.getStats(sessionId);
HikingRecord record = HikingRecord.fromTrackingSession(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stats의 pointCount가 0이면 통계 데이터 없음으로 간주하고 경고 처리나 예외 처리하면 좋을 듯!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다 일단 예외는 안넣고 로그만 넣었습니다

@@ -0,0 +1,53 @@
-- =====================================================================

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파일명도 바꿔야 할듯

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정 완료

@howooyeon howooyeon added the enhancement New feature or request label May 20, 2026
JangInho and others added 3 commits May 21, 2026 20:08
…record-finalize

# Conflicts:
#	src/main/java/com/semosan/api/domain/tracking/service/TrackingSessionService.java
- 002_hiking_record_extension.sql 삭제, V9__extend_hiking_record.sql 신규 작성
  - 기존 002 내용 + tracking_session_id UNIQUE 제약 (세션당 기록 1건 강제)
- HikingRecord.altitude 필드명을 컬럼명과 정합되게 maxAltitude 로 변경
  (DTO 응답 키 호환 위해 HikingRecordSummaryResponse 필드명은 유지)
- TrackingSessionService.complete: stats.pointCount == 0 일 때 경고 로그 추가
@JangInho
JangInho merged commit b61348d into feat/#19-tracking-gps May 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants