# mypage 영상 모달 연결 구조 분석 및 선행 Task
작성 목적
- `mypage.php`의 3개 탭(시청중인 콘텐츠, 시청완료 콘텐츠, 저장한 콘텐츠) 리스트 카드 클릭 시, `search_result.php`와 동일한 "카테고리 정책 보존형 모달 라우팅"을 적용하기 위한 사전 구조 분석 문서.
- 이 문서는 분석/태스크 정의용이며, 실제 코드 반영 전 기준점으로 사용한다.
---
## 1) 현재 마이페이지 구조 (운영 기준)
### 1-1. 화면 엔트리
- 메인 페이지: `edu/skin/mypage.php`
- 탭 UI:
- 시청중인 콘텐츠: `#panel-watching`, 리스트 컨테이너 `#mypage-watching-list`
- 시청완료 콘텐츠: `#panel-completed`, 리스트 컨테이너 `#mypage-completed-list`
- 저장한 콘텐츠: `#panel-saved`, 리스트 컨테이너 `#mypage-saved-list`
### 1-2. 프론트 스크립트 역할 분리
- `edu/js/mypage.js`
- 퍼블리싱 UI 전환 중심(탭 전환, 모바일 UI/바텀시트, 아코디언 등)
- 콘텐츠 모달 로직 없음
- `edu/js/apply_page/add_mypage.js`
- 실데이터 바인딩/탭별 AJAX 조회/무한스크롤/북마크 토글/삭제/한줄소감/학습레벨 처리
- 현재 마이페이지 데이터 동작의 핵심 스크립트
### 1-3. 데이터 API
- 학습활동/카테고리 통계: `edu/ajax/get_init_data_for_mypage.php`
- 탭별 콘텐츠 리스트: `edu/ajax/get_video_list_for_mypage.php`
- 북마크 토글: `edu/ajax/toggle_content_wishlist.php`
- 카드 삭제(정책상 버튼 숨김): `edu/ajax/delete_mypage_content_item.php`
- 한줄소감: `edu/ajax/get_review_list_for_mypage.php`
---
## 2) 현재 탭 리스트 렌더링 방식
### 2-1. 서버 HTML 조각 주입 방식
- `add_mypage.js`의 `loadWatchingContentList / loadCompletedContentList / loadSavedContentList`가
`get_video_list_for_mypage.php`를 호출한다.
- 응답은 JSON 형태지만, 리스트 본문은 `html` 문자열(서버에서 생성한 `
` 조각)로 내려온다.
- 프론트는 `innerHTML` 또는 `insertAdjacentHTML`로 직접 주입한다.
### 2-2. 카드 마크업 특징
- 각 카드 루트는 `.content-card[data-content-id]`
- 카드 링크는 `.card-link`
- 북마크 체크박스는 `.bookmark input[type="checkbox"]`
- 현재 서버에서 카드 링크 URL을 강제로 `#`로 세팅하고 있어 모달 오픈 진입이 없다.
### 2-3. 탭 카운트/무한스크롤
- 카운트는 API 응답 `counts`를 `renderContentTabCounts`로 갱신
- 무한스크롤은 각 탭 리스트 `ul`의 `scroll` 이벤트 기반
- 탭별 상태: `contentListState.{watching|completed|saved}`
---
## 3) 모달 연결 관점에서 현재 갭
### 3-1. 모달 오픈 진입점 부재
- 카드 클릭 시 호출되는 모달 함수가 없다.
- `VideoModalManager` 인스턴스 생성 코드도 현재 마이페이지 경로에는 없다.
### 3-2. 브리지 라우팅에 필요한 데이터 부족
- 현재 카드 DOM에는 최소 `content_id`만 보장된다.
- 카테고리 분기(`category_code`)와 브리지 입력 스키마(`title`, `description`, `subCategory`, `watchTm`, `contentTm`, `bookmark` 등)를 안정적으로 꺼낼 원천이 부족하다.
- `get_video_list_for_mypage.php`는 내부적으로 필요한 데이터를 계산하지만, 프론트에 구조화된 `videos` 배열을 내려주지 않고 HTML 조각 위주로만 사용한다.
### 3-3. 추천/전용 UX 보존 요구
- `search_result.php`와 동일하게 카테고리별 브리지 우선 호출이 필요하다.
- 이미 사용 중인 브리지:
- 온보딩: `window._onboardingOpenModal`
- 법정교육: `window._learningOpenModal`
- 미연결 브리지(추가 필요): 인사이트/리더십/비즈트렌드(또는 fallback 정책 명확화)
### 3-4. 북마크 이벤트 충돌 가능성
- 현재는 문서 전역 `change` 이벤트에서 체크박스를 처리하며, `.content-card` 기준으로 북마크 토글을 수행한다.
- 모달 내부 체크박스/리스트 체크박스와 이벤트가 섞이지 않도록 이벤트 스코프 구분이 필요하다.
---
## 4) search_result와 비교한 구조 차이
### search_result
- 페이지 내 `currentVideos` JSON 보유
- `openSearchResultVideoByCategory(videoData)`로 카테고리 분기
- 브리지 없으면 `VideoModalManager.openVideo` fallback
### mypage (현재)
- 탭별 HTML 조각 주입 중심
- 카드별 구조화된 `videoData` 저장소 없음
- 모달 호출 함수 없음
결론
- 마이페이지는 먼저 "리스트 데이터 모델(클라이언트 측 video map) 확보"를 해야 search_result와 같은 브리지 라우팅 구조를 적용할 수 있다.
---
## 5) 필요한 작업 Task (코드 적용 전 정의)
우선순위 순서로 정리.
### Task A. 마이페이지 모달 라우팅 공통 함수 도입
- 목표: 카드 클릭 -> 카테고리별 브리지 호출 -> fallback 공통 모달 흐름 구현
- 작업 항목:
1) `add_mypage.js`에 `openMypageVideoByCategory(videoData)` 추가
2) 분기 정책을 `search_result.php`와 동일하게 정렬
3) 브리지 함수 존재 여부 체크 후 호출
4) 브리지 미존재 시 `VideoModalManager.openVideo(content_id)` fallback
### Task B. 탭 리스트 데이터 모델 정규화
- 목표: 각 카드 클릭 시 `videoData`를 안정적으로 조회 가능하게 만들기
- 작업 항목(선택지):
1) `get_video_list_for_mypage.php` 응답에 `videos` 배열(구조화 데이터) 추가
2) 또는 카드 DOM에 `data-*`를 확장해 분기/모달 입력값을 모두 싣기
3) 탭별 로딩 후 전역 map(`content_id -> videoData`) 유지
- 권장안: `videos` 배열 병행 응답(HTML + JSON 동시 반환)
### Task C. 카드 클릭 이벤트 체계 정리
- 목표: 북마크 체크 클릭과 카드 클릭(모달 오픈)을 명확 분리
- 작업 항목:
1) `.card-link` 클릭 위임 핸들러 추가
2) `.bookmark` 영역 클릭 시 모달 오픈 차단
3) 모바일 탭/무한스크롤과 충돌 없는 위임 범위 고정
### Task D. 마이페이지 전용 공통 모달 fallback 준비
- 목표: 브리지가 없는 카테고리도 기존 기능 손실 없이 기본 모달 오픈
- 작업 항목:
1) `VideoModalManager` 인스턴스를 마이페이지에서 1회 생성/재사용
2) 탭 데이터 갱신 시 manager 내부 `videos` 동기화
### Task E. 브리지 대상 카테고리 확장
- 목표: 탭 3개 어디서 열어도 카테고리 원본 UX 보존
- 작업 항목:
1) 비즈트렌드 브리지 재사용 가능 여부 확인
2) 인사이트/리더십 브리지 신규 작성 또는 fallback 정책 확정
3) 온보딩/법정교육 브리지 로딩 순서 및 의존성 확인
### Task F. API/세션 일관성 정비
- 목표: 최근 정책(세션 키, 완료 기준, 정렬 기준)과 동일 동작 보장
- 점검 항목:
1) 세션: `member_id`, `sys_comp_code` 기준 유지
2) 완료 판단(특히 completed 탭)과 실제 모달 상태의 정합성
3) 정렬 기준(최근 시청/완료/저장 시점)과 UX 일치
### Task G. 검증 체크리스트
- 공통:
1) 3개 탭 카드 클릭 시 모달 정상 오픈
2) ESC/배경/닫기 버튼 정상
3) 북마크 토글 후 탭 카운트/카드 체크상태 동기화
4) 무한스크롤 로드 이후 카드도 동일하게 모달 오픈
- 카테고리별:
1) 온보딩: 차시/댓글/북마크/이어보기
2) 법정교육: 차시 정렬/완료상태/설명 노출
3) 리더십/인사이트/비즈트렌드: 원본 페이지 정책 유지
---
## 6) 권장 구현 순서 (실작업 시작 시)
1. `Task B` (데이터 모델 정규화) 먼저
2. `Task C` (카드 클릭 이벤트) + `Task D` (fallback manager)
3. `Task A` (카테고리 분기 함수)
4. `Task E` (브리지 확장)
5. `Task F` (정합성 점검) + `Task G` (검증)
이 순서가 가장 안전한 이유
- 현재 마이페이지는 HTML 조각 주입 기반이므로, 데이터 모델이 먼저 없으면 브리지 분기 자체가 불안정해진다.
---
## 7) 마이페이지 작업 이력 로그
기록 규칙
- 마이페이지 관련 작업이 끝날 때마다 이 섹션 마지막에 항목을 추가한다.
- 코드 전체는 넣지 않고, 파일/라인/작업요약만 기록한다.
### 2026-04-21 / Task B 1차 반영
1. `edu/ajax/get_video_list_for_mypage.php`
- 라인 31: `map_content_row` 시작점.
- 라인 39: `all_tm` 파생값 추가.
- 라인 63: `subcate(category_group)` 매핑 추가.
- 라인 66: `description2` 매핑 추가.
- 라인 74: 응답 video 항목에 `all_tm` 포함.
- 라인 225, 271, 321, 344: 탭별 조회 SQL에 `c.category_group` 컬럼 추가.
- 라인 228, 274, 324, 347: 탭별 조회 SQL에 `c.description2` 컬럼 추가.
- 라인 233, 279, 290, 329, 352: 탭별 조회 SQL에 `all_tm` 컬럼 추가/전파.
- 라인 529: JSON 응답에 `videos` 배열 추가 (`html` 병행 유지).
2. `edu/js/apply_page/add_mypage.js`
- 라인 28: 탭별 구조화 데이터 저장소 `mypageVideoStore` 추가.
- 라인 35: 디버그/연동용 `window._mypageVideoStore` 노출.
- 라인 48-49: 탭 상태 초기화 시 해당 탭 store clear 처리.
- 라인 53: `normalizeMypageVideo(video)` 추가 (모달 분기용 표준 포맷 정규화).
- 라인 81: `mergeVideosIntoStore(tab, videos, page)` 추가.
- 라인 746: watching 로딩 응답에서 `data.videos` store 반영.
- 라인 808: completed 로딩 응답에서 `data.videos` store 반영.
- 라인 878: saved 로딩 응답에서 `data.videos` store 반영.
3. 검증
- `edu/ajax/get_video_list_for_mypage.php`: 오류 없음.
- `edu/js/apply_page/add_mypage.js`: 오류 없음.
### 2026-04-21 / Task C + Task D(최소 fallback) 반영
1. `edu/skin/mypage.php`
- 라인 617: `VideoModalManager` 로더 스크립트 추가 (`/edu/js/main/Videomodalmanager.js`).
2. `edu/js/apply_page/add_mypage.js`
- 라인 37: `mypageModalManager` 변수 추가(마이페이지 공통 모달 인스턴스 참조).
- 라인 58: `normalizeMypageVideo`에 `category` 필드 정규화 추가.
- 라인 68: `normalizeMypageVideo`에 `type` 기본값(`main`) 추가.
- 라인 98: store merge 이후 `syncMypageModalManagerVideos()` 호출 추가.
- 라인 101: `getAllMypageVideos()` 추가(탭별 store 병합).
- 라인 115: `ensureMypageModalManager()` 추가(1회 생성/재사용).
- 라인 131: `syncMypageModalManagerVideos()` 추가(manager 영상목록 동기화).
- 라인 141: `getVideoByTabAndContentId(tab, contentId)` 추가(카드 클릭 시 데이터 조회).
- 라인 155: `bindContentCardOpenAction()` 추가(카드 클릭 위임 핸들러).
- 라인 161: `.bookmark`, `.btn-remove-card` 클릭 시 모달 오픈 차단 처리.
- 라인 189: fallback 모달 오픈 `manager.openVideo(videoData.content_id)` 연결.
- 라인 221: `DOMContentLoaded` 구간에 `bindContentCardOpenAction()` 바인딩 추가.
3. 검증
- `edu/skin/mypage.php`: 오류 없음.
- `edu/js/apply_page/add_mypage.js`: 오류 없음.
### 2026-04-21 / Task A 반영
1. `edu/js/apply_page/add_mypage.js`
- 라인 155: `toBridgeInfo(videoData)` 추가(브리지 공통 입력 스키마 변환).
- 라인 174: `openMypageVideoByCategory(videoData)` 추가(카테고리 정책 보존형 분기 함수).
- 라인 178-179: `CA10006` 비즈트렌드 브리지(`window._biztrendOpenModal`) 우선 호출.
- 라인 183-184: `CA10005` 인사이트 브리지(`window._insightOpenModal`) 우선 호출.
- 라인 188-189: `CA10004` 리더십 브리지(`window._leadershipOpenModal`) 우선 호출.
- 라인 193-194: `CA10003` 법정교육 브리지(`window._learningOpenModal`) 우선 호출.
- 라인 198-199: `CA10002` 온보딩 브리지(`window._onboardingOpenModal`) 우선 호출.
- 라인 203-211: 브리지 미존재 시 `VideoModalManager.openVideo(content_id)` fallback 유지.
- 라인 239-240: 카드 클릭 핸들러에서 `openMypageVideoByCategory` 호출로 전환 및 실패 로그 처리.
2. 검증
- `edu/js/apply_page/add_mypage.js`: 오류 없음.
### 2026-04-21 / Task E 반영
1. `edu/skin/mypage.php`
- 라인 620: 법정교육 브리지 로드 스크립트 추가 (`/edu/js/bridges/learning-modal-bridge.js`).
- 라인 621-627: 온보딩 브리지 의존용 `window.puzzleConfig` 주입 추가.
- 라인 628: 온보딩 전용 스크립트 로드 추가 (`/edu/js/puzzle-onboarding.js`).
- 라인 629: 온보딩 브리지 로드 스크립트 추가 (`/edu/js/bridges/onboarding-modal-bridge.js`).
- 라인 630: fallback 공통 모달 스크립트 유지 (`/edu/js/main/Videomodalmanager.js`).
2. `edu/js/apply_page/add_mypage.js`
- 라인 174: `tryBridgeOpen(openFn, bridgeInfo, bridgeName)` 추가(브리지 실패를 흡수하고 fallback 가능하도록 처리).
- 라인 183: 브리지 예외 로그 표준화(`[mypage modal] bridge failed`).
- 라인 193: `CA10006` 비즈트렌드 브리지 호출을 `tryBridgeOpen` 경유로 변경.
- 라인 198: `CA10005` 인사이트 브리지 호출을 `tryBridgeOpen` 경유로 변경.
- 라인 203: `CA10004` 리더십 브리지 호출을 `tryBridgeOpen` 경유로 변경.
- 라인 208: `CA10003` 법정교육 브리지 호출을 `tryBridgeOpen` 경유로 변경.
- 라인 213: `CA10002` 온보딩 브리지 호출을 `tryBridgeOpen` 경유로 변경.
- 라인 218 이후: 브리지 호출 실패/미존재 시 `VideoModalManager` fallback 경로 유지.
3. 검증
- `edu/skin/mypage.php`: 오류 없음.
- `edu/js/apply_page/add_mypage.js`: 오류 없음.