Private · Rinda telinfo

telinfo 모바일 앱 메뉴별 구조 전수분석

Flutter · shadcn_flutter · Riverpod · Clean Architecture — 92 files / 16.6K LOC

TL;DR — 진입점 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

탭별 요약

TAB 0

액션플랜

  • 본체: InsightsFeedPage (피드 SSOT 718줄)
  • 서버 /recordings-device/feed keyset 커서
  • 녹음 자동업로드 → STT → LLM분석
  • SSE 실시간 진행 표시
  • 완료/삭제/즐겨찾기/액션아이템 낙관적 CRUD
TAB 1

즐겨찾기

  • 상단 2탭 분리 구조
  • ①서버 insights(favorite=true)
  • ②로컬 SharedPreferences
  • 통화기록 카드에서 ★추가
  • 검색·정렬·다중선택
TAB 2

설정

  • 단일 ListView · 5섹션
  • 토큰 v2 device-scoped 교환
  • Rinda 선택전송(녹음/통화/SMS)
  • 부재중 자동SMS(기기 SmsManager)
  • 데이터 조회 하위화면 push

3-Layer 일관성

모든 feature가 동일 패턴 준수 — presentation(Riverpod AsyncNotifier) → domain(엔티티 + Repository 포트) → data(Adapter). DI는 core/di/providers.dart composition root 1곳.

공유 자산내용
공유 도메인ContactInfo (call_logs ↔ sms), CallInsight (액션플랜 ↔ 서버즐겨찾기)
공통 UILoadingView / 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는 별도 보관(업로드/복사 시만 사용)

발견된 이슈 (수정 후보)

P1

v2 토큰 형식 불일치

settings_adapter.saveparts.length != 2(레거시 2-part)를 강제. v2 3-part 토큰을 붙여넣기로 저장 시 거부될 소지. QR 경로는 core SSOT(isValidDeviceTokenFormat)를 쓰는데 붙여넣기 경로만 어긋남.

P2

Dead code

settings/presentation/widgets/bulk_upload_card·simple_bulk_card·stat_card 3개 전역 미참조 (2026 IA 리팩터 잔재). 삭제 전 확인 필요.

P3

미구현 스텁

AppInfoPage 이용약관·개인정보 처리방침 onTap: () {}, 버전 하드코딩 "1.0.0".