# 죽은 코드·중복 코드 정리 (보류 — 나중에 한 번에 진행) > 2026-09-04 사용자 지시로 상시계획서에서 빼 여기 보관함. 다른 작업이 끝난 뒤 한 창이 전담해 한 번에 진행 예정. > 점검 기록·대상 목록은 아래 그대로임(상시계획서 「진행 예정」에 있던 내용). ### 죽은 코드·중복 코드 정리 (2026-09-04 점검, 착수 지시 대기) 전수 정적 분석 결과 — Python 186개·TypeScript 245개 파일 대상(벤더 `openwebcad`·지식DB 제외). 점검표: . **아직 코드는 하나도 안 고침.** 다른 AI 교차검토 후 지울 것·남길 것을 가르고 착수. 판정 방법 — ① 안 쓰는 import·변수 `ruff check --select F401,F811,F841` ② 안 불리는 함수 = Python AST 로 최상위 `def` 를 뽑아 전 소스 이름 검색, 데코레이터 붙은 것은 사용중으로 간주 ③ 안 쓰이는 export = TS `export` 이름이 다른 파일에 한 번도 안 나오는지 검사 ④ 중복 = 주석·빈 줄 제거 후 10줄 창 해시, 이어지는 창을 합쳐 최대 블록 산출. 분석 스크립트는 일회성이라 남기지 않음 — 재현이 필요하면 같은 절차 재작성. 한계 — 문자열로 동적 호출하거나 템플릿·JSON 설정에서만 부르는 코드는 "안 쓰임" 으로 잘못 잡힐 수 있음. **항목마다 지우기 전 재확인 필수.** #### 1단계 — 통째로 죽은 것 (확인 후 삭제) - [ ] **A09 보안관리 API 한 벌** — 프론트 `A09_Security/A09_Security_Api_Fetch.ts`(61줄, 함수 8개)와 백엔드 `A09_Security/A09_Security_Router.py` 엔드포인트 9개(`/security/master/*` 5개, `/security/admin/*` 3개, `/security/activity` 1개). 화면 `A09_Security_UI_Page.ts` 가 이 API 파일을 import 하지 않고, 이 경로들을 부르는 곳도 죽은 파일 자신뿐임. 같은 기능을 `B01_Dashboard` 의 `/dashboard/admin/*` 가 이미 수행. **판단 필요 — 관리자 화면을 A09 로 되살릴 계획이 있는지 사용자 확인 후 삭제.** 삭제 시 `main.py` 의 `a09_security_router` 등록도 함께 정리. - [ ] **A07 회원가입 옛 화면** — `A07_Register/A07_Register_UI_Page.ts` 141줄. 라우터(`A00_Common/router.ts:30`)가 부르는 것은 `A07_Register_UI_Auth_Page` 뿐이고 이 파일을 import 하는 곳 없음. 삭제 후보. - [ ] **벡터 타일 서빙 엔드포인트** — `B04_PreProcess/B04_PreProcess_Router_GIS.py:180` `GET /tiles/{project_id}/{layer}/{z}/{x}/{y}.pbf`. 등록 API 123개 중 프론트 호출 흔적이 없는 유일한 것(`tiles/` 문자열이 TS 전체에 없음). **지도 타일 방식 전환 잔재로 보이나 향후 계획 확인 필요.** - [ ] **`db_management/migrate_workflow_state.py` (158줄)** — 어디서도 import 안 됨. 손으로 한 번 돌리는 마이그레이션이면 정상이므로 **삭제 말고 용도만 확인**. - [ ] **`B08_Quantity/0_old_260726_codex.zip`** — 옛 코드 보관 압축본. 필요 없으면 삭제. #### 2단계 — 안 불리는 Python 함수 16개 (호출처 0) 큰 것부터. 지우기 전 각 함수가 문자열·설정으로 불리지 않는지 확인. - [ ] `B04_PreProcess/B04_PreProcess_Engine_Watershed_Flow.py:457` `expand_until_closed()` 54줄 — 가장 큼. 배수유역 확장 로직으로, 현재 흐름에서 빠진 것인지 미완성인지 확인 필요. - [ ] `B01_Dashboard/B01_Dashboard_Repository.py:358` `create_system_company()` 29줄 / `:543` `count_company_admins()` 10줄 - [ ] `B06_Section/B06_Section_Repository.py:497` `count_cross_sections_without_design()` 20줄 - [ ] `B02_ProjRegister/B02_ProjRegister_Repository.py:133` `get_project_by_id()` 16줄 - [ ] `B04_PreProcess/B04_PreProcess_Repository.py:307` `update_project_status()` 12줄 - [ ] `common_util/common_util_workflow.py:31` `patch_project_workflow_stale()` 12줄 - [ ] `B04_PreProcess/B04_PreProcess_Engine_Watershed_Analyze.py:106` `preview_primary_region()` 10줄 - [ ] `common_util/common_util_auth_repository.py` — `:15` `_company_code()` 4줄, `:162` `company_master_email()` 10줄, `:282` `delete_user_sessions()` 5줄 - [ ] `common_util/common_util_drainage_detail.py:684` `estimate_pipe_diameter_mm()` 9줄 — **도메인 산식이므로 삭제 전 지식DB 대조 필요**(관경 결정 근거). - [ ] `common_util/common_util_email_templates.py:19` `join_request_email()` 8줄 — 가입요청 메일 본문. A09 삭제 여부와 묶어 판단. - [ ] `common_util/common_util_wamis_rainfall.py:333` `design_depth_mm()` 7줄 — **강우 설계값 산식, 삭제 전 지식DB 대조 필요.** - [ ] `B04_PreProcess/B04_PreProcess_Engine_SheetStore.py:266` `missing_sheets()` 4줄 - [ ] `B05_Profile/B05_Profile_Engine_Grade_Alignment.py:146` `tangent_elevation()` 3줄 #### 3단계 — TypeScript 정리 (동작 안 바뀜) - [ ] **안 쓰이는 export 31개 삭제** — 정의만 있고 자기 파일 안에서도 안 쓰이는 것. `A09_Security_Api_Fetch.ts` 8개(1단계와 함께 파일째 삭제), `B01_Dashboard_Api_Fetch.ts` 3개(`createSystemCompany`·`assignUserToCompany`·`fetchProjectWorkflowState`), `B06_Section_UI_Cross_Culvert_Const.ts` 4개(`PITCHING_THICKNESS_M`·`REVET_MATERIALS`·`FILL_STRUCTURE_HEIGHT_M`·`BASIN_BOTTOM_CLEARANCE_M` — **도면 상수라 지식DB 대조 후 판단**), `B03_FileInput_Api_Fetch.ts` 2개, `B05_Profile_UI_IrregularStations.ts:161` `createIrregularStationsSection`(아래 「B05/B06 미사용 코드 정리 후보」와 같은 항목), `B05_Profile_Util_Station.ts:44` `parseStationText`, `config/config_frontend.ts` 3개, `ui_template/ui_template_elements.ts:347` `createWorkflowShell` 등. - [ ] **`export` 만 떼면 되는 것 77개** — 자기 파일 안에서만 쓰는데 `export` 가 붙어 있음(예: `B05_Profile_UI_Corridor_Region.ts` `cross2`, `B03_FileInput_UI_Support.ts` `getBaseName`). 모듈 경계가 또렷해짐. **일괄 처리 대상 — 우선순위 낮음.** - [ ] **미사용 타입·인터페이스 249개는 그대로 둠** — API 응답 형태를 적어 두는 문서 역할. 정리 대상 아님. #### 4단계 — 안 쓰는 import 20건 - [ ] `B06_Section/B06_Section_Router.py` 7건 — 700줄 분리 리팩터링 잔재(`cross_filename`, `compute_default_designs`, `pavement_ranges`, `paved_at`, `default_section_modes`, `pavement_suggestions`, `design_elevation_from_longitudinal`). - [ ] `resources/knowledge/original/_pipeline/*` 13건 — 지식DB 수집 스크립트. `resources/knowledge/00_운영지침.md` 소관이므로 별도 판단. - [ ] 처리는 `ruff check --select F401 --fix` 로 일괄. 앱 코드와 지식DB 스크립트는 커밋을 나눌 것. #### 5단계 — 중복 블록 36군 (공통화 후보) 같은 값이 두 곳에 적힌 것은 한쪽만 고쳐 어긋나는 사고의 원인이 됨. 큰 것부터. - [ ] **32줄 — `requestJson` 헬퍼 통째 중복**: `B04_PreProcess_Api_Fetch.ts:142-179` ↔ `B05_Profile_Api_Fetch.ts:147-184`. 여기에 `B06_Section_Api_Fetch.ts:40-54` 도 15줄 겹침. **A00_Common 공통 fetch 헬퍼로 뽑는 것이 가장 이득 큼.** - [ ] **28줄 — `surface_models` 조회 SQL**: `B04_PreProcess_Router_Contour.py:62-91` ↔ `B04_PreProcess_Router_Status.py:161-188`. 같은 폴더 안이라 리포지토리 함수로 합치기 쉬움. - [ ] **22줄 — 종횡단 재생성 호출부**: `B05_Profile_Router.py:288-309` ↔ `B06_Section_Router.py:470-491`. - [ ] **19줄 / 16줄 — 패널 옵션 전달**: `B05_Profile_UI_Structures_Form.ts:135-153` ↔ `_Structures_Panel.ts:59-77`, `B05_Profile_UI_Drainage_Chrome.ts:152-167` ↔ `_Drainage_Panel.ts:86-101`. 최근 700줄 분리에서 생긴 인자 전달 중복으로 보임. - [ ] **17줄 ×3 — B07 라우터 머리말**: `B07_DesignDetail_Router_Support.py:88-111` ↔ `_Support_Basin.py:20-43` ↔ `_Support_Io.py:14-37`. `_STAGE_DIR`·`_CROSS_ID` 등 상수 3벌 — 공용 모듈 하나로. - [ ] **17줄 — `toXY` 좌표 변환**: `B06_Section_UI_Cross_Box.ts:45-61` ↔ `_Cross_Ford.ts:47-63`. - [ ] **15줄 ×3 — 옹벽 `baseWidth` 계산**: `B06_Section_UI_Cross_Wall.ts:68-82` ↔ `_Cross_Culvert_Extra.ts:231-248` ↔ `_Cross_Culvert_Geom.ts:348-365`. **설계 산식이 3벌 — 값이 어긋나면 도면·수량이 틀어짐. 우선순위 높음.** - [ ] **15줄 — `createHoldRepeater` 통째**: `B05_Profile_UI_Profile_Edit.ts:36-52` ↔ `B06_Section_UI_Cross_Design.ts:168-182`. 길게 누르기 반복 헬퍼 — 공용으로. - [ ] **15줄 — 박스·세월교 형상 계산**: `B06_Section_UI_Cross_Box_Geom.ts:83-99` ↔ `_Cross_Ford_Geom.ts:109-125`. - [ ] **15줄 / 10줄 ×2 — 유토곡선·표 오버레이 스크롤 동기화**: `B05_Profile_UI_Profile_MassHaul.ts` ↔ `_Profile_TableOverlay.ts` 세 군데(230-250·279-288·208-218). - [ ] **13줄 — 지반고 보간**: `B06_Section_UI_Cross_Culvert_Solve.ts:39-51` ↔ `_Cross_Design.ts:472-484`. - [ ] **12줄 ×2 — B05 엔진 중복**: `B05_Profile_Engine_RidgeValley.py` ↔ `_Engine_Solver.py`(회피점 통계 523-535↔647-659, 위반 구간 묶기 421-432↔549-560). - [ ] **12줄 / 11줄 ×2 — `ROUTES` 목록 3벌**: `A00_Common/main.ts:18-28` ↔ `A00_Common/router.ts:109-120` ↔ `config/config_frontend.ts:129-141`. **한 곳(config)만 정본으로.** - [ ] **11줄 — 허용 확장자 목록이 프론트·백엔드에 각각**: `config/config_frontend.ts:53-63` ↔ `config/config_system.py:78-88`. 언어가 달라 합치기 어려우면 **한쪽이 다른 쪽을 베낀 것임을 주석으로 명시**. - [ ] **11줄 — 워크플로 상태 기본값**: `B01_Dashboard_Repository.py:128-138` ↔ `common_util/common_util_workflow_state.py:200-210`. common_util 쪽을 정본으로. - [ ] **12줄 / 10줄 ×2 — B03 임시업로드 계열**: `B03_FileInput_Router_Chunks.py` ↔ `_Router_Temp_Chunks.py`(응답 365-376↔183-194, import 머리말 14-24↔13-23), `B03_FileInput_Repository.py:164-173` ↔ `_Repository_Temp.py:342-351`(`ON DUPLICATE KEY UPDATE`). 정식·임시 경로가 통째로 쌍둥이 — **묶어서 볼 것.** - [ ] **12줄 — 절·성토 면적 타입**: `B05_Profile_Api_Fetch.ts:69-80` ↔ `B06_Section_Api_Types.ts:145-156`. 타입 한 벌로. - [ ] **10줄 — 도면 글자 크기 상수**: `B07_DesignDetail_Engine_Cad_Basin.py:398-407` ↔ `_Cad_MassHaul.py:562-571`. - [ ] **10줄 — 모달 버튼 영역 생성**: `B01_Dashboard_UI_Modals.ts:46-55` ↔ `_UI_TempModal.ts:114-123`. 「B01 모달 — 바깥 클릭으로 닫기」 작업과 묶으면 한 번에 처리됨. - [ ] **10줄 — 좌표 `None` 처리**: `B04_PreProcess_Engine_SheetSurface.py:89-98` ↔ `_Router_Watershed.py:126-135`. - [ ] 나머지 소형 중복(13줄 배면 오프셋, 12줄 `onPipesChanged` 타입 등)은 위 처리 뒤 남는 것만 재판정. #### 자체검증 계획 - [ ] 단계마다 **`./venv/Scripts/python.exe -m pytest tmp/tests/ -q` 전부 통과** 확인. - [ ] 프론트는 `npm run typecheck` 통과 확인(삭제한 export 참조가 남았는지 여기서 드러남). - [ ] 1단계 삭제 후 **공용 브라우저로 A07 회원가입·A09 보안 화면·B01 대시보드 진입**을 실제 클릭해 화면이 그대로인지 확인. - [ ] 5단계 공통화 후에는 해당 화면의 수치를 **공통화 전후로 대조**(옹벽 `baseWidth`, 유토곡선 스크롤, 종횡단 재생성 결과).