# 보험유니버스 — 서비스 전반 문제점/필요사항 메타정보 수집

**작성일**: 2026-08-07
**목적**: 보안·정책·서비스수준·비즈니스모델·구성·UI/UX·개발속도·환경·운영·수익·관리포인트·권한·기획 전 축에 걸쳐, 지금 이 서비스가 안고 있는 문제와 필요사항을 **저장소 실측 근거와 함께** 목록화한다. 판단·우선순위는 붙이되, 해결안 설계는 이 문서 범위 밖이다.
**성격**: 사전 조사(meta). 여기 있는 항목은 "확인된 사실"과 "확인 필요"를 구분해 표기했다.

## 0. 조사 범위 · 기준점

| 저장소 | 브랜치(로컬 HEAD) | HEAD | 역할 |
|---|---|---|---|
| `insuniverse-server` | `stg` | `c7597fc7` (2026-08-06) | NestJS 10 API + 스케줄러 |
| `insuniverse-admin` | `prod` | `85fb96a0` (2026-08-07) | 관리자 콘솔 (React+Vite, FSD) |
| `insuniverse-site` | `stg` | `b9a90a42` (2026-08-06) | 사용자 웹/앱 (React+Vite, FSD) |
| `insuniverse-temp` | — | — | 위 3개를 묶은 submodule umbrella + `docs/_meta` 인덱스 |

- 조사 방법: 저장소 정적 분석(grep/파일 실측/git 메타), 기존 산출물 재사용(`insuniverse-temp/docs/_meta/findings/*`, `insuniverse-admin/planning/서비스정책_*.md`, `.claude/_meta/monitoring-alert-meta.md`)
- **조사 한계 (중요)**: 아래는 저장소 밖이라 이 조사로 확정할 수 없다 —
  AWS 콘솔 설정(EventBridge 규칙, CloudWatch 알람, ALB/WAF/CloudFront 룰, IAM 정책),
  S3 의 실제 `prod.env` 값, GitHub 브랜치 보호 규칙, DB 실 데이터 규모, 실 트래픽·매출 수치.
  이 문서에서 그 영역은 전부 **"확인 필요"** 로 남겼다.

---

## 1. 시스템 스냅샷 (실측)

### 1.1 규모

| 항목 | 값 | 산출 |
|---|---|---|
| 소스 파일 / 라인 (server) | 731 / 113,960 | `.ts .js` (node_modules·dist 제외) |
| 소스 파일 / 라인 (admin) | 631 / 110,625 | `.ts .tsx` 포함 |
| 소스 파일 / 라인 (site) | 1,066 / 160,226 | 〃 |
| **합계** | **2,428 / 384,811** | |
| 서버 비즈니스 모듈 | 45개 | `apps/api/src/modules/*` |
| 공유 라이브러리 | 20개 | `libs/*` |
| HTTP 컨트롤러 | 114개 | `*.controller.ts` |
| 엔드포인트 데코레이터 | 652개 | `@Get/@Post/@Put/@Patch/@Delete` |
| DB 테이블 | **155개** | `drizzle/schema.ts` (2,957행) — `tn_` 100 · `tt_` 30 · `tc_` 14 · `th_` 7 · `log_` 4 |
| 관리자 화면 | **242개** | `insuniverse-admin/src/pages/**/*Page.tsx` |
| 사용자 화면 | 98개 | `insuniverse-site/front/src/pages/**/*Page.tsx` |
| 스케줄러 | 17종 | 독립 진입점 16 + in-process `@Cron` 1 |
| 외부 벤더 연동 | 13종 | CODEF/COOCON/OCTOVER/HYPHEN/inhouse, TOSS/SMARTRO, ALIGO, MOK, VFAX, FCM, YouTube, SMTP |

### 1.2 개발 인력·속도

- 누적 커밋: server 2,601 · admin 1,158 · site 2,463 (**합 6,222**)
- 기여자: server 13명 · admin 10명 · site 13명 (중복 포함, 고유 인물 ≈ 10명 내외)
- 최근 12주 server 커밋: 33 / 21 / 82 / 97 / 19 / 49 / 70 / 34 / 15 / 27 / 19 / 14 (주별)
  → **주 14~97커밋, 편차 7배**. 최근 4주(34→15→27→19→14)는 뚜렷한 하락 추세
- 최근 500커밋 중 **머지 커밋 427건(85%)** — 브랜치 난립 + 잦은 통합
- 원격 브랜치: server 24 · admin 17 · site 24 (`forge/`, `test/clean-*`, `tempp`, `feautre/toss-fix`(오타) 등 정리 안 된 실험 브랜치 다수)

### 1.3 코드 위생 지표

| 지표 | server | admin | site |
|---|---|---|---|
| TODO/FIXME/HACK | 35 | 14 | 11 |
| `any` 사용 | 632 | 572 | 245 |
| `console.*` | 105 | 87 | **208** |
| `@ts-ignore`/`eslint-disable` | 0 | 9 | 11 |
| 테스트 파일 | 39 (`*.spec.ts`) | **0** | **0** (vitest 설치만 되어 있음) |
| `dangerouslySetInnerHTML` | — | 3 | 9 |
| `aria-*`/`role=` 총 등장 | — | — | **22** (tsx 450개 전체에서) |

### 1.4 최대 파일 (god file 후보)

| 저장소 | 파일 | 크기 |
|---|---|---|
| server | `modules/disease/disease.repository.ts` | 139KB |
| server | `modules/money/money.service.ts` | 115KB |
| server | `modules/fc/agency/fc-agency.service.ts` | 94KB |
| site | `features/agreementForm/constants/alimtalkAgreementContents.const.tsx` | 123KB |
| site | `pages/invoices/FaxSendPage.tsx` | 63KB |
| admin | `pages/Admin/Subscription/TreatMonitor/TreatMonitorPage.tsx` | 66KB |
| admin | `shared/helpers/common.helper.ts` | 52KB |

---

## 2. 축별 문제점 / 필요사항

심각도: **최상**(즉시) / **상** / **중** / **낮**
상태: `확인` = 저장소 근거로 확정 / `추정` = 근거는 있으나 저장소 밖 확인 필요

### A. 보안

| # | 문제 | 근거 | 영향 | 심각도 | 상태 |
|---|---|---|---|---|---|
| **A1** | **운영 본인인증 키 파일이 git 에 커밋돼 있다.** `mok_keyInfo_prod.dat`(1,728B, 바이너리)가 저장소 루트에 추적 상태. 커밋 `e6769494 chore: 운영용 mok info 추가`. `.env`(`MOK_PASSWORD`)와 짝을 이루는 드림시큐리티 본인인증 키 재료 | `insuniverse-server/mok_keyInfo_prod.dat`, `mok_keyInfo_dev.dat` · `git log -- mok_keyInfo_prod.dat` | 저장소 접근 권한자 = 운영 본인인증 키 접근자. 히스토리에 남아 파일 삭제만으론 회수 불가(재발급 필요) | **최상** | 확인 |
| **A2** | **전역 인증 가드가 없다.** `app.module.ts` 에 등록된 전역 provider 는 `APP_PIPE` 뿐. 인증은 컨트롤러가 `@UseGuards` 를 **직접 붙여야만** 걸린다 = fail-open 설계. 가드가 하나도 없는 컨트롤러 11개 존재 | `apps/api/src/app.module.ts:188` (APP_PIPE 단독) · 가드 없는 컨트롤러: `advertisement`, `agency/terms`, `institution-block`, `medical`, `money-public`, `push`, `referral`, `auth/*`, `app.controller` | 신규 엔드포인트가 가드를 빠뜨리면 조용히 공개된다. 리뷰에만 의존 | **최상** | 확인 |
| **A3** | **`@Roles` 미지정 = 무조건 통과.** `RolesGuard` 가 메타데이터 없으면 `return true`. 엔드포인트 652개 중 `@Roles` 선언은 137개(21%) | `modules/auth/admin/roles.guard.ts:21-22` | 인증된 하위 역할(sales/corp)이 역할 표기 없는 관리자 엔드포인트에 도달 가능 → 수평·수직 권한 상승 surface | **최상** | 확인 |
| **A4** | **운영에서 Swagger 가 열려 있을 가능성.** `main.ts:27` 은 `NODE_ENV !== 'production'` 일 때 `/swagger` 를 마운트한다. 그런데 코드 주석이 **"prod 의 NODE_ENV 가 'dev'"** 라고 명시 | `apps/api/src/main.ts:27` · `apps/api/src/swagger.ts:13` · `apps/api/src/helpers/cookie.helper.ts:12` (주석) | 전체 API 스펙·DTO 구조가 외부 노출. ALB/CloudFront 에서 차단 중인지 확인 필요 | **최상** | 추정 |
| **A5** | **인증 우회 경로가 코드에 존재.** `AdminJwtAuthGuard` 는 토큰 검증 실패 시 `isDevSwaggerRequest()` 면 관리자 `admId:19 / rsteam` 을 **강제 주입**하고 통과시킨다. 조건 = `NODE_ENV==='dev'` + referer 에 `swagger` 포함 + `x-forwarded-for` 가 하드코딩 IP `211.48.209.5` 와 일치. A4 와 같은 이유로 **prod 에서 이 분기가 살아 있을 수 있다** | `modules/auth/admin/jwt.guard.ts:42-45` · `helpers/request.helper.ts:3,18-24` | 조건이 맞으면 무토큰 관리자 접근. 사무실 IP 가 소스에 하드코딩된 것 자체도 문제 | **최상** | 추정 |
| **A6** | **admin-view IDOR 차단이 기본 OFF.** `AdminViewTokenGuard` 는 `ADMIN_VIEW_TOKEN_ENFORCE !== 'true'` 면 **미검증 요청도 통과**시키고 경고 로그만 남긴다(무중단 롤아웃용 게이트) | `modules/admin-view-token/admin-view-token.guard.ts:49-55` | prod env 에 플래그가 안 켜져 있으면 분석결과(의료 PII) IDOR 이 여전히 열려 있음 | **최상** | 추정 |
| **A7** | **사용자 프런트 번들에 AES 키가 그대로 실린다.** `vite.config.constants.ts` 의 `define` 이 `"process.env": env` 로 **env 전체를 인라인**하고, 코드는 `process.env.REACT_APP_PRIVATE_KEY \|\| "RSTEAM"` 로 localStorage 상태(user/analysis/invoice/payment/subscribe)를 AES 암복호화한다. 키 미주입 시 **하드코딩 문자열 `"RSTEAM"`** 사용 | `insuniverse-site/front/vite.config.constants.ts:61-66` · `front/src/shared/api/index.ts:40` · `front/src/entities/{user,analysis,invoice,payment,subscribe,dream,alimtalk}/model/store.ts` | 클라이언트 암호화가 사실상 무의미. **admin 저장소는 같은 문제를 이미 고쳤는데(`SENSITIVE_ENV_KEYS`) site 에는 미적용** — 보안 수정이 저장소별로 비대칭 | **상** | 확인 |
| **A8** | **site 프로덕션 빌드에서 console 이 제거되지 않는다.** admin 은 `esbuild: { drop: ["console","debugger"] }` 를 넣었으나 site 의 `vite.config.ts` 에는 없다. site 의 `console.*` 은 **208건** | `insuniverse-admin/vite.config.ts:69` (있음) vs `insuniverse-site/front/vite.config.ts` (없음) | 회원 PII·분석 데이터가 브라우저 콘솔/확장/세션리플레이에 노출 (admin 이 이미 같은 이유로 수정한 문제) | **상** | 확인 |
| **A9** | **전역 입력 검증 파이프가 주석 처리돼 있다.** `main.ts:21` 의 `app.useGlobalPipes(new ValidationPipe(...))` 가 주석. 대신 `APP_PIPE: ClassValidatorPipe` 커스텀 구현으로 대체돼 있음 → 검증 강도/whitelist 여부 재확인 필요 | `apps/api/src/main.ts:21` · `app.module.ts:188` | 커스텀 파이프가 `forbidNonWhitelisted`/`whitelist` 를 안 하면 mass-assignment 여지 | **중** | 확인(동작 재확인 필요) |
| **A10** | **보안 미들웨어 전무.** `helmet`, `express-rate-limit`, `@nestjs/throttler`, `csurf`, `compression` 모두 미설치·미사용. 레이트리밋은 진료 인증 1곳(`CertifyRateLimitGuard`)만, 그마저 `RATE_LIMIT_CERTIFY_PER_MIN>0` 일 때만 | `insuniverse-server/package.json` (해당 의존성 0건) · `modules/treat/certify-rate-limit.guard.ts` | 로그인 brute-force, 스크래핑, 헤더 기반 공격에 무방비. 보안 헤더(HSTS/CSP/X-Frame-Options) 없음 | **상** | 확인 |
| **A11** | **CORS 가 조용히 비활성화될 수 있다.** `setupCors` 는 `allowOrigins` 가 비면 `return` 하고 `enableCors` 를 아예 호출하지 않는다 | `apps/api/src/main.ts:44-47` | env 오설정 시 동작 변화가 로그 없이 발생 | **중** | 확인 |
| **A12** | **JWT 토큰이 12시간 고정, 무효화 수단 없음.** 액세스 토큰 12시간(`_aT`/`_aaT`), 서버측 세션/블랙리스트 없음. 관리자 계정에 **"정지" 상태가 없어 삭제만 가능** | `helpers/cookie.helper.ts:25` · `planning/서비스정책_관리자.md:71` | 계정 탈취·퇴사 시 즉시 차단 수단이 없다(최대 12시간 유효) | **상** | 확인 |
| **A13** | **관리자 IP 허용목록이 저장만 되고 강제되지 않는다.** `allow-ip` 모듈은 CRUD 서비스/레포지토리뿐, 미들웨어·가드로 연결된 코드 0건 | `modules/allow-ip/*` (guard/middleware 없음) · `planning/서비스정책_관리자.md:57-60` | 관리자 콘솔이 인터넷 전 구간에 열려 있는 상태로 운영. 화면은 "IP 제한 중"처럼 보임 = **오인 위험** | **상** | 확인 |
| **A14** | **원시 SQL 사용량이 크다.** `sql\`` 템플릿이 50개 파일 666건. drizzle 템플릿은 기본적으로 파라미터 바인딩이지만, 정렬/컬럼명/동적 절 조립 구간은 개별 감사 필요 | `apps/api/src` 전역 (`disease.repository.ts` 214건, `analyze.repository.ts` 22건 등) | 동적 식별자 삽입 지점이 있으면 SQL injection | **중** | 확인(개별 감사 필요) |
| **A15** | **의존성 취약점 관리 체계 없음.** dependabot 설정 0건, CI 에 `npm audit`/SCA/이미지 스캔 단계 0건. 프런트는 `jquery`(소스 사용 0건 = 죽은 의존성), `react-bootstrap@1`(React 16/17 세대), `zustand-persist`, `moment`+`moment-timezone`+`dayjs` 동시 탑재 | `.github/workflows/*` · `package.json` × 3 | 알려진 CVE 무인지 상태로 장기 운영 | **상** | 확인 |

