Skip to content

Conversation

@son-daehyeon
Copy link
Member

@son-daehyeon son-daehyeon commented Nov 8, 2025

[1팀] 거부기린 백엔드 코드리뷰

✨ 리뷰를 요청드리는 주요 부분

저희 DB 구조에 따르면 세션과 세션 상태(활성화, 일시중지, 재개, 종료), 세션 지표(실제 스코어 시계열) 이렇게 3개의 테이블이 있습니다.

이렇게 상태를 나눈 이유는 시계열 데이터만 가지고 있으면, 일시중지 했을 때 지표 데이터가 서버에 없을텐데, 실제로 세션 자체가 일시중지된 상태인건지 혹은 데이터가 누락된 것 인지 알 수 없기 때문입니다.

다만, 위 과정에서 생긴 몇몇 이슈가 있는데

  1. 전체 세션 시간과 좋은 자세 시간을 계산할 때 오차가 발생합니다.

    private fun calculateTotalSeconds(session: Session): Long {
    var totalSeconds = 0L
    var activeStartTime: LocalDateTime? = null
    session.statusHistory.forEach {
    when (it.status) {
    SessionStatus.STARTED, SessionStatus.RESUMED -> {
    activeStartTime = it.timestamp
    }
    SessionStatus.PAUSED, SessionStatus.STOPPED -> {
    activeStartTime?.let { start ->
    totalSeconds += ChronoUnit.SECONDS.between(start, it.timestamp)
    activeStartTime = null
    }
    }
    }
    }
    return totalSeconds
    }
    private fun calculateGoodSeconds(session: Session): Long {
    var totalSeconds = 0.0
    var previousMetric: SessionMetric? = null
    session.metrics.forEach { metric ->
    previousMetric?.let { prev ->
    if (metric.score <= 1.2) {
    val duration = ChronoUnit.MILLIS.between(prev.timestamp, metric.timestamp)
    val pausedDuration = calculatePausedDuration(session, prev.timestamp, metric.timestamp)
    totalSeconds += (duration - pausedDuration)
    }
    }
    previousMetric = metric
    }
    return (totalSeconds / 1_000).toLong()
    }

    전체 세션 시간은 세션 상태로 구간을 나눠 계산하였고, 좋은 자세 시간은 세션 지표를 통해 계산하였습니다.
    만약 세션 자체는 진행중인 상태인데, 데이터가 누락된 경우에는 좋은 자세 시간이 계수되지 않는다는 문제가 있습니다.

  2. 1번 질문과 조금 이어지는 질문으로, 데이터가 누락된 경우 서버에서 검증을 해야할까 라는 의문이 있습니다.
    만약 그렇다면 정책적으로 어떻게 해야할까요?
    제가 생각했던 과정들입니다.
    검증한다면: 중간에 누락된 데이터로 인해 전체 데이터를 사용할 수 없는 시나리오도 발생할 것 같습니다. 세션이 5분이고, 4분의 데이터만 온다면 서버에서 이를 어떻게 대응해야할까요?
    검증하지 않는다면: 전체 데이터의 신뢰도가 떨어질 것 같습니다. 1번 문제를 비롯하여 데이터가 누락됨으로써 생기는 사용자의 신뢰가 하락한다면 서비스의 특성상 사용자 이탈까지 고려하고 있습니다.

  3. 데이터를 어떤 주기 그리고 간격으로 받아야 할까요?
    프론트에서는 실시간적으로 사용자의 mesh를 계산하여 score를 계산하고 있습니다.
    이 때 모든 데이터를 받자니 데이터의 규모가 너무 커질 것 같고, 1초 단위로 받자니 짧은 순가의 중요한 데이터들의 누락될 것 같습니다.
    현재 정책은 0.1초 주기로 프론트에서 데이터를 쌓은 후 5초 간격(10 * 60 * 5 = 1,200개)의 score 데이터를 받고 있습니다.
    이러한 방향성이 올바른지 검증받고 싶습니다!

💌 요청드리는 리뷰 방향

기능 위주의 리뷰를 받고 싶습니다. 서비스의 특성 상 데이터를 매우 정교하게 다루어여 하는데 이에 대한 노하우가 궁금합니다!

바쁘신 와중에 시간 내어 리뷰해주셔서 감사합니다.
편하게 피드백 부탁드립니다! 🥹

* chore: git 설정 추가

* build: Gradle 빌드 설정

* feat: Spring Boot 애플리케이션 초기 설정

* config: 데이터베이스 및 Redis 설정

* config: 서버 및 Actuator 설정

* config: Swagger API 문서 설정

* config: JPA, Redis, Jackson 설정

* config: Properties 설정 추가

* feat: API 응답 포맷 구현

* feat: 전역 예외 처리 구현

* feat: HTTP 필터 구현

* feat: 커스텀 유효성 검증기 구현

* feat: JPA 기본 엔티티 구현

* config: JWT 및 프론트엔드 연동 설정

* feat: JWT 토큰 발급 및 검증 구현

* feat: Spring Security UserDetails 구현

* feat: JWT 인증 필터 구현

* feat: Spring Security 설정 구현

* feat: 이메일 인증 토큰 발급 구현

* feat: 이메일 발송 기능 구현

* feat: 이메일 템플릿 추가

* feat: 사용자 도메인 엔티티 구현

* feat: 사용자 API DTO 구현

* feat: 사용자 인증 비즈니스 로직 구현

* feat: 사용자 인프라 레이어 구현

* feat: 사용자 인증 컨트롤러 구현

* feat: 데이터베이스 마이그레이션 스크립트 추가
* chore: Dockerfile 추가

* ci: GitHub Actions 배포 파이프라인 구축
@son-daehyeon son-daehyeon reopened this Nov 9, 2025
@son-daehyeon son-daehyeon self-assigned this Nov 9, 2025
@son-daehyeon son-daehyeon force-pushed the main branch 3 times, most recently from 3ce259d to c70602a Compare November 19, 2025 18:58
@son-daehyeon son-daehyeon force-pushed the main branch 2 times, most recently from 1af794d to f3e02e5 Compare November 21, 2025 06:05
@son-daehyeon son-daehyeon force-pushed the main branch 2 times, most recently from b888e42 to 921aea0 Compare November 25, 2025 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants