Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

모바일 앱(안드로이드)

프레시틱 (Freshtic) 개발 작업 히스토리

Billcorea 2026. 2. 18. 21:27

프레시틱 (Freshtic) 개발 작업 히스토리

프로젝트 개요

  • 프로젝트명: Freshtic (Fresh + Tactic)
  • 목적: 유통기한(또는 사용자 정의 기한) 관리를 통해 음식물 폐기(낭비)를 줄이는 로컬 중심 Android 앱
  • 버전: v1.0 (오프라인 완결)
  • 개발 기간: 2026.02.17 ~
  • 기술 스택: Kotlin, Jetpack Compose, Room, Hilt, WorkManager (예정), CameraX + ML Kit (예정)

📋 Plan.pptx 대비 진행 상황

완료된 단계

1단계: 프로젝트 설정 및 테마 적용 ✅ 100% 완료

Plan 요구사항:

  • 프로젝트 초기 설정
  • Material 3 테마 적용
  • 색상 시스템 (Light/Dark)
  • 타이포그래피 (Noto Sans KR)

구현 완료:

✅ Kotlin 2.3.10, KSP 2.3.2 적용
✅ Gradle 9.0.1, AGP 최신 버전
✅ Hilt 2.59.1 설정 완료
✅ Room 2.8.4 설정 완료
✅ Material 3 테마 완전 구현
   - Color.kt: Light/Dark 색상 각 38개 정의
   - Theme.kt: lightScheme, darkScheme 완성
   - Type.kt: Material 3 Typography 전체 정의
✅ Google Fonts (Noto Sans KR) 적용
   - font_certs.xml 생성
   - ui-text-google-fonts 라이브러리 추가
✅ AndroidManifest.xml 카메라 권한 설정

파일 구조:

ui/theme/
├── Color.kt          # 76개 색상 (Light/Dark/Contrast variants)
├── Theme.kt          # Material 3 테마 설정
└── Type.kt           # Noto Sans KR 타이포그래피

res/values/
└── font_certs.xml    # Google Fonts 인증서

2단계: 데이터 레이어 구축 (Room Database) ✅ 100% 완료

Plan 요구사항:

  • Entity 정의 (ItemEntity, BarcodeCacheEntity)
  • Enum 클래스 (DateType, StorageType, ItemStatus)
  • TypeConverter (LocalDate, Instant, Enum)
  • DAO 인터페이스 (ItemDao, BarcodeCacheDao)
  • Database 클래스
  • Repository 패턴 적용

구현 완료:

✅ Domain Model (Enum 클래스)
   - DateType: EXPIRY(유통기한), USER_DEFINED(사용자 정의)
   - StorageType: ROOM(실온), FRIDGE(냉장), FREEZER(냉동)
   - ItemStatus: ACTIVE(활성), CONSUMED(소비), TRASHED(폐기)

✅ Room Entity
   - ItemEntity: 11개 필드, 인덱스 3개 (status, targetDate, barcode)
   - BarcodeCacheEntity: 바코드 재스캔 시 상품명 자동완성

✅ TypeConverter
   - LocalDate ↔ Long (epochDay)
   - Instant ↔ Long (epochMilli)
   - Enum ↔ String (name)

✅ DAO 인터페이스
   - ItemDao: 14개 메서드
     * CRUD 기본 (insert, update, delete, getById)
     * 홈 화면용 쿼리 (getAllActive, getUpcoming, getExpired)
     * 검색/필터 (searchByName, getByStorageType)
     * 알림용 (getAllActiveItems)
   - BarcodeCacheDao: 4개 메서드 (upsert, getByBarcode, deleteOld)

✅ Repository
   - ItemRepository: 비즈니스 로직 중앙 관리
   - 바코드 캐시 자동 upsert
   - WorkManager 연동 준비 (TODO 마커)

✅ Hilt DI
   - DatabaseModule: Database, DAO 제공

파일 구조:

domain/model/
├── DateType.kt
├── ItemStatus.kt
└── StorageType.kt