### B. 개인정보 · 컴플라이언스 (정책/법)

| # | 문제 | 근거 | 영향 | 심각도 | 상태 |
|---|---|---|---|---|---|
| **B1** | **환불 수수료 안내와 코드가 다르다.** 안내 의도는 "7일 이내 0%", 코드는 **5% 단일 적용** | `planning/서비스정책_사용자.md:149` · `서비스정책_관리자.md:272` | 전자상거래법상 표시·광고와 실제 조건 불일치. 소액이라도 **분쟁·환불 민원 직결**. 금전 손해가 사용자에게 발생 | **최상** | 확인(정책 재확인 필요) |
| **B2** | **머니 환불요청 취소 시 차감 머니 복구 로직 미구현** | `planning/서비스정책_관리자.md:273` | 사용자 자산 유실. 수동 보정 운영 부담 | **상** | 확인 |
| **B3** | **일부 사용자 청구서 엔드포인트에 인증 가드 미적용(공개)** | `planning/서비스정책_관리자.md:276` | 보험금 청구서 = 민감정보. 무인증 접근 시 개인정보 유출 사고 | **최상** | 확인(현 HEAD 재검증 필요) |
| **B4** | **처리하는 정보 등급이 매우 높다.** 심평원 진료내역·처방·질병코드·자동차보험 = **민감정보(건강정보)**. 본인인증 정보, 결제 빌링키까지 취급 | `libs/codef`, `tt_*` 테이블 30종, `libs/pg` | 유출 시 개인정보보호법상 가중 처벌 대상. 위 A1·A6·A7·B3 의 파급이 일반 서비스보다 훨씬 크다 | — | 확인 |
| **B5** | **암호화 키 관리 체계 부재.** AES 키·IV 가 env 평문(`AES_SECRET`/`AES_IV`), KMS·Secrets Manager 사용 흔적 없음. 키 로테이션 절차 없음 | `apps/api/src/config/configuration.ts:92-95` | 키 유출 시 저장된 PII 전량 복호화 가능. 로테이션 불가 구조 | **상** | 확인 |
| **B6** | **접근 감사 로그(audit log) 체계가 없다.** 관리자가 누가·언제·누구의 의료데이터를 조회했는지 남기는 공통 기제 없음(머니 일부만 `0017_money_actor_audit.sql`) | `drizzle/*.sql` 전수 · 서버 전역 | 개인정보 접근기록 보관 의무 대응 곤란. 내부자 유출 추적 불가 | **상** | 확인 |
| **B7** | **개인정보 보관/삭제 기간이 문서·코드 여러 곳에 흩어져 있다.** 진료원본 30일 / 분석결과 30일 / 청구서 첨부 30일 / 연락처 해지 후 1년 / 탈퇴 후 1년 물리삭제 / 계약·결제 5년 / 분쟁 3년 / 본인확인 6개월 / 방문기록 3개월 — 정본 정의 위치가 단일하지 않음 | `planning/서비스정책_사용자.md:65-68,240-247,272` | 어느 하나가 어긋나도 인지 수단이 없다. 삭제 스케줄러 실패 = 법적 위반 | **상** | 확인 |
| **B8** | 약관 시행일 표기가 서로 다르다. 가입 시 이용약관 "적용 2025-01-01" vs 정적 게시 이용약관 "시행 2025-02-10" | `planning/서비스정책_사용자.md:57,65` | 어느 버전에 동의받았는지 입증 곤란 | **중** | 확인 |

### C. 권한 / 접근통제 (기능 모델)

