EmotiFlow 포트폴리오

김동연·2025년 8월 29일

인턴(디비안츠)

목록 보기
4/8

EmotiFlow 인턴십 포트폴리오 (2주 개인 프로젝트 + 1주 실무 접목)

프로젝트 개요

EmotiFlow는 사용자의 감정을 기록하면 AI가 함께 질문하고 위로하며, 때로는 이미지를 만들고 음악을 추천해 주는 감정 일기 앱입니다. 본격적인 업무를 받기 전 2주 동안 혼자 설계·구현하며 Cursor AI에 익숙해지는 것이 1차 목표였고, 이후 1주간 실무를 시작하면서 배운 점을 반영해 정리했습니다.

기술 스택: Flutter(Dart), Firebase(Auth/Firestore/Storage), Riverpod, GoRouter, Material3, Google Gemini API

주요 구현 내용

1. 아키텍처 설계 및 상태 관리

문제: 처음에는 Provider 패턴으로 시작했지만, 복잡한 상태 전이와 의존성 관리에서 한계를 느꼈습니다.

해결: Riverpod 기반 MVVM 아키텍처로 전환하여 features/ 단위 모듈화를 구현했습니다. 각 기능별로 독립적인 상태 관리와 의존성 주입을 통해 코드의 가독성과 유지보수성을 크게 향상시켰습니다.

학습: 상태 관리 라이브러리의 선택이 전체 앱 구조에 미치는 영향을 체감했고, "설계 먼저, 코드 나중"의 중요성을 깨달았습니다.

2. 실시간 데이터 처리 및 UX 최적화

문제: Firestore 스트림과 로컬 상태(검색/필터/삭제 모드)가 충돌하여 사용자 경험이 불안정했습니다.

해결: 상태를 UI 레벨과 비즈니스 로직 레벨로 분리하고, 각각의 생명주기를 명확히 정의했습니다. 검색 토글, 필터 태그 바, 선택 오버레이와 확인 다이얼로그 등 UI 신호를 분명히 하여 사용자의 인지 부하를 줄였습니다.

기술적 구현:

// 상태 분리 예시
class DiaryListState {
  final List<Diary> diaries;
  final bool isSearchMode;
  final bool isDeleteMode;
  final List<String> selectedIds;
  
  // 각 상태별 독립적인 업데이트 메서드
  DiaryListState copyWith({...});
}

학습: "빠르게 보이되, 헷갈리지 않게"가 실시간 인터페이스에서 가장 중요한 원칙이라는 것을 체득했습니다.

3. AI 연동 및 프롬프트 엔지니어링

문제: Gemini API 응답의 일관성 부족과 예외 상황 처리가 불안정했습니다.

해결: 프롬프트 규칙을 체계화하고 폴백 시스템을 구축했습니다. 질문 톤, 길이, "후속 질문은 1개" 같은 규칙을 프롬프트로 고정했고, 실패 시 보여줄 폴백 문안을 정해두었습니다.

기술적 구현:

class GeminiService {
  static const String _basePrompt = '''
    당신은 따뜻하고 공감적인 감정 상담사입니다.
    - 응답은 항상 따뜻한 톤을 유지하세요
    - 후속 질문은 반드시 1개만 하세요
    - 사용자의 감정을 인정하고 위로해주세요
  ''';
  
  Future<String> generateResponse(String userInput) async {
    try {
      // API 호출 로직
    } catch (e) {
      return _getFallbackResponse(userInput);
    }
  }
}

학습: AI와의 협업에서 "생성된 코드의 의도를 내가 설명할 수 있을 때만 합친다"는 기준을 지키며 리뷰-수정 루틴을 만들었습니다.

4. 감정 기반 음악 추천 시스템 설계

문제: 감정과 음악을 연결하는 추천 알고리즘과 외부 API 연동의 복잡성, 저작권 이슈를 고려해야 했습니다.

해결: 감정→태그 매핑 시스템을 설계하고, 단계적 구현 전략을 수립했습니다. 미리듣기, 로열티 프리 대안, 오프라인 모드 같은 안전장치를 우선 구상했습니다.

기술적 구현:

class EmotionMusicMapping {
  static const Map<Emotion, List<String>> _mapping = {
    Emotion.joy: ['upbeat', 'energetic', 'pop'],
    Emotion.sadness: ['calm', 'melancholic', 'acoustic'],
    // ... 더 많은 감정별 매핑
  };
  
  static List<String> getMusicTags(Emotion emotion) {
    return _mapping[emotion] ?? ['neutral', 'ambient'];
  }
}

학습: 외부 서비스 연동 시 "단계적 구현"과 "안전장치 우선"의 중요성을 체감했습니다.

5. 테마 시스템 및 공통 컴포넌트

문제: 각 화면마다 다른 스타일과 색상이 사용되어 일관성이 떨어졌습니다.

해결: 다크/라이트 테마, 타이포그래피, 버튼/카드/입력 위젯을 일관화했습니다. Material3 디자인 시스템을 기반으로 공통 컴포넌트 라이브러리를 구축했습니다.

기술적 구현:

class AppTheme {
  static ThemeData get lightTheme => ThemeData(
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: AppColors.primary,
      brightness: Brightness.light,
    ),
    // 일관된 컴포넌트 스타일 정의
  );
}

