---
title: "🚀 260526-월요일_셀기능 시각검증 2차 fix + 컬럼 필터 + 신발 마일리지"
notion_id: "36c229620868819494a7f6e8b68b7300"
notion_url: "https://app.notion.com/p/36c229620868819494a7f6e8b68b7300"
category: "workreport"
parent: "Claude Code 작업보고"
updated: "2026-05-26"
priority: "Medium"
purpose: "셀기능 2차 시각검증 잔여 fix 2건 + 추가요청 3건(컬럼 필터·신발별 마일리지 차트·Settings 신발 마일리지 병기)"
---

> ⚡ **작업 메타**
> - 일자: 2026-05-26 (월)
> - 범위: 시각검증 2차 잔여 fix 2건 + 사용자 추가 요청 3건
> - 커밋: `78b027b` (origin/main 반영)
> - 빌드: 성공 (419 modules, gzip 331KB)
> - 이전: `a453a0c` (1차 fix)

## 1. 사용자 2차 시각검증 리포트

5건 보고 — 1차 fix 잔여 2건 + 추가 요청 3건. 모두 처리. 이슈 11 RLS는 이전 트랙 유지.

## 2. 잔여 fix 2건

### 2-1. 이슈 1 잔여 — 셀 레이아웃 + 모바일 popover 잘림

**원인 가설 확정:**

- popover 잘림: `position: absolute, right: 0, minWidth: 240px`. trigger 버튼이 모바일 좌측에 있을 때 popover가 trigger right edge 기준으로 좌측으로 펼쳐져 화면 밖 잘림
- 셀 텍스트 밀림: 러닝 시간 셀 width 95px에 input 3개(42+34+34=110px+gap)가 안 들어가서 flex wrap → 두 줄이 됨

**수정:**

- ColumnConfigDropdown: fixed center overlay 패턴 — 전체 화면 다크 난 배경 + 가운데 모달형 팝오버. 모바일 잘림 원천 차단
- CellModeRunning RUN_COLUMNS: 시간 컬럼 95px → 120px, 날짜 100→105px (마지막 셀도 70px로 여유)
- 시간 input width 38/28/28 → 42/34/34, padding 3px 1px → 3px 2px, flex: 0 0 auto 명시
- 셀 minHeight 30 → 36, padding 4px 5이Ć6px → 6px 5이Ć6px, boxSizing: border-box 명시

### 2-2. 이슈 2 잔여 — 삭제가 여전히 안됨

**원인 추정 (코드 계층에서는 이상 없음):**

- `supabase.from(...).delete().in('id', ids)` 호출은 정상
- ConfirmDialog 열림 → 사용자 승인 → doDelete 호출 정상
- **가능성 A**: 실제로는 서버 응답이 조용한 실패 (RLS 차단). error 객체 비어 있고 행도 남아 있음 → 사용자는 "삭제 안 됨"으로 인지
- **가능성 B**: 이전 setMsg 에러 메시지가 작은 글씨라 사용자가 못 봤을 수

**수정:**

- `supabase.delete({ count: 'exact' })` — 삭제 된 행 수 명시적 확인
- count === 0 경우 명시적 에러: "DB 응답 count=0 — 권한 부족 또는 ID 미일치. RLS 정책 점검 필요."
- **NotifyDialog 강제 키움** — 성공·실패 가림없이 모달로 궁조. 실패 시는 "v0.9 작업 2 RLS 검증 항목" 명시
- console.log로 디버그 정보 출력 (사용자가 콘솔 열어 확인 가능)

## 3. 추가 요청 3건

### 3-1. 추가1 — 컬럼 필터 기능 (MS엑셀 유사)

**설계:**

- 컬럼별 카테고리 필터 — 고유값 체크박스 list (엑셀 패턴)
- 활성 필터들의 AND 결합
- 명시적 "적용" 전까지 변경 미반영 (tmp state)
- 검색 input + 전체선택/해제 + 체크박스 list + 필터 해제

**신규 파일:**

- `useColumnFilters.ts` — hook (activeFilters Map + filteredRows useMemo + getUniqueValues)
- `ColumnFilterPopover.tsx` — popover UI (fixed center overlay 패턴, ColumnConfigDropdown과 동일)

**ColumnDef 확장:** `filterable?: boolean` 추가

**필터 가능 컬럼:**

| 탭 | 필터 가능 | 값 추출 |
|---|---|---|
| 체성분 | 프로젝트 | projectName(project_id) |
| 러닝 | 런타입 / 루틴 / 신발 / 마일리지 | run_type / routineName(routine_id) / shoe / '마일리지 포함' or '제외' |