data/local/
├── entity/
│   ├── ItemEntity.kt
│   └── BarcodeCacheEntity.kt
├── dao/
│   ├── ItemDao.kt
│   └── BarcodeCacheDao.kt
├── converter/
│   └── RoomTypeConverters.kt
└── db/
    └── FreshticDatabase.kt

data/repository/
└── ItemRepository.kt

di/
└── DatabaseModule.kt

Plan 대비 차이점:

  • ✅ Plan의 모든 쿼리 요구사항 구현됨
  • ✅ 인덱스 최적화 적용 (Plan 권장사항)
  • ⚠️ WorkManager 알림 연동은 아직 TODO (4단계 예정)

3단계: UI 기본 구조 및 네비게이션 ✅ 85% 완료

Plan 요구사항:

  • 5개 화면 구현 (홈, 스캔, 등록/수정, 상세, 설정)
  • Navigation 설정
  • 각 화면 기본 UI
  • ViewModel 연동

구현 완료:

✅ Navigation 설정
   - Screen.kt: 5개 라우트 정의
   - FreshticNavGraph.kt: 네비게이션 그래프
   - 딥링크 지원 (freshtic://items/{itemId})
   - 파라미터 전달 (itemId)

✅ 홈 화면 (HomeScreen.kt + HomeViewModel.kt)
   - 임박 섹션 (0~3일) ✅
   - 전체 목록 (targetDate 오름차순) ✅
   - D-day 자동 계산 및 색상 구분 ✅
   - FAB (+버튼) → 스캔 화면 이동 ✅
   - Empty/Loading 상태 처리 ✅
   - Flow 기반 실시간 업데이트 ✅

✅ 바코드 스캔 화면 (BarcodeScanScreen.kt)
   - 기본 레이아웃 완성 ✅
   - "직접 입력" 버튼 → 등록 화면 이동 ✅
   - ⚠️ CameraX + ML Kit 구현 예정 (TODO)

✅ 등록/수정 화면 (AddEditItemScreen.kt + AddEditItemViewModel.kt)
   - 기본 레이아웃 완성 ✅
   - itemId 파라미터 처리 ✅
   - ⚠️ 폼 필드 구현 예정 (다음 단계)

✅ 상세 화면 (ItemDetailScreen.kt + ItemDetailViewModel.kt)
   - 기본 레이아웃 완성 ✅
   - Loading/Error/Success 상태 처리 ✅
   - 소비/폐기 버튼 UI ✅
   - ⚠️ 실제 동작 구현 예정 (다음 단계)

✅ 설정 화면 (SettingsScreen.kt)
   - 알림 on/off Switch ✅
   - 앱 정보 표시 ✅
   - ⚠️ 실제 설정 저장 로직 예정 (4단계)

✅ MainActivity 통합
   - FreshticNavGraph 적용 ✅
   - enableEdgeToEdge ✅

파일 구조:

navigation/
├── Screen.kt
└── FreshticNavGraph.kt

ui/
├── home/
│   ├── HomeScreen.kt
│   └── HomeViewModel.kt
├── scan/
│   └── BarcodeScanScreen.kt
├── addedit/
│   ├── AddEditItemScreen.kt
│   └── AddEditItemViewModel.kt
├── detail/
│   ├── ItemDetailScreen.kt
│   └── ItemDetailViewModel.kt
└── settings/
    └── SettingsScreen.kt

Plan 대비 차이점:

  • ✅ 모든 화면 기본 구조 완성
  • ✅ Material 3 디자인 적용 (Plan 요구사항)
  • ⚠️ Icons 라이브러리 미사용 (Text로 대체, 추후 추가 예정)
  • ⚠️ 검색/필터 UI는 다음 단계 예정
  • ⚠️ 하단 배너 광고는 추후 구현 예정

🚧 진행 중 / 예정 단계

4단계: 상세 기능 구현 🔄 0% (다음 단계)

Plan 요구사항:

  • 등록 폼 완전 구현
    • 상품명 입력 (필수)
    • 날짜 선택 (DatePicker)
    • 날짜 타입 선택 (유통기한 / 내가 정한 기한)
    • 보관 타입 선택 (실온/냉장/냉동)
    • 메모 입력 (선택)
    • 사진 첨부 (선택)
    • 바코드 자동 채우기
  • 상세 화면 완성
    • 모든 정보 표시
    • 소비/폐기 처리 로직
    • Undo 스낵바 (Plan 권장사항)
  • 검색/필터 기능
    • 상품명 검색
    • 보관 타입 필터
    • 상태 필터 (정상/임박/만료)

예상 파일:

ui/addedit/
├── components/
│   ├── DateTypeSelector.kt
│   ├── StorageTypeSelector.kt
│   └── DatePickerDialog.kt

5단계: 바코드 스캔 구현 🔄 0% (예정)

Plan 요구사항:

  • CameraX 통합
  • ML Kit Barcode Scanner
  • 권한 처리 (CAMERA)
  • 스캔 성공/실패 처리
  • 토치, 사진 모드 전환
  • 저조도/흔들림 대응

필요 라이브러리:

// build.gradle.kts 추가 예정
implementation("androidx.camera:camera-camera2")
implementation("androidx.camera:camera-lifecycle")
implementation("androidx.camera:camera-view")
implementation("com.google.mlkit:barcode-scanning")

6단계: 알림 시스템 (WorkManager) 🔄 0% (예정)

Plan 요구사항:

  • ExpiryNotificationWorker 구현
  • RescheduleExpiryWorker 구현
  • D-3 (20:00) 알림
  • D-0 (20:00) 알림
  • UniqueWork 관리 (expiry_${itemId}_D3/D0)
  • Tag 관리 (expiry_notifications)
  • 소비/폐기 시 알림 취소
  • 설정 변경 시 재스케줄링

예상 파일 구조:

worker/
├── ExpiryNotificationWorker.kt
├── RescheduleExpiryWorker.kt
└── WorkerKeys.kt

notification/
├── NotificationHelper.kt
└── NotificationChannels.kt

7단계: 광고 통합 🔄 0% (예정)

Plan 요구사항:

  • Google AdMob 통합
  • 홈 화면 하단 배너 광고 1개
  • 광고 로딩 실패 처리

📊 전체 진행률

단계 항목 진행률 상태
1 프로젝트 설정 및 테마 100% ✅ 완료
2 데이터 레이어 (Room) 100% ✅ 완료
3 UI 기본 구조 85% ✅ 완료
4 상세 기능 구현 0% 🔄 예정
5 바코드 스캔 0% 🔄 예정
6 알림 시스템 0% 🔄 예정
7 광고 통합 0% 🔄 예정
전체 MVP 완성도 ~40% 🚀 진행 중

🏗️ 현재 아키텍처

Clean Architecture 구조

app/
├── data/                    # 데이터 레이어
│   ├── local/              # Room Database
│   │   ├── entity/         # DB 엔티티
│   │   ├── dao/            # DB 접근
│   │   ├── converter/      # 타입 변환
│   │   └── db/             # Database 클래스
│   └── repository/         # Repository 패턴
│
├── domain/                  # 도메인 레이어
│   └── model/              # 비즈니스 모델 (Enum)
│
├── ui/                      # Presentation 레이어
│   ├── home/               # 홈 화면
│   ├── scan/               # 스캔 화면
│   ├── addedit/            # 등록/수정 화면
│   ├── detail/             # 상세 화면
│   ├── settings/           # 설정 화면
│   └── theme/              # Material 3 테마
│
├── navigation/              # 네비게이션
│
├── di/                      # Dependency Injection
│
└── worker/                  # Background 작업 (예정)

의존성 그래프

UI Layer (Compose + ViewModel)
    ↓
Repository Layer
    ↓
Data Source Layer (Room DAO)
    ↓
Database (Room)

🔧 기술적 특징

1. LocalDate / Instant 사용

  • Java 8+ Date/Time API 활용
  • Room TypeConverter로 자동 변환
  • 타임존 안전성 확보 (Plan 요구사항)

2. Flow 기반 반응형 프로그래밍

// 실시간 데이터 업데이트
fun getAllActiveItems(): Flow<List<ItemEntity>>

3. Material 3 디자인 시스템

  • Dynamic Color 지원 (Android 12+)
  • Light/Dark 테마 완벽 지원
  • Noto Sans KR 폰트 적용

4. Hilt 의존성 주입

  • Singleton Repository
  • ViewModel 자동 주입
  • Database 모듈 분리

5. Navigation Component

  • Type-safe navigation
  • 딥링크 지원
  • SavedStateHandle 파라미터 전달

📝 Plan.pptx 준수 사항

완벽히 준수한 항목

  1. 데이터 설계
    • ✅ targetDate 하나로 통일 (dateType으로 구분)
    • ✅ 인덱스 (status, targetDate, barcode)
    • ✅ TypeConverter 정확히 구현
    • ✅ BarcodeCacheEntity 정책대로 구현
  2. DAO 설계
    • ✅ Plan의 모든 쿼리 구현
    • ✅ 표시 상태 계산 로직 (targetDate 기준)
    • ✅ Flow 기반 반응형
  3. Repository 책임
    • ✅ DB 변경 후 스케줄 연동 (TODO 준비)
    • ✅ 바코드 캐시 upsert
  4. UI/플로우
    • ✅ 5개 화면 모두 생성
    • ✅ 홈 임박 섹션 구현
    • ✅ D-day 계산 및 표시

⚠️ 부분 구현 / 예정 항목

  1. 바코드 스캔
    • ⚠️ 기본 UI만 완성
    • 🔄 CameraX + ML Kit 구현 예정
  2. 등록 폼
    • ⚠️ 기본 레이아웃만 완성
    • 🔄 모든 필드 구현 예정
  3. 알림 시스템
    • ⚠️ Repository에 TODO 마커만
    • 🔄 WorkManager 구현 예정
  4. 광고
    • 🔄 AdMob 통합 예정

Plan과 다른 점

  1. Icons 사용
    • Plan: Material Icons 사용 예상
    • 실제: Text로 임시 대체 (빌드 속도 우선)
    • 계획: 추후 material-icons-extended 추가
  2. OCR 유통기한 인식
    • Plan: Won't for v1 (명시적 제외)
    • 실제: 구현 안 함 (Plan 준수)
  3. 커뮤니티 기능
    • Plan: Won't for v1 (명시적 제외)
    • 실제: 구현 안 함 (Plan 준수)

🐛 알려진 이슈 및 해결

1. Kotlin/Hilt 버전 호환성

  • 문제: Kotlin 2.3.2 + KSP 호환 이슈
  • 해결: Kotlin 2.3.10, KSP 2.3.2로 조정

2. 파일 인코딩 문제

  • 문제: PowerShell 정규식으로 한글 깨짐
  • 해결: 파일별 수동 수정

3. Material Icons 의존성

  • 문제: icons 라이브러리 누락
  • 해결: Text로 임시 대체 (빌드 우선)

📚 다음 작업 우선순위

즉시 착수 (4단계)

  1. ✅ 등록 폼 완전 구현
    • DatePicker 통합
    • 모든 필드 검증
    • 저장 로직 완성
  2. ✅ 상세 화면 완성
    • 소비/폐기 처리
    • Undo 기능
  3. ✅ 검색/필터 UI

중요 (5단계)

  1. 🔄 바코드 스캔
    • CameraX 설정
    • ML Kit 통합
    • 권한 처리

핵심 기능 (6단계)

  1. 🔄 알림 시스템
    • WorkManager 구현
    • D-3, D-0 알림
    • 스케줄 관리

부가 기능 (7단계)

  1. 🔄 광고 통합
  2. 🔄 Material Icons 추가
  3. 🔄 최종 테스트 및 최적화

🎯 v1.0 릴리즈 체크리스트

  • 프로젝트 설정
  • Room Database
  • Navigation 설정
  • 홈 화면
  • 등록 폼 (진행 중)
  • 바코드 스캔
  • 알림 시스템
  • 광고
  • 최종 테스트
  • 릴리즈 빌드

예상 완성도: 40% → 100% (약 60% 남음)


📌 참고 문서

  • documents/plan.pptx - 전체 기획안
  • documents/README.md - Material Theme 가이드
  • gradle/libs.versions.toml - 의존성 버전 관리

마지막 업데이트: 2026-02-17
작성자: AI Assistant
프로젝트 상태: 🚀 활발히 개발 중

반응형