Flutter · shadcn_flutter · Riverpod · Clean Architecture — 92 files / 16.6K LOC
HomePage = 3탭 BottomNav(액션플랜 / 즐겨찾기 / 설정).
헥사고날 포트-어댑터 구조, 전역 텔레메트리 자동계측, 기기-로컬 우선 + Rinda 서버 선택전송.
영업 페르소나 대상(통화녹음 → AI 액션플랜) 앱.
HomePage [3탭 셸 · AppBar(로고+제목+새로고침) · 콜드스타트 자동분석 모달]
├─ 탭0 액션플랜 → RecordingsHubPage
│ ├─ 진행/분석/authFailed 배너 · 검색 · 필터시트
│ ├─ [원본] → RecordingsRawPage → RecordingPlayerPage
│ └─ InsightsFeedPage(무한스크롤) → InsightCard → InsightsDetailPage
├─ 탭1 즐겨찾기 → FavoritesPage [상단 2탭]
│ ├─ 액션플랜(서버 SSOT) → InsightCard → InsightsDetailPage
│ └─ 내 즐겨찾기(로컬) → FavoriteCard · FAB추가 · 검색/정렬/필터/다중선택
└─ 탭2 설정 → SettingsPage [5섹션]
├─ 연동 RindaSettingsCard → QrScanPage · 자동분석 Switch
├─ 전송 녹음 / 통화기록 / SMS → Rinda 업로드
├─ 자동화 부재중 자동SMS → AutoSmsConfigPage
├─ 데이터 통화기록 → CallLogsPage · SMS → SmsPage · 녹음원본 → RecordingsRawPage
└─ 앱정보 → AppInfoPage
/recordings-device/feed keyset 커서모든 feature가 동일 패턴 준수 —
presentation(Riverpod AsyncNotifier) →
domain(엔티티 + Repository 포트) →
data(Adapter).
DI는 core/di/providers.dart composition root 1곳.
| 공유 자산 | 내용 |
|---|---|
| 공유 도메인 | ContactInfo (call_logs ↔ sms), CallInsight (액션플랜 ↔ 서버즐겨찾기) |
| 공통 UI | LoadingView / ErrorView / AuthRequiredView / SkeletonListView / EmptyListView |
| 전역 계측 | TelemetryNavigatorObserver + UiAutocapture (탭/스크롤/화면전환 root 1곳 포착) |
| 영역 | 조치 |
|---|---|
| 무한재시도 종결 | 실패 원장(백오프 + 상한 5회)으로 자동업로드 루프 영구 제외, 수동만 예외 |
| 자동 트리거 가드 | 재진입·authFailed 잠금·30초 디바운스, 401/403 전 워커 중단 |
| SSE 실시간 | 진행상태 별도 provider(리스트 non-rebuild) + Last-Event-ID resume + backoff |
| 좀비/stale | _generation 세대토큰으로 await 후 폐기, 폴링 머지 3분기 |
| 짧은녹음 | 클라 측정 삭제 → 서버 ffprobe(STT 전) 판정 |
| 자동SMS | 서버·Solapi 제거 → 기기 SmsManager 직접(발신번호=본인·무료), MethodChannel 동기 |
| 권한 | 콜드스타트 1회 일괄요청(전화·SMS·연락처·오디오), 화면별 산발 팝업 제거 |
| 토큰 | v2 device-scoped 3-part(deviceId 서명 바인딩)로 사칭 차단, 부팅 수렴 |
| 마스킹 | 화면 표시는 마스킹, raw는 별도 보관(업로드/복사 시만 사용) |
settings_adapter.save가 parts.length != 2(레거시 2-part)를 강제. v2 3-part 토큰을 붙여넣기로 저장 시 거부될 소지. QR 경로는 core SSOT(isValidDeviceTokenFormat)를 쓰는데 붙여넣기 경로만 어긋남.
settings/presentation/widgets/의 bulk_upload_card·simple_bulk_card·stat_card 3개 전역 미참조 (2026 IA 리팩터 잔재). 삭제 전 확인 필요.
AppInfoPage 이용약관·개인정보 처리방침 onTap: () {}, 버전 하드코딩 "1.0.0".