| # | 문제 | 근거 | 영향 | 심각도 |
|---|---|---|---|---|
| **C1** | **권한 모델이 "메뉴 접근 가능/불가" 이진**이다. 읽기/쓰기/삭제/엑셀다운로드 구분이 없다 | `planning/서비스정책_관리자.md:46` | "조회만 시키고 싶은" 요구를 구조적으로 못 받는다. 신규 역할 요구가 올 때마다 코드 분기 증가 | **상** |
| **C2** | **영업대리점·기업관리자 메뉴가 프런트에 하드코딩**돼 있다. DB 동적 메뉴는 통합관리자만 | `insuniverse-admin/src/features/authority/constants/menu.ts` (297행, 주석에 "하드코딩 유지" 명시) | 권한 변경 = 프런트 재배포. 서버 권한과 화면 권한이 두 곳에서 따로 관리 → 드리프트 | **상** |
| **C3** | 메뉴코드가 축을 가로질러 중복된다. `MEM002`·`POP001`·`SUB001/002/004` 가 도메인상태코드이면서 동시에 메뉴코드 | `docs/_meta/findings/11-index-code.md` 발견 10 | 코드값만으로 조인·판정하면 오작동 | **중** |
| **C4** | 관리자 화면 242개 대비 권한 그룹 설계 문서가 없다. 신규 화면 추가 시 어느 권한에 넣을지 규칙 부재 | `insuniverse-admin/src/pages` 실측 · `planning/` 내 권한 매트릭스 문서 없음 | 권한 부여가 담당자 기억에 의존 | **상** |

### D. 서비스 수준(SLA) · 운영

> 이 축은 `.claude/_meta/monitoring-alert-meta.md` 에 이미 상세 조사돼 있다. 여기서는 **미해결 항목만** 요약 인용한다.

| # | 문제 | 근거 | 심각도 |
|---|---|---|---|
| **D1** | API 500 에러가 아무 데도 통보되지 않는다 (`logger.error` 만) | `fliters/all-exception.filter.ts:34` | **최상** |
| **D2** | 정기결제 실패가 `logger.log`(error 아님)로 삼켜지고, 스케줄러는 항상 `process.exit(0)` | `schedules/regular-subscription.schedule.ts:37-41` | **최상 (매출 직결)** |
| **D3** | 스케줄러 미실행/중도 사망을 인지할 방법이 없다 (EventBridge→ECS RunTask 는 기본 알림 없음) | 〃 meta 문서 B3 | **최상** |
| **D4** | APM·에러추적 도구 전무 (Sentry/Datadog/NewRelic 흔적 0건) | 전 저장소 grep | **상** |
| **D5** | 헬스체크가 `return 'OK'` 상수 — DB/Redis/벤더 상태 미반영 | `app.controller.ts:9` | **중** |
| **D6** | 프런트 런타임 에러 미수집 (`ErrorBoundary` 는 화면 폴백만) | `insuniverse-site/front/src/shared/ui/ErrorBoundary.tsx` | **중** |
| **D7** | 모니터링이 **진료(treat) 도메인에만** 존재. 결제·정산·팩스·알림톡·본인인증은 무감시 | `modules/treat/monitor/*` 만 존재 | **상** |
| **D8** | **SLA·SLO 정의 자체가 없다.** 가용성 목표, 분석 완료 소요 목표, 장애 등급/에스컬레이션/온콜 문서 0건 | 전 저장소 검색 | **상** |
| **D9** | 진료 수집이 외부 벤더 5개 풀에 100% 의존. 벤더 동시 장애 = 핵심 기능 정지, 대체 수단 없음 | `TREAT_POOL` 구성 | **상** |

### E. 개발 프로세스 · 품질 · 개발속도

| # | 문제 | 근거 | 영향 | 심각도 |
|---|---|---|---|---|
| **E1** | **프런트엔드 타입 체크가 실제로는 동작하지 않는다.** `tsconfig.json` 이 `{"files": [], "references": [tsconfig.node.json]}` 라서 `tsc`(비-`--build`)는 **0개 파일을 검사하고 exit 0** 한다. 즉 `npm run build` 의 `tsc &&`, `npm run type-check` 모두 no-op. **실행 검증함**: `npx tsc --noEmit -p tsconfig.json --listFiles` → 출력 0줄, exit 0 | `insuniverse-admin/tsconfig.json`, `package.json:build,type-check` · `insuniverse-site/front/tsconfig.json` | admin 110K + site 160K = **27만 라인이 타입 검증 없이 배포**되고 있다. 런타임 타입 오류가 QA/운영에서만 발견됨 | **최상** |
| **E2** | **CI 에 품질 게이트가 하나도 없다.** 3개 저장소 workflow 전수에 `lint`·`test`·`type-check`·보안스캔 단계 0건. 서버는 dockerfile 내부 `nest build` 의 타입체크가 유일한 검증 | `.github/workflows/*.yml` × 11 | 깨진 코드가 push 만으로 운영까지 간다 | **최상** |
| **E3** | **prod 브랜치 push = 즉시 운영 배포.** 승인 게이트·수동 approve·카나리 없음. 롤백 절차 문서 없음 | `api.yml:1-6`, `prod.yml:1-4` | 잘못된 커밋 1개가 곧바로 매출·의료데이터 서비스에 반영 | **최상** |
| **E4** | **프런트 테스트 0건.** admin 은 테스트 프레임워크 자체가 없고, site 는 vitest·testing-library 를 설치만 하고 테스트 파일 0개 | 실측 | 화면 242+98개 회귀 검증이 전부 수동 | **상** |
| **E5** | 서버 테스트 39개는 **`treat`/결제 등 최근 위험 영역에 편중**. 155테이블·45모듈 대비 커버리지 낮음. 커버리지 측정·임계 설정 없음 | `jest.config.js` (coverageThreshold 없음) | 리팩터링 두려움 → 기술부채 누적 가속 | **상** |
| **E6** | **CI 가 `npm ci` 가 아니라 `npm install`** 을 쓴다(site/admin). lockfile 이 강제되지 않아 빌드 재현성이 없다 | `insuniverse-site/.github/workflows/prod.yml:116` | 같은 커밋이 다른 결과물을 낼 수 있다 | **상** |
| **E7** | GitHub Actions 버전이 낡았다. `actions/checkout@v2`, `actions/setup-node@v2` (Node16 런타임, deprecated) | `insuniverse-site/.github/workflows/*.yml:26,92` | 언젠가 갑자기 CI 정지 | **중** |
| **E8** | **CODEOWNERS·PR 템플릿·이슈 템플릿·dependabot 전부 없다.** 리뷰 책임자가 코드로 정의되지 않음 | `.github/` 전수 | 리뷰 누락이 구조적으로 허용됨 | **상** |
| **E9** | 최근 500커밋 중 머지 85%, 원격 브랜치 65개(3저장소 합) 중 `forge/`·`test/clean-*`·`tempp`·`feautre/`(오타) 등 미정리 다수 | git 실측 | 어느 브랜치가 살아 있는지 판단 비용. 실수로 낡은 브랜치 배포 위험 | **중** |
| **E10** | **`any` 1,449건 / `console` 400건.** 서버는 `noImplicitAny: false` 로 명시적 완화 | `tsconfig.json:14` (server) | 타입 안전성이 명목상만 존재 | **중** |
| **E11** | god file 다수 (`disease.repository.ts` 139KB, `money.service.ts` 115KB). 변경 시 영향범위 예측 불가 | 실측 | 신규 인력 온보딩·병행 작업 비용 급증 | **상** |
| **E12** | 근접 복제 파일 존재. `B2cAnalysisDetailPage.tsx`(39KB) vs `B2cAnalysisDetailPageForMember.tsx`(38KB), admin `pages/Admin/User/Corpfc/CorpfcPage.tsx`(33KB) vs `pages/Corp/User/Corpfc/CorpfcPage.tsx`(30KB) | 실측 | 한쪽만 고치는 버그가 구조적으로 발생 | **상** |