**헤더 UI:** filterable 컬럼 헤더 옆에 ▽(비활성) / ▼(활성, 라임색) 버튼

**편집 모드 보호:** 필터 활성 시에도 _isNew · _dirty 행은 항상 표시 (작업 흐름 보존)

### 3-2. 추가2 — 대시보드 RUNNING 신발별 마일리지 막대그래프

**구현:**

- runs 에서 is_record !== false 만 합산 → Map(shoe → totalKm)
- 가로 막대 (indexAxis: 'y') Bar 차트
- 신발 수에 따라 동적 높이 (24px × 신발수 + 30px)
- 라임 채움 + barThickness: 14 + borderRadius: 4
- 위치: '월별 마일리지' 차트 다음 (심박/케이던스/페이스 추이 차트 앞)
- 헤더: "신발별 누적 마일리지" + "마일리지 포함 기록 기준 · N종"

### 3-3. 추가3 — Settings 신발 목록에 마일리지 병기

**구현:**

- fetchAll 에 `running_logs.select('shoe,distance_km,is_record').limit(2000)` 추가
- 신발별 누적 km 계산 → shoeMileageMap state
- 신발 카드에 "`s.name` · 12.3 km" 형식 병기
- **새 신발은 0.0 km 릌당** (사용자가 부탁한 가시화 명시 필요)
- 마일리지 포함(is_record !== false) 기준으로만 집계

## 4. 변경 파일

| 파일 | 추가/수정 | 요약 |
|---|---|---|
| `src/components/cellmode/CellModeBody.tsx` | 수정 | 셀 보강 + 삭제 NotifyDialog + 필터 통합 |
| `src/components/cellmode/CellModeRunning.tsx` | 수정 | 시간 셀 폭 + 삭제 NotifyDialog + 필터 통합 |
| `src/components/cellmode/ColumnConfigDropdown.tsx` | 수정 | fixed center overlay 패턴 |
| `src/components/cellmode/useColumnConfig.ts` | 수정 | ColumnDef.filterable 추가 |
| `src/components/cellmode/useColumnFilters.ts` | 신규 | 컬럼 필터 hook |
| `src/components/cellmode/ColumnFilterPopover.tsx` | 신규 | 필터 popover UI |
| `src/components/dashboard/RunningSection.tsx` | 수정 | 신발별 마일리지 차트 |
| `src/pages/Settings.tsx` | 수정 | 신발 목록에 마일리지 병기 + fetchAll 러닝 로드 |

8 files / +503 / -81 lines

## 5. 검증

- `npx tsc --noEmit`: 오류 0
- `npm run build`: 성공 (419 modules, gzip 331KB — 이전 328KB 에서 +3KB)
- MCP 브라우저 재검증: 사용자 사후 체크

## 6. 미해결·별도 트랙

> ⚠️ **이슈 11 (OAuth 런타입 RLS) — 진행중 아님, 리마인드 유지**
> v0.9 작업 2 (멀티유저 보안) 안에서 적용아쁗. 이슈 2 삭제 불가와 같은 원인(RLS 정책) 가능성 높음. 이번 추가된 삭제 실패 메시지의 "v0.9 작업 2 RLS 검증 항목" 안내가 이용자 리마인드 역할.

## 7. 후속 권고

1. 사용자 사후 체크 (Cloudflare 자동 배포 1~3분 후 반영)
	- 모바일 컬럼 설정 → 잘림 없이 가운데 모달로 열림 확인
	- 러닝 수정 모드 시간 셀 입력 올바르게 표시 확인
	- 삭제 시도 → 성공하면 NotifyDialog "삭제 완료", 실패하면 "삭제 실패" + 원인 안내
	- 헤더 ▽ 아이콘 클릭 → 필터 popover → 체크박스 선택 → 적용 확인
	- 대시보드 RUNNING 신발 차트 표시
	- 설정 → 개인 러닝 → 신발 목록에 "· N.N km" 표시
2. 이슈 11 v0.9 작업 2로 해소
3. 근력 Phase 5 세컨드 페이즈 (옵션B 1행=1세트) — useColumnFilters/useColumnConfig hook 그대로 재사용 가능

---

> ✅ **결론**
> 잨여 2건 fix + 추가 3건 접수 → 구현 완료. `a453a0c..78b027b` 푸쉬. 이슈 11 RLS는 임시 환경 안내 메시지로 사용자 인지 확보. 완전 해소는 v0.9 작업 2의 일환.
