---
title: "⚖️ 의사결정 — 데이터 관리 설계결정 (D1~D6: 내보내기≠가져오기·근력 그룹핑·중복 3구분·파서 유연화)"
category: "decision"
parent: "Claude Code 작업보고"
updated: "2026-07-04"
priority: "High"
purpose: "엑셀 내보내기/가져오기 기능의 핵심 설계 결정(D1~D6)과 사장님이 뒤집은 항목의 근거 기록. '내보내기=백업 최대보존 / 가져오기=간소 양식' 컬럼 분리, 중복 3구분, 그리고 2026-07-03 가져오기 파서 유연화(A 헤더별칭 + C CSV, 자유양식 B 제외)의 결정·근거·Codex가 잡은 export 왕복 오염 이슈."
read_when: ["데이터 관리 설계","내보내기 가져오기 컬럼 분리","근력 세션 그룹핑","중복 의심 3구분","D3 D5 결정","백업 최대보존","파서 유연화 A C","자유양식 제외","export 왕복 오염","체지방량 세트번호 오매핑"]
document_type: "의사결정"
source_status: "generated"
knowledge_group: "03_history"
work_timestamp: "20260702_204706"
source_of_truth: "https://dallog-tools.hansbridge.co.kr/knowledge/"
context: "달록본레포CC (D:\\dallog\\dallog_git)."
---

> 관련 작업보고: "데이터 관리(엑셀 내보내기/가져오기)". 본 문서는 설계 결정·사장님 수정 반영 기록.

## 1. 결정 목록 (권고안 → 사장님 확정)
- **D1(승인)** 근력 세트 표현: export 시 연속 동일(중량·횟수) 세트만 묶고, 세트 순서는 set_index로 보존(전부 병합은 순서 파괴라 Codex 지적으로 "연속 동일만"으로 보정).
- **D2(승인)** "루틴명" = `strength_logs.label`에 저장·그룹핑 키로 사용. 체지방률만 있으면 fat_kg 역산 저장(기존 saveBody 패턴).
- **D3(사장님 수정)** 아래 별도 항목.
- **D4(승인)** 중량 공란 = `weight_kg=null` + `use_additional=false`(0 강제 금지·맨몸/미기록).
- **D5(사장님 보완)** 아래 별도 항목.

## 2. ★D3 — 내보내기 ≠ 가져오기 컬럼 (사장님이 뒤집음)
- **CC 초기 권고(오류)**: 왕복 호환을 위해 내보내기 컬럼을 가져오기 양식과 동일하게 제한.
- **사장님 지적**: 이는 구현을 단순화하려 백업 필드를 깎은 축소(§0.4 위반). 내보내기는 **백업 목적 = 최대 보존**, 가져오기는 **입력 편의 = 간소** → 둘을 동일 강제하지 말 것.
- **확정**: 내보내기 xlsx = 달록 보유 주요 필드 최대 보존(러닝 런타입·신발·페이스·거리반영, 근력 추가중량·세트번호 등). 가져오기 표준양식 = 지시 5번 간소 컬럼. 둘은 독립.

## 3. ★D5 — 러닝·근력 중복 처리 (사장님 보완)
- **CC 초기 권고**: 체성분 upsert / 러닝·근력 insert(중복 판정 범위 밖).
- **사장님 보완**: 러닝·근력도 최소한 파일 내부 중복 + 기존 DB 명백한 중복을 인식 결과에서 경고할 것. "무조건 신규 N건"이 아니라 **신규 / 중복 의심 / 오류 3구분**으로 표시하고, 중복 의심이 있으면 적용 전 사용자 확인.
- **확정**: 체성분 upsert(날짜) 유지. 러닝=날짜+시각, 근력=날짜+시각+루틴 키로 중복 의심 판정. 인식 결과 3구분 + 중복 포함 체크박스.

## 4. 참고 패널 사용 범위 (지시 4번)
"AI에게 보내기" 패널은 **레이아웃 골격만 참고**(오버레이·닫기·캡션·선택영역·하단 액션 배치). AI 고유요소(제목·"AI에게 보내기용 복사"·Markdown 중심 동작·부가영역 선택·개인메모/코치저널/프로필목표 등)는 **가져오지 않음**. 기존 AI 전달용 Markdown 기능은 변경하지 않고 별도 경로로 분리.

## 5. Codex 검수로 보강된 결정
- 근력 세션 그룹키(날짜+시각+루틴)가 시각·루틴 공란 시 과병합 위험 → 공란 시 경고.
- 세션 note는 스키마상 세션 단위 → 같은 세션 첫 행 메모를 세션 note로.
- 시각/소요시간/날짜 파싱 엄격화(엑셀 serial·Date·M:SS 초<60·불가능 날짜 차단).
- all-or-nothing 트랜잭션은 Supabase client 한계로 RPC 필요 → 이번은 근력 세션 단위 보상삭제 + 부분성공 시 outcome 표시로 갈음(파일 전체 원자성은 후속).

## 6. ★D6 — 가져오기 파서 유연화 (A+C) 채택 · 자유양식(B) 제외 (2026-07-03)
사장님 "파서 개선하면 블록2 완전 닫고 블록3" 요청에 대해 개선 방향을 4안으로 제시하고 **A(유연 헤더/컬럼 매핑) + C(CSV 지원)** 확정.
- **왜 B(타 앱 자유양식 자동해석)를 뺐나**: 자유양식은 입력이 무한이라 "N개 포맷 지원해도 N+1번째가 또 실패" → **구조적으로 "완전히 닫히지 않는" 작업**. 사장님 목표("완전 닫고 블록3")와 상충. 게다가 오파싱=조용한 데이터 오염 위험이 큼. → B는 범위 밖(출시 후 별도 페이즈), A·C만 경계가 분명해 닫힘.
- **D(특정 실패케이스 수정)**: 사장님 결정으로 페이즈1 완전 종료 후 별도 세션 이관.

### ★특이이슈 — Codex가 잡은 export→import 왕복 데이터 오염 (치명 2건)
유연 매핑이 우리 앱 **내보내기 헤더**를 그대로 가져올 때 조용히 값을 오염시키는 버그를 Codex 검수가 포착:
1. **체지방량(kg) → 체지방률(%) 오매핑**: export 헤더에 `체지방량(kg)`·`체지방률(%)`이 둘 다 있는데, `체지방` 부분매칭으로 체지방량(예 8.7kg)이 체지방률(8.7%)로 저장될 뻔. → fat_pct 별칭을 `체지방률`/`체지방비율` 등 비율 토큰만으로 정밀화(`체지방량` 배제).
2. **세트번호 → 세트수 오매핑**: export의 `세트번호`(set_index=1,2,3…)가 `세트수`로 잡혀 "3세트 생성"으로 **세트 증식**. → setCount 별칭을 `세트수`/`세트개수`/`세트갯수`만으로 정밀화(`세트번호` 배제, 근력 export는 안전 거부).
- 부가: CP949 CSV mojibake(→UTF-8 fatal 디코드 거부), 무명시트 다중유형 모호(→reject), 과도축소로 안전변형표기 거부(→`체지방비율`·`세트개수` 복원), U+FFFD 오탐(→fatal 디코드).
- **교훈**: 왕복(export↔import) 데이터 오염은 단위테스트만으론 못 봄 — **우리 앱 실제 헤더 조합**으로만 드러남. Codex 3라운드(검수-반영-재검수)로 걸러냄. 회귀 고정 테스트 추가(파서 28케이스).