### F. 환경 · 인프라

| # | 문제 | 근거 | 영향 | 심각도 |
|---|---|---|---|---|
| **F1** | **IaC 가 전혀 없다.** `.tf`/`cdk.json`/`template.yaml`/`serverless.yml` 0건. ECS·EventBridge·CloudWatch·ALB·IAM 전부 콘솔 수작업 | 전 디렉터리 검색 | 환경 재현·감사·리뷰 불가. 담당자 이탈 시 복구 곤란. 변경 이력 없음 | **최상** |
| **F2** | **prod 의 `NODE_ENV` 가 `'dev'` 로 추정된다.** 코드 주석이 명시. 이 하나로 A4(Swagger 노출)·A5(인증 우회 분기)가 동시에 활성화된다 | `helpers/cookie.helper.ts:12` | 환경 판별이 신뢰 불가 → 환경별 동작 분기 전체가 위험 | **최상** |
| **F3** | **CI 가 결제/한도 문제로 멈춘 전례가 있고, 그 우회로가 로컬 수동 배포 스크립트다** | `insuniverse-server/deploy/README.md:3-4` | 배포 경로가 이중화돼 있으나 로컬 경로는 감사·기록이 남지 않음 | **상** |
| **F4** | **IAM 프로파일 이름이 실제 권한과 다르다.** `insuniverse-readonly` 가 "이름과 달리 쓰기 권한 있음"(ECR push/ECS update) | `deploy/README.md:15` | 최소권한 위배 + 운영자 오인 유발 | **상** |
| **F5** | 환경이 3종(dev/stg/prod)인데 **dev 는 다른 AWS 계정**(RSTEAM)이고 stg/prod 는 INPAS 계정 | `api.yml:14` | 권한·비용·네트워크 정책이 계정별로 갈림. dev↔stg 재현성 낮음 | **중** |
| **F6** | env 관리가 S3 단일 파일(`s3://insuniverse-<env>-envs/api/<env>.env`). 버전관리·변경이력·접근감사 없음, 로컬 `.env` 와 키 이름이 어긋난 사례 존재(`GOOGLE_CHAT_WEBHOOK_URL` vs `CHATBOT_WEBHOOK_URL`) | `api.yml:12-13` · `configuration.ts:141` vs 로컬 `.env` | 배포 후에야 설정 오류를 알게 됨 | **상** |
| **F7** | 마이그레이션 번호가 중복된다. `0006` × 2, `0009` × 2, `0024` × 2, `0027` × 2. 게다가 `drizzle/`(28개)과 `migrations/`(별도 번호) 두 디렉터리로 분리 | `insuniverse-server/drizzle/*.sql`, `migrations/*` | 적용 순서가 파일명으로 결정되지 않는다 | **상** |
| **F8** | **스키마 변경이 수동 절차다.** README 가 `db:push` 금지 + "ALTER TABLE SQL 직접 작성 → 담당자 확인 후 DB에 실행" 을 규정. 자동 마이그레이션 러너 없음 | `insuniverse-server/README.md:199-208` | 코드 배포와 스키마 상태가 원자적으로 묶이지 않음. 롤백 시 스키마 불일치 | **상** |
| **F9** | 프로시저가 DB에 존재하는데 저장소에 정본이 없다(`db:push` 금지 사유가 "프로시저 손실") | `README.md:199-201` | DB 로직 일부가 버전관리 밖에 있다 | **상** |
| **F10** | Windows 전용 분기가 프로덕션 진입점에 있다 (`process.platform === 'win32'` → `setupKernel()`) | `apps/api/src/main.ts:28-30` | 개발환경 코드가 운영 경로에 섞임 | **낮** |
| **F11** | `koffi`(네이티브 FFI)가 devDependency 인데 win32 커널 셋업에 쓰인다 → 로컬/운영 동작 차이 | `package.json` devDeps · `main.ts:29` | 로컬에서만 재현되는 문제 발생 여지 | **낮** |

### G. 구성 / 아키텍처

| # | 문제 | 근거 | 영향 | 심각도 |
|---|---|---|---|---|
| **G1** | **저장소 3분할인데 계약(타입/에러코드/상태코드)이 공유되지 않는다.** 에러코드는 코드값이 유일하지 않고(같은 `E0202` 가 4개 의미), 심볼 이름도 유일하지 않다(`UNAUTHORIZED` 가 E0601/E0001 두 개) | `docs/_meta/findings/11-index-code.md` 발견 1·5 | 프런트/서버가 같은 코드로 다른 판단을 한다. 문구도 불일치(서버 "중복되는 계약이 존재합니다" vs 프런트 "계약일이 중복되었습니다") | **상** |
| **G2** | 프런트가 코드를 **소비만** 한다. site 의 코드 선언은 1건뿐, 심볼 없는 코드 등장 1,870건(server 606·site 722·admin 542) | 〃 발견 12 | 매직 스트링 산재. 서버 변경 시 프런트 파급 추적 불가 | **상** |
| **G3** | 스케줄 발화 주기(cron)가 **저장소 밖(EventBridge)** 에만 있다. 16/16 파일에 cron 표현 0건 | `docs/_meta/findings/12-index-runtime.md` F-02 | "언제 무엇이 도는지" 를 코드로 알 수 없다. 리뷰·복구 불가 | **상** |
| **G4** | `samsung-s2-report` 스케줄러가 소스에는 있으나 dockerfile CMD·CI TYPES 양쪽 모두에 없다 = 배포되지 않는 코드 | 〃 F-01 | 의도 불명. 죽은 코드이거나 누락된 배포 | **중** |
| **G5** | 파일명 오타가 배포 경로까지 전파. `delete-fc.schdule.ts`(schedule 아님) ↔ dockerfile 도 같은 오타 | 〃 F-04 | 지금은 맞아떨어져 동작. 한쪽만 고치면 즉시 장애 | **낮** |
| **G6** | `push.scheduler.ts` 만 API 프로세스 안에서 `@Cron` 으로 돈다(전체 중 유일) | 〃 F-05 | 스케줄 기제가 두 종류. API 스케일아웃 시 중복 실행 위험 | **중** |
| **G7** | **죽은 코드 다수.** `libs/chat` (어디에도 주입 안 됨), `refund` 모듈(컨트롤러 전체 주석), `jquery` 의존성(소스 사용 0건), `graphql`/`@graphql-codegen`(REST 서비스인데 설치됨) | `libs/chat/src/chat.service.ts` · `planning/서비스정책_관리자.md:274` · package.json × 2 | 번들·빌드시간·인지부하 낭비. "이거 쓰나요?" 질문이 반복 발생 | **중** |
| **G8** | B2C 테이블이 정회원 테이블의 **프리픽스만 바꾼 복제 구조**(`tn_order_detail`↔`tn_b2c_order_detail`, `tt_treat_basic`↔`tt_b2c_treat_basic` …) | `insuniverse-server/README.md:170-178` | 정책 변경 시 항상 두 벌 수정. 155테이블 중 상당수가 이 복제 | **상** |
| **G9** | 사용자 사이트에 **레거시 정적 퍼블리싱(`publish/`)** 이 React 앱(`front/`)과 함께 남아 있다 | `insuniverse-site/publish/*.html` 다수 | 어느 쪽이 정본인지 불명. 잘못된 화면을 수정하는 사고 | **중** |
| **G10** | site 의 package name 이 `matam_front_admin` — 이전 프로젝트 잔재 | `insuniverse-site/front/package.json:2` | 프로젝트 정체성 혼동 | **낮** |

### H. UI / UX

| # | 문제 | 근거 | 영향 | 심각도 |
|---|---|---|---|---|
| **H1** | **접근성이 사실상 없다.** site tsx 450개에서 `aria-*`/`role=` 총 22건. i18n 라이브러리 0건 | 실측 | 스크린리더 사용 불가. 공공/기업 고객 요구 시 대응 불가 | **상** |
| **H2** | **디자인 시스템·토큰이 없다.** admin 은 AdminLTE + Bootstrap4 + `react-bootstrap@1`(React16/17 세대) 기반, site 는 별도 퍼블리싱. 공통 컴포넌트 라이브러리 없음 | `insuniverse-admin/public/_statics/adminLTE/*` · package.json | 화면 242+98개의 일관성이 개인 역량에 의존. 신규 화면 제작 시간 증가 | **상** |
| **H3** | 위젯 파일이 비대하다. `widgets/AddDetail.tsx` 47KB, `widgets/SearchForm.tsx` 40KB | 실측 | 화면 하나 바꾸려다 전 화면이 깨진다 | **상** |
| **H4** | 대형 폼/상세 화면이 단일 파일에 몰려 있다(`FaxSendPage.tsx` 63KB, `TreatMonitorPage.tsx` 66KB) | 실측 | 렌더 성능·유지보수 동시 악화 | **중** |
| **H5** | **에러 UX 가 코드 불일치 위에 서 있다.** G1(코드값 1:N) 때문에 같은 에러코드가 화면마다 다른 문구로 뜬다 | `findings/11-index-code.md` 발견 4 | 사용자·CS 혼선 | **상** |
| **H6** | 앱 브릿지(`REACT_APP_BRIDGE_NAME`) 기반 하이브리드인데 앱 버전 분기·최소지원버전 정책 문서 없음(`origin/feature/app-version-check` 브랜치만 존재) | `front/.env` · 브랜치 목록 | 구버전 앱에서 신규 API 호출 실패 시 대응 불가 | **중** |
| **H7** | 대량 엑셀 다운로드가 동기 스트리밍이라 요청 타임아웃을 30분으로 늘려 대응하고 있다(10만행+) | `apps/api/src/main.ts:32-35` | 커넥션 점유·재시도 불가·사용자 대기. 비동기 잡 큐로 갈 시점 | **중** |

### I. 비즈니스모델 / 수익

> 아래는 **코드가 표현하는 수익 구조**다. 실제 매출·비중은 저장소 밖이라 확인 필요.

**수익원 (실측 5종)**

| # | 수익원 | 과금 방식 | 근거 |
|---|---|---|---|
| 1 | FC 구독 (월/연/일) | TOSS 빌링키 정기결제, 상품별 분석 쿼터 부여 | `modules/subscribe`, `schedules/regular-subscription` |
| 2 | 기업(대리점) 구독 | 기업FC 계정 단위, 후불/선불/무상 3형 | `schedules/regular-agency-subscription`, `0024_order_billing_type.sql` |
| 3 | 머니(포인트) 충전 | SMARTRO 일반결제, 최소 1만원, 환불수수료 5% | `modules/money` (115KB) |
| 4 | 팩스 발송 | 머니 장당 차감 | `modules/fax`, `libs/vfax` |
| 5 | 고객사(B2B API) | 분석 건당 계약 단가 × 건수 정산 | `modules/client`, `schedules/settlement-client` |

**구조적 문제**

| # | 문제 | 근거 | 심각도 |
|---|---|---|---|
| **I1** | **원가가 매출과 분리 추적되지 않는다.** 진료 수집 벤더 단가(`TREAT_POOL` 의 `unitCost`)는 분산 라우팅용이고, "이 구독 1건의 실제 벤더 비용"을 집계하는 지표가 없다 | `configuration.ts:32-45` · 통계 모듈에 원가 항목 없음 | **상** — 분석 1건당 마진을 모름 |
| **I2** | **정산이 "건수 × 단가 합계" 단일 방식**. 수수료율·최소보장·구간요금 개념 없음 | `planning/서비스정책_관리자.md:146` | **중** — 신규 요금제 요구 시 코드 개조 필요 |
| **I3** | **구독 주기 필드를 관리자 UI 에서 수정할 수 없다** (생성/수정 DTO에서 제외) | 〃:109 | **중** — 요금제 실험 속도 제약 |
| **I4** | **교육(강의)이 전면 무료**, 유료 게이트 없음 | 〃:275, `서비스정책_사용자.md:153` | **중** — 콘텐츠 투자 대비 수익화 경로 부재 |
| **I5** | **무료체험 남용 방지가 "연락처 1년 보유" 에만 의존**. 탈퇴 후 1년 뒤 재가입 시 체험 재부여 | `서비스정책_사용자.md:99,111` | **중** — 체험 반복 이용 여지 |
| **I6** | **결제 실패 리커버리가 약하다.** 실패 시 알림·재시도·던닝(dunning) 플로우가 스케줄러 로그로만 남고 통보 없음(D2) | `schedules/regular-subscription.schedule.ts:37-41` | **최상** — 조용한 이탈 = 조용한 매출 감소 |
| **I7** | **B2C 분석이 FC 쿼터를 차감하지 않는 별도 체계**인데 그 수익 모델이 코드에서 불명확 | `서비스정책_사용자.md:221` | **중** — 확인 필요 |
| **I8** | 벤더 비용 급증 경보가 없다(모니터링 meta 의 C5 미구현) | `.claude/_meta/monitoring-alert-meta.md` §4 C5 | **상** — 원가가 매출을 넘어도 즉시 인지 불가 |

### J. 기획 / 문서

| # | 문제 | 근거 | 심각도 |
|---|---|---|---|
| **J1** | **정본 문서가 흩어져 있다.** 서비스정책 2종은 `insuniverse-admin/planning/`, 기술 인덱스는 `insuniverse-temp/docs/_meta/`, 운영 조사는 `.claude/_meta/`, 나머지는 **노션**(`README.md:131,264` 이 노션을 참조) | 실측 | **상** — "무엇이 정본인가" 를 매번 물어야 함 |
| **J2** | **서비스정책 문서가 "코드를 읽어서 사후 작성" 됐다.** 기준일 2026-06-22, 작성 방식이 역공학 | `planning/서비스정책_*.md` 머리말 | **상** — 기획이 코드를 규정하는 게 아니라 코드가 기획을 규정하는 상태 |
| **J3** | 정책 문서 자체가 코드-문서 갭 9건을 부록에 나열하고 있다(IP허용목록/관리자정지/환불수수료/환불취소복구/refund모듈/강의유료/청구서인증/admin-view/팩스타임아웃) | `서비스정책_관리자.md:264-278` | **상** — 갭이 기록만 되고 닫히지 않았다 |
| **J4** | **CLAUDE.md 가 실제와 어긋난다.** site CLAUDE.md 는 `npm run build:stg`/`build:prod` 를 안내하나 `package.json` 에 없다 | `insuniverse-site/CLAUDE.md` vs `front/package.json` | **중** |
| **J5** | server README 는 스케줄러 13개라 하는데 실제는 17종(배포 15 + 미배포 1 + in-process 1) | `README.md:236-250` vs 실측 | **중** |
| **J6** | **아키텍처 다이어그램·데이터 흐름도가 없다.** 155테이블/45모듈/13벤더 구조를 설명하는 그림 0건 | 전 저장소 | **상** |
| **J7** | 기업조직/선불구독제 기획은 상세 문서(설계 67KB·스토리보드 52KB·명세 21KB)와 목업 25종이 있는 반면, 기존 도메인은 그런 산출물이 없다 — 문서화 밀도가 극단적으로 불균형 | `insuniverse-admin/planning/` | **중** |

### K. 관리포인트 / 조직 · 지속성

| # | 문제 | 근거 | 심각도 |
|---|---|---|---|
| **K1** | **관리해야 할 표면이 과대하다.** 화면 340개(admin 242 + site 98) · 테이블 155 · 엔드포인트 652 · 스케줄러 17 · 벤더 13. 인력은 활성 기여자 기준 10명 내외 | 실측 | **최상** — 1인당 화면 34개, 테이블 15개 |
| **K2** | **운영 지식이 사람·노션·AWS 콘솔에 분산**돼 있고 저장소에 없다(cron 주기, CloudWatch 알람, IAM, 스키마 변경 담당자, 프로시저) | F1·F8·F9·G3 | **최상** — 담당자 이탈 시 복구 불가 영역이 실재 |
| **K3** | 기여 분포가 편중돼 있다. site 커밋 2,463 중 1,443(59%)이 1명, admin 1,158 중 779(67%)가 1명 | `git shortlog -sne` | **상** — 버스 팩터 1 |
| **K4** | 커밋 계정에 **개인 이메일(naver/gmail)이 다수** 섞여 있다(회사 도메인 `@rs-team.com` 은 소수) | 〃 | **중** — 퇴사자 계정·저작권 귀속·감사 추적 문제 |
| **K5** | **디스크·컨텍스트 중복.** `insuniverse-temp` 가 3저장소를 submodule 로 또 담고 있어 로컬에 같은 소스가 2벌(총 3.6GB). worktree 4개 추가 존재 | 실측 | **낮** — 다만 "어느 사본을 고쳤는가" 사고 유발 |
| **K6** | 개발 속도가 하락 추세(최근 4주 34→15→27→19→14 커밋/주)인데 원인 분석 지표가 없다(리드타임·배포빈도·변경실패율 미측정) | git 실측 | **중** |

---

## 3. 우선순위 종합

### P0 — 지금 손실이 나고 있거나, 사고 시 회복 불가

| ID | 항목 | 축 |
|---|---|---|
| A1 | 운영 MOK 키 파일 git 커밋 (키 재발급 + 히스토리 대응 필요) | 보안 |
| A4·A5·F2 | prod `NODE_ENV='dev'` → Swagger 노출 + 인증 우회 분기 활성 가능성 | 보안/환경 |
| A6 | admin-view IDOR 차단 플래그 OFF 여부 | 보안 |
| B1 | 환불 수수료 안내 5% 불일치 (법적·금전) | 정책 |
| B3 | 사용자 청구서 엔드포인트 무인증 | 정책/보안 |
| D1·D2·D3 | 500에러·정기결제 실패·스케줄러 미실행 무통보 | 운영/수익 |
| E1 | 프런트 27만 라인 타입체크 미동작 | 개발품질 |
| E2·E3 | CI 품질게이트 0 + prod push 즉시 배포 | 개발프로세스 |
| F1 | IaC 부재 (환경 재현 불가) | 환경 |

### P1 — 구조적으로 계속 비용을 만드는 것

A2·A3(fail-open 인증/권한), A7·A8(site 프런트 키·console), A10(보안 미들웨어), A12(토큰 무효화 불가), A13(IP 허용목록 미강제), A15(의존성 관리), B5·B6·B7(키관리·감사로그·보관기간), C1·C2(권한 이진모델·하드코딩 메뉴), D4·D7·D8(APM·도메인 편중·SLO 부재), E4·E5·E6·E8(테스트·npm ci·CODEOWNERS), F3·F4·F6·F7·F8(배포 우회로·IAM 오명명·env·마이그레이션), G1·G2·G8(코드계약·복제 스키마), H1·H2(접근성·디자인시스템), I1·I6·I8(원가추적·던닝·비용경보), J1·J2·J3(문서 정본·역공학 정책·미해결 갭), K1·K2·K3(관리표면·지식 편재·버스팩터)

### P2 — 정리하면 좋은 것

A9·A11·A14, C3·C4, D5·D6·D9, E7·E9·E10·E11·E12, F5·F9·F10·F11, G3~G7·G9·G10, H3~H7, I2~I5·I7, J4~J7, K4~K6

---

## 4. 확인 필요 사항 (저장소 밖 — 사용자/운영 답변 필요)

| # | 질문 | 왜 필요한가 |
|---|---|---|
| Q1 | **prod 의 `NODE_ENV` 실제 값은?** `'dev'` 라면 A4·A5 가 즉시 P0 확정 | 코드 주석만 근거 |
| Q2 | `https://api.insuniverse.com/swagger` 가 외부에서 열리는가? ALB/WAF/CloudFront 에서 막고 있는가 | A4 실효성 |
| Q3 | prod env 에 `ADMIN_VIEW_TOKEN_ENFORCE=true` 가 설정돼 있는가 | A6 |
| Q4 | `mok_keyInfo_prod.dat` 를 실제 운영이 참조하는가(`MOK_KEY_PATH`), 재발급 가능한가 | A1 대응 경로 |
| Q5 | GitHub 브랜치 보호 규칙(prod/stg 강제 리뷰·상태체크)이 켜져 있는가 | E3 |
| Q6 | CloudWatch 알람이 콘솔에 설정돼 있는가 (있다면 목록) | D 축 전체 |
| Q7 | EventBridge 규칙 15종의 실제 cron 표현은? | G3 |
| Q8 | 진료 수집 벤더 5개의 **월 실제 비용**과 분석 1건당 단가는? | I1·I8 |
| Q9 | 매출 구성비(구독 : 머니 : 팩스 : B2B API)는? | I 축 우선순위 |
| Q10 | 환불 수수료 정책의 **정본**은 5% 인가 7일 내 0% 인가 | B1 — 코드/약관 어느 쪽을 고칠지 결정 |
| Q11 | 현재 활성 개발 인력 수와 역할 분담은? | K1 — 관리표면 대비 현실적 우선순위 |
| Q12 | 노션 위키에 있는 문서 목록(특히 "ECS기반의 스케줄러 생성하기", API 키 관리) | J1 |
| Q13 | `samsung-s2-report` 미배포는 의도인가 | G4 |
| Q14 | DB 프로시저 목록과 정본 위치 | F9 |
| Q15 | 개인정보 접근기록 보관 요구를 현재 어떻게 충족하고 있는가 | B6 |

---

## 5. 조사 근거 파일

```
# 기존 산출물 (재사용)
.claude/_meta/monitoring-alert-meta.md                                   운영 장애 알림 사각지대 조사
insuniverse-temp/docs/_meta/findings/11-index-code.md                    코드·에러코드 사실 인덱스
insuniverse-temp/docs/_meta/findings/12-index-runtime.md                 스케줄러 런타임 사실 인덱스
insuniverse-temp/docs/_meta/extraction-manifest.yaml                     추출 규약
insuniverse-admin/planning/서비스정책_사용자.md                          사용자 정책 정본(역공학)
insuniverse-admin/planning/서비스정책_관리자.md                          관리자 정책 정본 + 코드갭 부록

# 이번 조사에서 직접 확인한 파일
insuniverse-server/apps/api/src/main.ts:17-37,42-55                      CORS·파이프 주석·Swagger·타임아웃
insuniverse-server/apps/api/src/swagger.ts:13                            /swagger 마운트
insuniverse-server/apps/api/src/app.module.ts:188                        전역 provider = APP_PIPE 단독
insuniverse-server/apps/api/src/modules/auth/admin/jwt.guard.ts:42-45    인증 우회 분기
insuniverse-server/apps/api/src/modules/auth/admin/roles.guard.ts:21-22  @Roles 미지정 통과
insuniverse-server/apps/api/src/helpers/request.helper.ts:3,18-24        하드코딩 IP·dev swagger 판정
insuniverse-server/apps/api/src/helpers/cookie.helper.ts:12,25           prod NODE_ENV='dev' 주석·12h 토큰
insuniverse-server/apps/api/src/modules/admin-view-token/admin-view-token.guard.ts:49-55  미강제 모드
insuniverse-server/apps/api/src/modules/allow-ip/                        CRUD 전용(가드 없음)
insuniverse-server/apps/api/src/config/configuration.ts                  벤더·키 설정 전체
insuniverse-server/mok_keyInfo_prod.dat / mok_keyInfo_dev.dat            git 추적 중인 키 파일
insuniverse-server/.github/workflows/api.yml                             CI(품질게이트 없음)·스케줄러 15종
insuniverse-server/deploy/README.md:3-4,15                               CI 결제중단 우회·IAM 오명명
insuniverse-server/README.md:170-178,199-208,236-250                     B2C 복제 스키마·수동 마이그레이션·스케줄러13
insuniverse-server/drizzle/*.sql                                         마이그레이션 번호 중복
insuniverse-server/tsconfig.json:14                                      noImplicitAny: false
insuniverse-admin/tsconfig.json + package.json                           type-check no-op (실행 검증)
insuniverse-admin/vite.config.ts:69 / vite.config.constants.ts:62-72     console drop·민감키 제외(적용됨)
insuniverse-admin/src/features/authority/constants/menu.ts               하드코딩 메뉴(297행)
insuniverse-site/front/vite.config.ts / vite.config.constants.ts:61-66   env 전량 인라인·console drop 없음
insuniverse-site/front/src/entities/*/model/store.ts                     REACT_APP_PRIVATE_KEY 사용처
insuniverse-site/.github/workflows/prod.yml:26,92,116                    checkout@v2·setup-node@v2·npm install
insuniverse-site/publish/                                                레거시 정적 퍼블리싱 잔존
```