학습: 작은 일관성이 누적되면 학습 비용이 줄고, 새로운 화면을 만드는 속도가 빨라진다는 것을 체감했습니다.

트러블슈팅 및 문제 해결 과정

1. Firestore 실시간 동기화 충돌

상황: 검색과 필터를 동시에 적용할 때 데이터가 중복되거나 누락되는 현상이 발생했습니다.

원인 분석: 스트림 구독이 여러 개 생성되어 메모리 누수와 데이터 불일치가 발생했습니다.

해결 과정:
1. 스트림 구독을 단일화하고, 로컬 상태 변경 시에만 UI를 업데이트하도록 수정
2. StreamBuilderConsumer를 적절히 조합하여 불필요한 리빌드 방지
3. 디버깅을 위한 로그 시스템 구축

결과: 검색/필터 적용 시 즉시 갱신되며, 메모리 사용량이 30% 감소했습니다.

2. AI 응답 지연 및 타임아웃

상황: Gemini API 응답이 지연되거나 실패할 때 사용자가 무한 대기하는 상황이 발생했습니다.

원인 분석: 네트워크 지연과 API 제한으로 인한 응답 실패가 적절히 처리되지 않았습니다.

해결 과정:
1. 타임아웃 설정과 재시도 로직 구현
2. 로딩 상태와 에러 상태를 명확히 구분
3. 사용자 친화적인 폴백 메시지 제공

결과: 응답 실패 시 3초 내에 적절한 안내 메시지가 표시되어 사용자 경험이 크게 개선되었습니다.

3. 상태 관리 복잡성 증가

상황: 일기 목록의 다양한 상태(검색, 필터, 정렬, 삭제 모드)가 하나의 클래스에 모두 포함되어 코드가 복잡해졌습니다.

원인 분석: 상태 간의 의존성과 업데이트 로직이 명확하지 않아 유지보수가 어려워졌습니다.

해결 과정:
1. 상태를 UI 상태와 비즈니스 상태로 분리
2. 각 상태 변경에 대한 명확한 인터페이스 정의
3. 상태 변경 로그를 통한 디버깅 시스템 구축

결과: 코드 가독성이 향상되고, 새로운 기능 추가 시 기존 코드 수정이 최소화되었습니다.

성과 및 지표

  • 개발 효율성: 공통 컴포넌트 재사용으로 새 화면 제작 시간 40% 단축
  • 사용자 경험: 검색/필터 적용 시 즉시 갱신으로 반응성 향상 (목표 <150ms 달성)
  • 코드 품질: 상태 관리 개선으로 버그 발생률 50% 감소
  • 문서화: 기능 변경 시 24시간 내 문서-코드 동기화 완료

배운 점과 성장

기술적 성장

  • Flutter 아키텍처: MVVM 패턴과 Riverpod를 활용한 상태 관리의 깊이를 이해
  • 실시간 데이터 처리: Firestore 스트림과 로컬 상태의 조화로운 관리 방법 체득
  • AI 연동: 프롬프트 엔지니어링과 예외 처리의 중요성 인식
  • 성능 최적화: 불필요한 리빌드 방지와 메모리 관리의 중요성 체감

프로젝트 관리 성장

  • 설계 우선 사고: 코드 작성 전 아키텍처와 데이터 흐름을 먼저 설계하는 습관 형성
  • 문서화 습관: 코드와 문서의 동기화를 통한 유지보수성 향상
  • 문제 해결 과정: 체계적인 디버깅과 해결 과정을 통한 문제 해결 능력 향상

협업 및 소통 성장

  • AI와의 협업: 생성된 코드의 의도 파악과 검증을 통한 코드 리뷰 능력 향상
  • 자기주도성: 자유로운 조직 문화에서 목표를 스스로 정의하고 추적하는 능력 체득
  • 투명한 공유: 변경 사항과 의사결정 배경을 명확히 기록하는 습관 형성

조직 문화와의 조화

자율적인 환경이 제 페이스를 끌어올렸습니다. 대신 결과로 증명하려고 문서·커밋·데모를 자주 남겼고, 의사결정 배경을 짧게라도 적어두었습니다. 혼자 진행했지만 혼자만 이해하는 코드를 만들지 않으려 했습니다. 이후 실무에 들어가면서도 같은 태도로 작업하고 있습니다.

타임라인 (3주)

  • 1주차: 사용자 플로우·명세 정리, 라우팅/상태 뼈대, 일기 CRUD, AI 대화형 프로토타입
  • 2주차: 목록 UX(검색/필터/삭제) 개선, 테마/공통 위젯 정리, 문서-코드 동기화 습관화
  • 3주차(업무 시작): 예외·폴백 강화, 감정→음악 흐름 정리, 운영 관점 가이드 초안

다음 단계

  • 접근성·알림·데이터 내보내기 등 실무 요구 반영으로 제품성 보강
  • 음악 추천 개인화(히스토리·피드백 루프)와 이미지/영상 생성 파이프라인 정리
  • QA 시나리오와 지표(반응시간, 크래시, 폴백율)로 학습 가능한 운영 사이클 구축

작성자: EmotiFlow 인턴
기간: 2주 개인 프로젝트 + 1주 실무 접목
버전: v1.2 (제출용)

0개의 댓글