docs: CLAUDE.md 작업 프로토콜 추가 및 수정 계획 작성
- CLAUDE.md: Claude-Gemini 교차 토론 프로토콜 추가 - CLAUDE.md: 존재하지 않는 디렉토리 3개 제거 - analysis/fix-plan: 4 Phase 수정 계획 (Claude-Gemini 합의) - .claude/agents/: dev 리뷰 에이전트 9개 복사 - .claude/skills/: 프로젝트 스킬 4개 복사
This commit is contained in:
97
analysis/fix-plan-2026-03-27.md
Normal file
97
analysis/fix-plan-2026-03-27.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Askii Never Die — 수정 계획 (Fix Plan)
|
||||
|
||||
> 작성일: 2026-03-27
|
||||
> Claude-Gemini Cross-Debate 합의 완료
|
||||
> 기준: full-audit-2026-03-27.md (Health Score: 49/100)
|
||||
|
||||
---
|
||||
|
||||
## 합의된 조정 사항
|
||||
|
||||
| 항목 | Claude 초안 | Gemini 의견 | 합의 |
|
||||
|------|------------|------------|------|
|
||||
| Crashlytics 배치 | Phase 4 | Phase 1 전진 | **Phase 4 유지** (오프라인 정책 충돌, 로컬 로그 대안) |
|
||||
| IAP 검증 | 로컬 RSA + Secure Storage | 서버 검증 권고 | **로컬 RSA + Secure Storage** (서버 인프라 없음) |
|
||||
| Force Update | 미포함 | 추가 권고 | **미포함** (오프라인 앱에서 구현 불가) |
|
||||
| Code Obfuscation | 미포함 | 추가 권고 | **Phase 1에 추가** (빌드 설정 확인) |
|
||||
| 공수 | P1:2-3일, P3:1-2주 | P1:4-5일, P3:2-3주 | **P1:5일, P3:3주** |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: 보안 강화 + DevOps 기반 (5일)
|
||||
|
||||
| # | 작업 | 근거 | 검증 방법 |
|
||||
|---|------|------|-----------|
|
||||
| 1-1 | CI 파이프라인 구축 | DevOps 2/10 → 6/10 | push 시 format+analyze+test 자동 실행 |
|
||||
| 1-2 | 폰트 라이선스 파일 추가 | Supply Chain: OFL 의무 | assets/fonts/에 LICENSE 존재 |
|
||||
| 1-3 | IAP 로컬 영수증 RSA 검증 | Security: Lucky Patcher 방어 | 검증 실패 시 구매 거부 테스트 |
|
||||
| 1-4 | 구매 상태 flutter_secure_storage 전환 | Security: 평문 저장 제거 | 기존 SharedPreferences 마이그레이션 테스트 |
|
||||
| 1-5 | 세이브 파일 HMAC 체크섬 | Security: 변조 감지 | 변조 세이브 로드 거부 테스트 |
|
||||
| 1-6 | 난독화 설정 확인/적용 | Security: APK 디컴파일 방어 | --obfuscate + --split-debug-info 빌드 성공 |
|
||||
| 1-7 | 중복 파일 제거 | Code Quality: 100% 중복 | features/arena/widgets/ascii_disintegrate_widget.dart 삭제 |
|
||||
| 1-8 | cupertino_icons 제거 | Supply Chain: 미사용 ~280KB | pubspec.yaml에서 삭제 + flutter pub get |
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: 수익 보호 + 버전 업데이트 (5일)
|
||||
|
||||
| # | 작업 | 근거 | 검증 방법 |
|
||||
|---|------|------|-----------|
|
||||
| 2-1 | AdMob 미디에이션 (AppLovin MAX) | Idea Alignment: 수익 보호 | AdMob 비활성 시 백업 네트워크 로드 |
|
||||
| 2-2 | google_mobile_ads 5.3→7.x | Supply Chain: iOS Privacy Manifest | App Store 심사 통과 |
|
||||
| 2-3 | freezed 2.x→3.x + build_runner 업데이트 | Supply Chain: 중단된 전이 의존성 | dart run build_runner build 성공 |
|
||||
| 2-4 | CHANGELOG + 버전 태그 체계 | DevOps: 릴리즈 이력 | git tag 존재 |
|
||||
| 2-5 | flutter_lints 5→6 업데이트 | Code Quality: 최신 lint | flutter analyze 통과 |
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: 아키텍처 개선 (3주, 점진적)
|
||||
|
||||
| # | 작업 | 근거 | 검증 방법 |
|
||||
|---|------|------|-----------|
|
||||
| 3-1 | 핵심 서비스 인터페이스 정의 | Architecture: 인터페이스 0개 | abstract class 6개 이상 |
|
||||
| 3-2 | DI 컨테이너 (GetIt) 도입 | Architecture: 싱글톤 6개 제거 | 싱글톤 0개, GetIt 등록 |
|
||||
| 3-3 | ad/iap_service → core/infrastructure/ 이동 | Architecture: 엔진 프레임워크 오염 | core/engine/에 Flutter import 0개 |
|
||||
| 3-4 | setState → ValueNotifier 세분화 | Performance: 50ms 전체 리빌드 | 프레임 드롭 측정 (before/after) |
|
||||
| 3-5 | God Widget 분할 (arena_battle_screen) | Code Quality: 759 LOC | 400 LOC 이하 |
|
||||
| 3-6 | progress_service.dart 분할 | Code Quality: 832 LOC | 각 서비스 200 LOC 이하 |
|
||||
| 3-7 | 저장 시스템 테스트 작성 | Test Coverage: 0% | save/load/delete 라운드트립 테스트 |
|
||||
| 3-8 | Model 직렬화 라운드트립 테스트 | Test Coverage: 0% | toJson→fromJson 동일성 검증 |
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: 콘텐츠/성장 (2주+)
|
||||
|
||||
| # | 작업 | 근거 | 검증 방법 |
|
||||
|---|------|------|-----------|
|
||||
| 4-1 | Analytics 연동 (Firebase/PostHog) | Idea Alignment: DAU/리텐션 | 이벤트 로깅 확인 |
|
||||
| 4-2 | 크래시 리포팅 (로컬 로그 또는 Crashlytics) | DevOps: 크래시 추적 | 에러 발생 시 로그 저장 |
|
||||
| 4-3 | 피벗 후 시장 재분석 | Idea Alignment: 22/100 | idea-market-intel 리포트 |
|
||||
| 4-4 | README 전면 재작성 | Docs Sync: 극빈약 | 6개 화면, 수익화, 다국어 반영 |
|
||||
| 4-5 | ARCHITECTURE.md 작성 | Docs Sync: 없음 | 계층 구조, 데이터 흐름 문서화 |
|
||||
|
||||
---
|
||||
|
||||
## 예상 점수 변화
|
||||
|
||||
| Phase 완료 | Architecture | Code Quality | Security | Performance | Test | Supply Chain | Docs | DevOps | 예상 총점 |
|
||||
|-----------|:-----------:|:-----------:|:--------:|:-----------:|:----:|:-----------:|:----:|:------:|:---------:|
|
||||
| 현재 (0%) | 5 | 6 | 5 | 7 | 5 | 6 | 5 | 2 | **49** |
|
||||
| Phase 1 | 5 | 6.5 | 7.5 | 7 | 5.5 | 7 | 5 | 5 | **59** |
|
||||
| Phase 2 | 5 | 7 | 7.5 | 7 | 5.5 | 8 | 5.5 | 6 | **64** |
|
||||
| Phase 3 | 8 | 8 | 7.5 | 8 | 7 | 8 | 6 | 6 | **76** |
|
||||
| Phase 4 | 8 | 8 | 7.5 | 8 | 7 | 8 | 8 | 7 | **80+** |
|
||||
|
||||
---
|
||||
|
||||
## 제외된 항목
|
||||
|
||||
| 항목 | 제외 사유 |
|
||||
|------|----------|
|
||||
| Force Update | 오프라인 앱에서 네트워크 기반 버전 체크 불가 |
|
||||
| IAP 서버 검증 | 서버 인프라 없음. 로컬 RSA 검증으로 대체 |
|
||||
| Crashlytics Phase 1 | 오프라인 정책 충돌. Phase 4에서 로컬 로그 대안 검토 |
|
||||
|
||||
---
|
||||
|
||||
*Claude-Gemini Cross-Debate 합의 완료 (2026-03-27)*
|
||||
226
analysis/full-audit-2026-03-27.md
Normal file
226
analysis/full-audit-2026-03-27.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Askii Never Die - Full Project Audit Report
|
||||
|
||||
**분석일**: 2026-03-27
|
||||
**분석 도구**: 9개 개발 리뷰 에이전트 (Claude-Gemini 교차 토론 적용)
|
||||
**프로젝트**: Askii Never Die (오프라인 방치형 Idle RPG, Flutter)
|
||||
**규모**: 61,000 LOC / 224개 Dart 파일 / 247개 테스트 (전부 통과)
|
||||
|
||||
---
|
||||
|
||||
## Project Health Score: 49 / 100
|
||||
|
||||
| # | 영역 | 점수 | 가중치 | 가중 점수 | 핵심 이슈 |
|
||||
|---|------|:----:|:------:|:---------:|-----------|
|
||||
| 1 | Architecture | 5/10 | 15% | 7.5 | 인터페이스 0개, DI 부재, 싱글톤 6개, 엔진에 프레임워크 직접 의존 |
|
||||
| 2 | Code Quality | 6/10 | 15% | 9.0 | 200 LOC 초과 47.6%, God Widget 2개, 100% 중복 파일 1쌍 |
|
||||
| 3 | Security | 5/10 | 15% | 7.5 | IAP 로컬 영수증 검증 미구현, 세이브 무결성 없음, 구매 상태 평문 저장 |
|
||||
| 4 | Performance | 7/10 | 10% | 7.0 | 매 50ms setState 전체 리빌드, 서비스 객체 반복 생성, SFX 캐싱 부재 |
|
||||
| 5 | Test Coverage | 5/10 | 10% | 5.0 | 파일 커버리지 10%, 저장/전투틱/Model 직렬화 테스트 전무 |
|
||||
| 6 | Supply Chain | 6/10 | 10% | 6.0 | 폰트 라이선스 미포함, google_mobile_ads 2 메이저 뒤처짐 |
|
||||
| 7 | Docs Sync | 5/10 | 5% | 2.5 | CLAUDE.md에 존재하지 않는 디렉토리 3개, README 극빈약 |
|
||||
| 8 | DevOps | 2/10 | 10% | 2.0 | CI/CD 완전 부재, 릴리즈 프로세스 미정립 |
|
||||
| 9 | Idea Alignment | 22/100 | 10% | 2.2 | 완전 피벗 (RPS 격투 -> Idle RPG), 피벗 후 시장 재분석 없음 |
|
||||
| | **합계** | | **100%** | **48.7** | |
|
||||
|
||||
> **점수 해석**: 49점대는 "동작하는 프로토타입~알파" 수준. 제품으로서 기능하지만 프로덕션 배포에 필요한 품질/운영 기반이 미비.
|
||||
|
||||
> **참고**: Keystore Git 노출은 개인 Git 서버에서 사용자가 허가한 사항이므로 이슈에서 제외. IAP는 서버가 없는 구조이므로 로컬 검증 강화 방안으로 조정.
|
||||
|
||||
---
|
||||
|
||||
## CRITICAL Issues (즉시 조치 필요)
|
||||
|
||||
### 1. CI/CD 파이프라인 완전 부재 [DevOps]
|
||||
- **영향**: 빌드/테스트/린트 모두 수동. 깨진 코드 push 가능
|
||||
- **조치**: Gitea Actions 또는 GitHub Actions로 `dart format` + `flutter analyze` + `flutter test` 자동화
|
||||
- **예상 공수**: 반나절
|
||||
|
||||
### 2. AdMob 미디에이션 미구현 [Idea Alignment + Security]
|
||||
- **영향**: AdMob 계정 정지 = 수익 즉시 소멸 (인디 개발자 가장 흔한 수익 소멸 시나리오)
|
||||
- **조치**: AppLovin MAX 또는 IronSource 연동
|
||||
- **예상 공수**: 2-3일
|
||||
|
||||
---
|
||||
|
||||
## HIGH Issues (단기 조치)
|
||||
|
||||
### 3. IAP 로컬 영수증 서명 검증 미구현 [Security]
|
||||
- **파일**: `lib/src/core/engine/iap_service.dart:332-336`
|
||||
- **영향**: 서버 없이도 로컬 서명 검증으로 캐주얼 크래킹(Lucky Patcher 등) 방어 가능
|
||||
- **조치**:
|
||||
- **Google Play**: `purchase.verificationData.localVerificationData`에서 서명된 JSON 추출 -> Google Play Console의 공개 키(Base64 RSA)로 `RSASSA-PKCS1-v1_5 + SHA1` 서명 검증. `pointycastle` 패키지 활용
|
||||
- **Apple**: StoreKit 2의 JWS(JSON Web Signature) 토큰을 로컬에서 Apple 루트 인증서로 검증
|
||||
- **구매 상태 저장**: `shared_preferences` -> `flutter_secure_storage` (Android Keystore / iOS Keychain)
|
||||
- **공수**: 1-2일
|
||||
- **한계**: 루팅+후킹 조합 공격은 로컬 검증으로 완전 차단 불가. 그러나 90%+ 캐주얼 크래킹 방어 가능
|
||||
|
||||
### 4. 구매 상태 평문 저장 [Security]
|
||||
- **파일**: `iap_service.dart:65-66`, `monetization_state.dart:17-45`
|
||||
- **조치**: shared_preferences -> flutter_secure_storage 전환 (3번 작업과 동시 진행)
|
||||
- **공수**: 반나절
|
||||
|
||||
### 5. 세이브 파일 무결성 없음 [Security]
|
||||
- **파일**: `save_service.dart:17-20`
|
||||
- **조치**: HMAC-SHA256 체크섬 추가. 키는 앱 번들에 난독화 포함
|
||||
- **공수**: 반나절
|
||||
|
||||
### 6. Analytics 부재 [Idea Alignment]
|
||||
- **영향**: DAU, 리텐션, 광고 시청률, IAP 전환율 측정 불가
|
||||
- **조치**: Firebase Analytics 또는 PostHog 연동
|
||||
- **공수**: 1일
|
||||
|
||||
### 7. 인터페이스 0개 + DI 부재 [Architecture]
|
||||
- **영향**: 테스트 격리 불가, 싱글톤 6개로 모킹 원천 봉쇄
|
||||
- **조치**: GetIt 또는 생성자 주입 도입, 핵심 서비스 abstract class 정의
|
||||
- **공수**: 3-5일 (점진적)
|
||||
|
||||
### 8. 매 50ms 전체 위젯 setState [Performance]
|
||||
- **파일**: `game_play_screen.dart:352-368`
|
||||
- **영향**: 모바일 프레임 드롭 원인 1순위
|
||||
- **조치**: ValueNotifier/Selector로 세분화된 상태 관리
|
||||
- **공수**: 1-2일
|
||||
|
||||
### 9. 저장 시스템 테스트 전무 [Test Coverage]
|
||||
- **파일**: `save_repository.dart`, `save_service.dart`, `save_manager.dart` (6개 파일 모두)
|
||||
- **영향**: 세이브 파일 손상 시 플레이어 데이터 영구 손실
|
||||
- **조치**: IOOverrides/임시 디렉토리 기반 저장/로드/삭제 테스트 작성
|
||||
- **공수**: 1일
|
||||
|
||||
---
|
||||
|
||||
## MEDIUM Issues (중기 개선)
|
||||
|
||||
### 10. 폰트 라이선스 파일 미포함 [Supply Chain]
|
||||
- JetBrainsMono (OFL), PressStart2P (OFL) LICENSE 파일 `assets/fonts/`에 추가 필수
|
||||
|
||||
### 11. google_mobile_ads 5.3.0 -> 7.0.0 업그레이드 [Supply Chain]
|
||||
- iOS Privacy Manifest 미대응으로 App Store 심사 거절 리스크
|
||||
|
||||
### 12. God Widget 2개 분할 [Code Quality]
|
||||
- `game_play_screen.dart` (736 LOC), `arena_battle_screen.dart` (759 LOC)
|
||||
|
||||
### 13. progress_service.dart 832 LOC 분할 [Code Quality]
|
||||
- Quest/Plot/Exp/Combat 서비스로 분리
|
||||
|
||||
### 14. 100% 중복 파일 제거 [Code Quality]
|
||||
- `features/arena/widgets/ascii_disintegrate_widget.dart` 삭제 (shared/ 버전 사용)
|
||||
|
||||
### 15. CLAUDE.md 디렉토리 구조 수정 [Docs Sync]
|
||||
- `core/animation/` -> `shared/animation/`, `core/constants/` 삭제, `core/l10n/` -> `shared/l10n/`
|
||||
|
||||
### 16. README 전면 재작성 [Docs Sync]
|
||||
- 현재 프로젝트 초기 임시 메모 수준. 6개 화면, 수익화, 다국어 지원 등 전혀 반영 안 됨
|
||||
|
||||
### 17. 크래시 리포팅 도입 [DevOps]
|
||||
- Firebase Crashlytics 또는 Sentry
|
||||
|
||||
### 18. 엔진 계층 프레임워크 오염 제거 [Architecture]
|
||||
- `ad_service.dart`, `iap_service.dart` 등을 `core/infrastructure/`로 이동
|
||||
|
||||
### 19. 피벗 후 시장 재분석 [Idea Alignment]
|
||||
- "오프라인 Idle RPG + ASCII 아트" 시장 분석이 전무. idea-market-intel 재실행 필요
|
||||
|
||||
---
|
||||
|
||||
## LOW Issues (장기)
|
||||
|
||||
- cupertino_icons 미사용 제거 (~280KB 절약)
|
||||
- SFX 에셋 프리로드 및 캐싱
|
||||
- 모바일 포그라운드 복귀 시 전체 화면 재생성 최적화
|
||||
- gcd_simulation_test/balance_analysis_test를 실제 assert 포함 테스트로 전환
|
||||
- analysis_options.yaml lint rule 추가 (prefer_const_constructors, prefer_final_locals 등)
|
||||
- CHANGELOG에 실제 릴리즈 이력 기록
|
||||
- Model 직렬화 라운드트립 테스트 작성
|
||||
|
||||
---
|
||||
|
||||
## Fix Plan (Eisenhower Matrix)
|
||||
|
||||
```
|
||||
긴급 (Urgent) 비긴급 (Not Urgent)
|
||||
┌──────────────────────────┬──────────────────────────┐
|
||||
중요 │ DO FIRST (즉시) │ SCHEDULE (계획) │
|
||||
(Important) │ │ │
|
||||
│ 1. CI/CD 구축 │ 7. 인터페이스+DI 도입 │
|
||||
│ 2. AdMob 미디에이션 │ 12. God Widget 분할 │
|
||||
│ 3. IAP 로컬 서명 검증 │ 13. progress_service 분할│
|
||||
│ 4. 구매 상태 보안 저장 │ 18. 엔진 프레임워크 분리 │
|
||||
│ 5. 세이브 무결성 추가 │ 19. 피벗 후 시장 재분석 │
|
||||
│ 10. 폰트 라이선스 추가 │ 17. 크래시 리포팅 도입 │
|
||||
├──────────────────────────┼──────────────────────────┤
|
||||
덜 중요 │ DELEGATE (위임 가능) │ ELIMINATE (후순위) │
|
||||
(Less │ │ │
|
||||
Important) │ 6. Analytics 연동 │ 14. 중복 파일 제거 │
|
||||
│ 8. setState 세분화 │ 15. CLAUDE.md 수정 │
|
||||
│ 9. 저장 시스템 테스트 │ 16. README 재작성 │
|
||||
│ 11. google_mobile_ads 7.x│ + LOW 이슈 전체 │
|
||||
└──────────────────────────┴──────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 실행 로드맵 (권장 순서)
|
||||
|
||||
### Phase 1: 보안 강화 + DevOps 기반 (2-3일)
|
||||
```
|
||||
1. CI 파이프라인 구축 (dart format + analyze + test) → verify: push 시 자동 실행
|
||||
2. 폰트 라이선스 파일 추가 → verify: assets/fonts/에 LICENSE.txt 존재
|
||||
3. IAP 로컬 영수증 서명 검증 구현 (Google Play 공개키 RSA 검증) → verify: 검증 실패 시 구매 거부 테스트
|
||||
4. 구매 상태 flutter_secure_storage 전환 → verify: 기존 테스트 통과
|
||||
5. 세이브 파일 HMAC 체크섬 추가 → verify: 변조된 세이브 로드 거부 테스트
|
||||
```
|
||||
|
||||
### Phase 2: 수익 보호 (3-5일)
|
||||
```
|
||||
1. AdMob 미디에이션 연동 (AppLovin MAX) → verify: AdMob 비활성 시 백업 네트워크 로드
|
||||
2. google_mobile_ads 7.x 마이그레이션 → verify: iOS Privacy Manifest 포함 확인
|
||||
3. CHANGELOG 정리 + 버전 태그 체계 수립 → verify: git tag 존재
|
||||
```
|
||||
|
||||
### Phase 3: 아키텍처 개선 (1-2주, 점진적)
|
||||
```
|
||||
1. 핵심 서비스 인터페이스 정의 (SaveRepository, AdService, IAPService)
|
||||
2. DI 컨테이너(GetIt) 도입
|
||||
3. ad_service, iap_service를 core/infrastructure/로 이동
|
||||
4. GamePlayScreen setState 세분화
|
||||
5. 저장 시스템 테스트 작성
|
||||
```
|
||||
|
||||
### Phase 4: 콘텐츠/성장 (2주+)
|
||||
```
|
||||
1. Firebase Analytics 연동
|
||||
2. Crashlytics 연동
|
||||
3. 피벗 후 시장 재분석 (idea-market-intel 실행)
|
||||
4. Web meta 태그 수정 + ASO 최적화
|
||||
5. README / CLAUDE.md / ARCHITECTURE.md 동기화
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 에이전트별 상세 리포트 참조
|
||||
|
||||
| 에이전트 | 점수 | 주요 발견 |
|
||||
|---------|:----:|----------|
|
||||
| Architecture | 5/10 | 인터페이스 0개, 싱글톤 6개, core/engine/ Flutter 오염 6파일, app.dart God Class 459 LOC |
|
||||
| Code Quality | 6/10 | dart format/analyze 통과, 200 LOC 초과 100개(47.6%), God Widget 2개, var 31회 남용 |
|
||||
| Security | 5/10 | IAP 로컬 서명 검증 미구현, 세이브 무결성 없음, 구매 상태 평문 저장 |
|
||||
| Supply Chain | 6/10 | CVE 0, GPL 0, 폰트 라이선스 미포함, google_mobile_ads 2메이저 뒤처짐 |
|
||||
| Performance | 7/10 | 50ms setState 전체 리빌드, 서비스 객체 매틱 재생성, SFX 캐싱 부재, RepaintBoundary 활용 양호 |
|
||||
| Test Coverage | 5/10 | 247개 테스트 전통과, 파일 커버리지 10%, 저장/전투틱/Model 직렬화 테스트 전무 |
|
||||
| Docs Sync | 5/10 | CLAUDE.md 존재하지 않는 경로 3개, README 극빈약, CHANGELOG 릴리즈 이력 없음 |
|
||||
| DevOps | 2/10 | CI/CD 완전 부재, 릴리즈 프로세스 미정립, Crashlytics 없음 |
|
||||
| Idea Alignment | 22/100 | 완전 피벗 (RPS -> Idle RPG), 수익화만 일치, 피벗 후 시장 재분석 없음, Analytics 부재 |
|
||||
|
||||
---
|
||||
|
||||
## 제외된 이슈
|
||||
|
||||
| 이슈 | 제외 사유 |
|
||||
|------|----------|
|
||||
| Keystore + 비밀번호 Git 노출 | 개인 Git 서버(Gitea)에서 사용자가 허가한 운영 방식 |
|
||||
| IAP 서버 측 영수증 검증 | 서버 없는 오프라인 앱 구조. 로컬 서명 검증으로 대체 권고 |
|
||||
|
||||
---
|
||||
|
||||
*이 보고서는 Claude-Gemini 교차 토론을 통해 합의된 결과입니다.*
|
||||
*9개 에이전트 병렬 실행, 총 분석 시간: ~6분*
|
||||
175
analysis/supply-chain-review.md
Normal file
175
analysis/supply-chain-review.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# asciineverdie Supply Chain Review
|
||||
|
||||
> 검토일: 2026-03-27
|
||||
> Flutter 3.35.3 / Dart 3.9.2
|
||||
> Claude-Gemini Cross-Debate 완료 (합의 도달)
|
||||
|
||||
## Supply Chain Score: 6 / 10
|
||||
|
||||
| 항목 | 점수 | 비고 |
|
||||
|------|------|------|
|
||||
| 보안 (CVE) | 8/10 | 알려진 CVE 없음 |
|
||||
| 라이선스 | 6/10 | GPL 오염 없음, 폰트 라이선스 파일 누락 |
|
||||
| 유지보수 건강도 | 5/10 | google_mobile_ads 2 메이저 뒤처짐, build_runner 전이 의존성 중단 |
|
||||
| 최신성 | 4/10 | 직접 의존성 7개 중 5개 메이저 버전 뒤처짐 |
|
||||
| 의존성 비대화 | 7/10 | 직접 11개, 프로덕션 전이 포함 ~62개 (합리적 수준) |
|
||||
|
||||
---
|
||||
|
||||
## 1. 취약점 (Vulnerabilities)
|
||||
|
||||
| 패키지 | 버전 | CVE | 심각도 | 수정 버전 |
|
||||
|--------|------|-----|--------|-----------|
|
||||
| (해당 없음) | - | - | - | - |
|
||||
|
||||
**결론:** OSV(Open Source Vulnerabilities) 데이터베이스 및 GitHub Advisory Database 기준, 현재 사용 중인 의존성 버전에서 알려진 CVE는 발견되지 않음.
|
||||
|
||||
다만 `google_mobile_ads` 5.x는 최신 iOS Privacy Manifest 및 UMP(User Messaging Platform) 요구사항을 완벽히 지원하지 않을 가능성이 있어, App Store 심사 거절 리스크 존재.
|
||||
|
||||
---
|
||||
|
||||
## 2. 라이선스 이슈
|
||||
|
||||
| 패키지/자산 | 라이선스 | 리스크 | 필요 조치 |
|
||||
|------------|---------|--------|-----------|
|
||||
| 모든 Dart 패키지 | BSD-3 / MIT / Apache-2.0 | 없음 | GPL 오염 없음 -- 상업적 사용 안전 |
|
||||
| JetBrainsMono (폰트) | OFL-1.1 (추정) | 중간 | 라이선스 파일 미포함. `assets/fonts/`에 OFL.txt 추가 필요 |
|
||||
| PressStart2P (폰트) | OFL-1.1 (추정) | 중간 | 라이선스 파일 미포함. `assets/fonts/`에 OFL.txt 추가 필요 |
|
||||
|
||||
**폰트 라이선스 상세:**
|
||||
- JetBrains Mono: JetBrains 배포, Apache 2.0 라이선스
|
||||
- Press Start 2P: Google Fonts 배포, OFL 라이선스
|
||||
- 두 폰트 모두 상업적 사용 가능하나, 라이선스 텍스트를 앱에 포함해야 하는 의무(attribution) 존재
|
||||
- 현재 `assets/fonts/` 디렉토리에 LICENSE 파일이 **전혀 없음**
|
||||
- App Store / Play Store 심사에서는 보통 문제되지 않으나, 법적 리스크는 존재
|
||||
|
||||
---
|
||||
|
||||
## 3. 유지보수 건강도
|
||||
|
||||
| 패키지 | 현재 버전 | 상태 | 리스크 |
|
||||
|--------|----------|------|--------|
|
||||
| cupertino_icons | 1.0.8 | 정상 유지보수 | 낮음 (단, 미사용) |
|
||||
| intl | 0.20.2 | Dart 팀 관리 | 없음 |
|
||||
| path_provider | 2.1.5 | Flutter 팀 관리 | 없음 |
|
||||
| shared_preferences | 2.5.3 | Flutter 팀 관리 | 없음 |
|
||||
| just_audio | 0.9.46 | 활발한 커뮤니티 (ryanheise) | 단일 메인테이너 리스크 |
|
||||
| freezed_annotation | 2.4.4 | 활발한 커뮤니티 (rrousselGit) | 단일 메인테이너 리스크 |
|
||||
| json_annotation | 4.9.0 | Google/Dart 팀 관리 | 없음 |
|
||||
| google_mobile_ads | 5.3.1 | Google 관리 | **v5.x 지원 종료 임박** |
|
||||
| in_app_purchase | 3.2.3 | Flutter 팀 관리 | 없음 |
|
||||
| package_info_plus | 8.3.1 | FlutterCommunity 관리 | 낮음 |
|
||||
| build_runner | 2.5.4 | Google/Dart 팀 관리 | **전이 의존성 중단됨** |
|
||||
|
||||
**중단된 전이 의존성 (Discontinued transitive deps):**
|
||||
- `build_resolvers` 2.5.4 -- 공식 중단 선언
|
||||
- `build_runner_core` 9.1.2 -- 공식 중단 선언
|
||||
- 이 패키지들의 기능은 최신 `build_runner`(2.10+)에 내재화됨
|
||||
- 즉각적인 빌드 실패를 일으키진 않으나, 향후 Dart SDK 업데이트 시 호환성 문제 발생 확실
|
||||
|
||||
---
|
||||
|
||||
## 4. 메이저 버전 뒤처짐 (Outdated - Major Behind)
|
||||
|
||||
### 직접 의존성 (Direct)
|
||||
|
||||
| 패키지 | 현재 | 최신 | 뒤처짐 | 비고 |
|
||||
|--------|------|------|--------|------|
|
||||
| google_mobile_ads | 5.3.1 | 7.0.0 | **2 메이저** | iOS Privacy Manifest, UMP 지원 필수 |
|
||||
| freezed_annotation | 2.4.4 | 3.1.0 | 1 메이저 | freezed 3.x와 짝 맞춰야 함 |
|
||||
| package_info_plus | 8.3.1 | 9.0.0 | 1 메이저 | |
|
||||
| just_audio | 0.9.46 | 0.10.5 | 1 마이너 (pre-1.0) | 0.x 시맨틱에서는 마이너 = 메이저 |
|
||||
| json_annotation | 4.9.0 | 4.11.0 | 2 마이너 | |
|
||||
|
||||
### 개발 의존성 (Dev)
|
||||
|
||||
| 패키지 | 현재 | 최신 | 뒤처짐 | 비고 |
|
||||
|--------|------|------|--------|------|
|
||||
| build_runner | 2.5.4 | 2.13.1 | 8 마이너 | 중단된 전이 의존성 해소 위해 업데이트 필요 |
|
||||
| freezed | 2.5.8 | 3.2.5 | **1 메이저** | freezed_annotation 3.x와 함께 업데이트 |
|
||||
| json_serializable | 6.9.5 | 6.13.1 | 4 마이너 | |
|
||||
| flutter_lints | 5.0.0 | 6.0.0 | 1 메이저 | |
|
||||
|
||||
---
|
||||
|
||||
## 5. 불필요한 의존성
|
||||
|
||||
| 패키지 | 사용 여부 | 판정 | 근거 |
|
||||
|--------|----------|------|------|
|
||||
| cupertino_icons | 미사용 | **제거 권장** | `lib/` 전체에서 `CupertinoIcons` import 0건. ~280KB 바이너리 낭비 |
|
||||
| json_annotation | 간접 사용 | 유지 | freezed_annotation이 re-export하지만, .g.dart 생성 파일이 직접 import함. 제거 시 빌드 깨질 수 있음 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 의존성 트리 통계
|
||||
|
||||
| 항목 | 수치 |
|
||||
|------|------|
|
||||
| 직접 프로덕션 의존성 | 11개 (SDK 포함) |
|
||||
| 직접 개발 의존성 | 6개 (SDK 포함) |
|
||||
| 프로덕션 전이 포함 총 패키지 | ~62개 |
|
||||
| 개발 포함 총 패키지 (pubspec.lock) | 122개 |
|
||||
| 코드 생성 대상 파일 (.freezed.dart + .g.dart) | 8개 |
|
||||
|
||||
---
|
||||
|
||||
## 권장 조치 사항
|
||||
|
||||
### [CRITICAL] 즉시 조치
|
||||
|
||||
1. **폰트 라이선스 파일 추가**
|
||||
- `assets/fonts/JetBrainsMono-LICENSE.txt` (Apache 2.0)
|
||||
- `assets/fonts/PressStart2P-OFL.txt` (OFL 1.1)
|
||||
- 앱 내 오픈소스 라이선스 화면에 표시 필요
|
||||
- Google Fonts 및 JetBrains 공식 사이트에서 다운로드
|
||||
|
||||
2. **google_mobile_ads 7.x 업데이트 계획 수립**
|
||||
- iOS Privacy Manifest 대응 필수 (App Store 심사 거절 리스크)
|
||||
- v7.0.0 마이그레이션 가이드: https://developers.google.com/admob/flutter/migration
|
||||
|
||||
### [HIGH] 단기 조치 (1-2주)
|
||||
|
||||
3. **cupertino_icons 제거**
|
||||
```yaml
|
||||
# pubspec.yaml에서 삭제
|
||||
# cupertino_icons: ^1.0.8
|
||||
```
|
||||
|
||||
4. **build_runner 체인 업데이트**
|
||||
```bash
|
||||
flutter pub upgrade build_runner json_serializable
|
||||
```
|
||||
- 중단된 `build_resolvers`, `build_runner_core` 전이 의존성 해소
|
||||
- 빌드 성능 개선 기대
|
||||
|
||||
5. **freezed 2.x -> 3.x 마이그레이션**
|
||||
- freezed_annotation + freezed 동시에 메이저 업데이트
|
||||
- 코드 생성 파일 전체 재생성 필요: `dart run build_runner build --delete-conflicting-outputs`
|
||||
|
||||
### [MEDIUM] 중기 조치 (1개월)
|
||||
|
||||
6. **just_audio 0.10.x 업데이트**
|
||||
- Android 최신 버전 호환성 개선
|
||||
- 단일 메인테이너(ryanheise) 패키지이므로 대안(audioplayers) 검토도 병행
|
||||
|
||||
7. **package_info_plus 9.x 업데이트**
|
||||
|
||||
8. **flutter_lints 6.x 업데이트**
|
||||
- 최신 lint 규칙 적용으로 코드 품질 향상
|
||||
|
||||
### [LOW] 장기 고려
|
||||
|
||||
9. **win32 전이 의존성** -- package_info_plus가 Windows 지원에 사용. 모바일 전용이면 무시 가능
|
||||
|
||||
---
|
||||
|
||||
## Claude-Gemini Cross-Debate 결과
|
||||
|
||||
| 항목 | Claude 의견 | Gemini 초기 의견 | 합의 |
|
||||
|------|------------|-----------------|------|
|
||||
| 종합 점수 | 6/10 | 3.5/10 | **6/10** (Gemini 수정 동의) |
|
||||
| CVE-2023-48220 | 해당 없음 (Nextcloud 취약점) | package_info_plus 관련 주장 | **해당 없음** (Gemini 철회) |
|
||||
| json_annotation 제거 | 위험 (빌드 깨짐 가능) | 제거 권장 | **유지** (Gemini 수정 동의) |
|
||||
| build_runner 긴급도 | 중기 과제 (당장은 동작) | 즉시 수술 필요 | **단기 과제** (절충) |
|
||||
| 보안 리스크 수준 | Low | Medium-High | **Low** (Gemini 수정 동의) |
|
||||
| 폰트 라이선스 | 중간 리스크 | 중간 리스크 | **합의** |
|
||||
Reference in New Issue
Block a user