Conversation
Walkthrough건강 상태 입력 화면에서 복부 관련 선택 상태를 네 가지(복부/허리/엉덩이/골반)로 세분화하고, 기록 동기화·표시·선택 로직을 이에 맞게 전면 수정했습니다. 입력 모드 여부에 따라 기록 반영을 제어하며, 한국어 라벨을 복부(복부/허리/골반/엉덩이)로 통일했습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as 사용자
participant Screen as HealthStatusInputScreen
participant Records as PainRecordsStore
User->>Screen: 화면 진입
Screen->>Records: _loadPainRecords()
alt 입력 모드 아님
Records-->>Screen: 기록 목록
Screen->>Screen: _updateBodyPartsFromRecords()\n- 네 불리언 리셋/적용\n- 자식 위젯 읽기 전용 설정
Screen->>Screen: _updateBodyPartsDisplay(isFront)
else 입력 모드
Records-->>Screen: 기록 무시(상태 유지)
end
User->>Screen: 신체부위 선택(onBodyPartsSelected)
Screen->>Screen: BodyParts → 네 불리언 디코드
Screen->>Screen: _updateBodyPartsDisplay(isFront)
Screen->>Screen: _getSelectedPainAreas() 수집
note right of Screen: hasSelectedParts 확인
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed everything up to 1aafd7a in 1 minute and 20 seconds. Click for details.
- Reviewed
240lines of code in1files - Skipped
0files when reviewing. - Skipped posting
6draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. frontend/ongi/lib/screens/health/health_status_input_screen.dart:37
- Draft comment:
New boolean state variables for abdomen, waist, hip, and pelvis have been added. Consider adding a brief inline comment explaining their distinct roles in relation to the BodyParts model. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
2. frontend/ongi/lib/screens/health/health_status_input_screen.dart:306
- Draft comment:
In _updateBodyPartsFromRecords, pain area cases now update dedicated booleans (e.g. _abdomenSelected) instead of directly modifying the BodyParts via copyWith. Ensure this design choice is consistent across the state management. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
3. frontend/ongi/lib/screens/health/health_status_input_screen.dart:369
- Draft comment:
The mapping for pelvis and hip in _updateBodyPartsDisplay is reversed between front and back views. Please ensure that this reversed mapping is intentional and add a clarifying comment if needed. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
4. frontend/ongi/lib/screens/health/health_status_input_screen.dart:828
- Draft comment:
In onBodyPartsSelected, lower body selection is mapped to _abdomenSelected (front view) and to _waistSelected (back view) while pelvis and hip are updated according to the view. Verify that these mappings conform to the intended UI behavior. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
5. frontend/ongi/lib/screens/health/health_status_input_screen.dart:438
- Draft comment:
Changed the stretching link label from '배' to '복부' for consistency with updated terminology. This looks correct. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
6. frontend/ongi/lib/screens/health/health_status_input_screen.dart:357
- Draft comment:
Multiple sequential calls to _bodyParts.copyWith in _updateBodyPartsDisplay could be consolidated into a single call to improve readability and possibly performance. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
Workflow ID: wflow_311mLjiDTbqlZhSK
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/ongi/lib/screens/health/health_status_input_screen.dart (2)
815-861: BodyParts.toString 파싱 의존 제거
toString()문자열 검색은 라이브러리 변경에 취약합니다.BodyParts의 공개 필드를 직접 참조하는 방식으로 교체하세요.- final partsString = parts.toString(); - // 가슴/등 선택 상태 업데이트 (앞/뒤 구분) - final upperBodySelected = partsString.contains('upperBody: true'); + // 가슴/등 선택 상태 업데이트 (앞/뒤 구분) + final upperBodySelected = parts.upperBody; - // 복부 부위 선택 상태 업데이트 - final lowerBodySelected = partsString.contains('lowerBody: true'); - final abdomenSelected = partsString.contains('abdomen: true'); - final vestibularSelected = partsString.contains('vestibular: true'); + // 복부 부위 선택 상태 업데이트 + final lowerBodySelected = parts.lowerBody; + final abdomenSelected = parts.abdomen; + final vestibularSelected = parts.vestibular;필드 직접 접근이 불가능한 타입이라면, 안전한 파서/헬퍼를 도입해 문자열 의존을 캡슐화하세요.
1475-1481: Color.withValues 사용은 빌드 실패 위험Flutter 안정 채널에서는
withOpacity가 표준입니다.withValues가 미지원이면 컴파일 에러가 납니다. 호환성 위해 교체를 권장합니다.- color: Colors.black.withValues( - alpha: 0.1, - ), + color: Colors.black.withOpacity(0.1),동일 패턴을 두 블록 모두에 적용해 주세요.
Also applies to: 1517-1520
🧹 Nitpick comments (3)
frontend/ongi/lib/screens/health/health_status_input_screen.dart (3)
253-268: 디버그 로그 가드 처리 필요
kDebugMode가드를 권장합니다.예시 패치(동일 패턴을 본 블록 전반에 적용):
+import 'package:flutter/foundation.dart'; ... - print('디버깅 - 원본 painArea: $painArea (타입: ${painArea.runtimeType})'); + if (kDebugMode) debugPrint('디버그: 원본 painArea: $painArea (${painArea.runtimeType})'); - print('디버깅 - 처리할 areas: $areas'); + if (kDebugMode) debugPrint('디버그: 처리할 areas: $areas'); - print('디버깅 - 처리 중인 부위: $areaUpper'); + if (kDebugMode) debugPrint('디버그: 처리 중인 부위: $areaUpper');
354-381: copyWith 연속 호출을 단일 호출로 합쳐 재빌드 비용 축소동일 setState 내에서
_bodyParts를 4회 재할당합니다. 한 번에 묶어 객체 생성/디프를 줄이는 편이 좋습니다.void _updateBodyPartsDisplay() { setState(() { - if (isFrontView) { - _bodyParts = _bodyParts.copyWith(upperBody: _chestSelected); - _bodyParts = _bodyParts.copyWith(lowerBody: _abdomenSelected); - } else { - _bodyParts = _bodyParts.copyWith(upperBody: _backSelected); - _bodyParts = _bodyParts.copyWith(lowerBody: _waistSelected); - } - - if (isFrontView) { - _bodyParts = _bodyParts.copyWith(abdomen: _pelvisSelected); - _bodyParts = _bodyParts.copyWith(vestibular: _hipSelected); - } else { - _bodyParts = _bodyParts.copyWith(abdomen: _hipSelected); - _bodyParts = _bodyParts.copyWith(vestibular: _pelvisSelected); - } + _bodyParts = _bodyParts.copyWith( + upperBody: isFrontView ? _chestSelected : _backSelected, + lowerBody: isFrontView ? _abdomenSelected : _waistSelected, + abdomen: isFrontView ? _pelvisSelected : _hipSelected, + vestibular:isFrontView ? _hipSelected : _pelvisSelected, + ); }); }
623-629: 스낵바 ‘복사’ 액션 동작 추가 제안현재 TODO 상태입니다. 실제 복사 동작과 피드백을 추가하세요.
+import 'package:flutter/services.dart'; ... - onPressed: () { - // URL을 클립보드에 복사하는 기능 추가 가능 - }, + onPressed: () async { + await Clipboard.setData(ClipboardData(text: url)); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('링크가 클립보드에 복사되었습니다.'), + duration: Duration(seconds: 2), + ), + ); + } + },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
frontend/ongi/lib/screens/health/health_status_input_screen.dart(12 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/ongi/lib/screens/health/health_status_input_screen.dart (1)
backend/ongi/src/main/java/ongi/health/entity/PainRecord.java (1)
PainArea(31-64)
🔇 Additional comments (5)
frontend/ongi/lib/screens/health/health_status_input_screen.dart (5)
37-41: 복부/허리/엉덩이/골반 상태 분리, 방향성 좋습니다선택 오동작을 분해해 해결한 접근이 타당합니다. 이후 리셋/표시/저장 경로에 일관되게 반영된 점도 확인했습니다.
217-250: 조회 모드 진입 시 상태 리셋 로직 명확기록 없음/있음에 따라 입력 모드·스트레칭 노출·내부 선택 상태를 일관되게 초기화하는 흐름이 깔끔합니다.
306-317: 기록 → 내부 상태 매핑 적절ABDOMEN/WAIST/PELVIS/HIP를 전용 bool로 분리해 반영하는 로직이 명확합니다.
979-986: 용어 통일(배 → 복부) 확인한글 라벨을 ‘복부’로 통일한 매핑이 백엔드 enum(ABDOMEN)과도 일치합니다.
194-197: 백엔드record['date']필드 포맷/타임존 일관성 확인 필요
클라이언트는selectedDate를DateFormat('yyyy-MM-dd')(로컬 타임존)로 포맷해record['date']문자열과 비교하고 있습니다. 스크립트 점검 결과 해당 포맷이 여러 곳에서 일관되게 사용되나, 백엔드가 UTC 기준으로 날짜를 저장·반환한다면 off-by-one 이슈가 발생할 수 있습니다.
API 스펙에서date필드가 로컬/UTC 중 어느 기준인지 확인하고, 필요 시 DateTime으로 파싱 후 로컬 타임존으로 정규화하여 비교 로직을 재검토하세요.
| // 입력 모드가 아닐 때만 기록에서 신체 부위 업데이트 | ||
| if (!_isInputMode) { | ||
| _updateBodyPartsFromRecords(); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
날짜 변경 시 입력 모드 유지로 인해 기록 UI 미갱신 가능성
입력 모드(true) 상태에서 날짜를 바꾸면 _loadPainRecords가 _updateBodyPartsFromRecords()를 건너뜁니다. 해당 날짜에 기록이 있어도 화면에 반영되지 않아 혼란을 줄 수 있습니다. 날짜 변경 시 조회 모드로 내려 UI를 기록 기반으로 재구성하는 것이 안전합니다.
다음과 같이 날짜 변경 시 입력 모드를 해제하는 편이 명확합니다.
void _onDateChanged(DateTime newDate) {
- setState(() {
- selectedDate = newDate;
- });
+ setState(() {
+ selectedDate = newDate;
+ _isInputMode = false; // 날짜 변경 → 우선 조회 모드로 전환
+ });
_loadPainRecords();
}📝 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.
| // 입력 모드가 아닐 때만 기록에서 신체 부위 업데이트 | |
| if (!_isInputMode) { | |
| _updateBodyPartsFromRecords(); | |
| } | |
| void _onDateChanged(DateTime newDate) { | |
| setState(() { | |
| selectedDate = newDate; | |
| _isInputMode = false; // 날짜 변경 → 우선 조회 모드로 전환 | |
| }); | |
| _loadPainRecords(); | |
| } |
🤖 Prompt for AI Agents
In frontend/ongi/lib/screens/health/health_status_input_screen.dart around lines
200 to 203, changing the date while _isInputMode is true skips calling
_updateBodyPartsFromRecords(), leaving the UI out of sync; fix by forcing exit
from input mode when the date changes (set _isInputMode = false) before loading
records so _loadPainRecords will call _updateBodyPartsFromRecords(); make this
change inside the date-change handler and wrap the state change in setState (or
the equivalent state update) so the UI is rebuilt from records for the newly
selected date.
| return _bodyParts.toString().contains('true') || | ||
| _chestSelected || | ||
| _backSelected; | ||
| _backSelected || | ||
| _abdomenSelected || | ||
| _waistSelected || | ||
| _hipSelected || | ||
| _pelvisSelected; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
hasSelectedParts 계산 간소화
중복 로직과 toString() 의존을 피하기 위해 최종 산출 함수를 재사용하세요.
- bool get hasSelectedParts {
- return _bodyParts.toString().contains('true') ||
- _chestSelected ||
- _backSelected ||
- _abdomenSelected ||
- _waistSelected ||
- _hipSelected ||
- _pelvisSelected;
- }
+ bool get hasSelectedParts => _getSelectedPainAreas().isNotEmpty;🤖 Prompt for AI Agents
In frontend/ongi/lib/screens/health/health_status_input_screen.dart around lines
868-875, the current hasSelectedParts check relies on
_bodyParts.toString().contains('true') and duplicates logic; replace this with a
single reusable predicate (or call the existing final-output function) that
returns whether any body part is selected by evaluating
_bodyParts.values.any((v) => v) || _chestSelected || _backSelected ||
_abdomenSelected || _waistSelected || _hipSelected || _pelvisSelected, and use
that helper everywhere instead of the toString() check to eliminate duplication
and brittleness.
* feat: 통증 기록 부위 구현 * fix: 통증 부위 선택 오류 수정 --------- Co-authored-by: itaegyeong <taekoong@pusan.ac.kr>
Important
Fixes body part selection for abdomen, waist, hip, and pelvis in
HealthStatusInputScreenand updates related display logic._HealthStatusInputScreenState._updateBodyPartsFromRecords()to reset abdomen-related states._updateBodyPartsDisplay()to handle abdomen, waist, hip, and pelvis based on view.onBodyPartsSelected()to update selection states for abdomen-related parts.getStretchingLinks()._buildTitleText()and other places.This description was created by
for 1aafd7a. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit