Skip to content

ExpeditionMoon/PharmMaster

Repository files navigation

💊 약대장 (PharmMaster)

스마트 복약 관리 & 약사 O2O 상담 플랫폼

Kotlin Compose Hilt Firebase

약대장은 흩어진 복약 정보를 한 곳에서 관리하고, 내 주변의 약사와 1:1로 연결되는 O2O 기반 헬스케어 서비스입니다.


📋 프로젝트 개요

  • 프로젝트명: 약대장 (PharmMaster)
  • 유형: Personal Project (기획/디자인/개발)
  • 기간: 2026.01 ~ 진행 중
  • 상태: 기능 구현 및 고도화 진행 중 (Dev)

📱 Preview

약사 등록 1:1 상담 요청 복약 관리
약사는 약국을 선택해 가입 사용자 → 약사에게 상담 요청 복약 시간·기간 설정 및 알림 등록

✨ 주요 기능

기능 설명
🧾 회원가입 & 약사 등록 사용자 유형(일반/약사)에 따른 분기 처리,
약사는 Google Maps SDK와 Kakao Local API 기반 약국 선택 후 가입
💊 복약 관리 & 알림 약 종류·복용 기간·시간 설정, 묶음 알림(Grouped Notification) 지원, 캘린더 연동
OCR 복약 등록: Google ML Kit 기반 텍스트 추출로 처방전 자동 인식 및 복약 정보 등록 연결
💬 1:1 약사 상담 (O2O) 이미지 첨부가 가능한 상담 글 작성, 공개/비공개 설정, 약사 지정 상담 요청
Firestore SnapshotListener + FCM을 활용한 상담 답변 실시간 푸시 및 UI 반영
👤 마이페이지 복약 기록 캘린더 확인, 상담/답변 내역 관리, 프로필 수정
🔎 약 검색 공공데이터포털 API를 활용한 국내 의약품 검색 및 상세 정보(효능, 주의사항) 제공

상세 기능 소개

각 항목을 클릭하면 상세 실행 화면을 볼 수 있습니다.

🧾 1. 회원가입 (Authentication)
일반 회원가입 약사 회원가입 (약국 선택)
auth-user-signup.mp4

기본 정보 입력으로 간편 가입
auth-pharmacist-signup.mp4

지도에서 근무 약국 선택 후 가입
💊 2. 복약 관리 & OCR 복약 등록 (Medication)
복약 설정 복약 알람 복약 기록 (캘린더)
medication-setting.mp4

복약 시간 및 기간 상세 설정
medication-alarm.mp4

정해진 시간에 복약 푸시 알림
medication-record.mp4

캘린더에서 복약 이력 확인
카메라 OCR 이미지 OCR
medication-ocr-camera.mp4

처방전 촬영 후 텍스트 자동 추출
medication-ocr-gallery.mp4

갤러리 이미지에서 약 정보 인식
💬 3. 약사 상담 (Consultation)
상담글 작성 약사: 글 알림 & 답장 일반: 답장 알림 상담 게시판
consult-write.mp4

사진 첨부 및 상담 내용 작성
consult-reply.mp4

새 상담 알림 수신 및 답변 등록
user-noti.mp4

약사 답변 등록 시 즉시 알림
consult-board.mp4

실시간 동기화되는 상담 목록
👤 4. 내 정보 (My Page)
약사: 나의 답변 내역 일반: 나의 상담 내역 나의 복약 기록 닉네임 수정 & 로그아웃
mypage-answers.mp4

내가 작성한 답변 모아보기
mypage-consults.mp4

나의 상담 질문 및 상태 확인
mypage-medi-his.mp4

월별 복약 달성 현황 확인
mypage-edit.mp4

프로필 관리 및 계정 설정
🔎 5. 약 검색(Search)
약 검색
drug-search.mp4

약 검색

🏗️ 시스템 아키텍처

Clean Architecture 기반 멀티 모듈 구조로 확장성과 유지보수성을 확보했습니다.

시스템구조도

  • :features: 기능별 화면 UI 및 ViewModel (Presentation Layer)
  • :domain: 비즈니스 로직 및 UseCase (Pure Kotlin)
  • :data: 데이터 소스 및 Repository 구현체 (Data Layer)
  • :component-ui: 앱 전반에서 재사용되는 공통 UI 컴포넌트 (Design System)

🛠️ 기술 스택 (Tech Stack)

Tech Stack

사용 라이브러리 및 버전 상세 (Click)
구분 기술 / 라이브러리
Architecture Clean Architecture, MVVM, Multi-Module
Android Kotlin, Jetpack Compose, Hilt, Coroutines, Flow
Network Retrofit2, OkHttp3, Moshi
Database Firebase Firestore (NoSQL)
Location & Map Google Maps SDK, Kakao Local API
Etc Google ML Kit (OCR), Coil (Image Loading)

📐 데이터 모델링

NoSQL 기반의 데이터 구조를 시각화한 초기 설계도입니다.
실제 구현 시에는 Firestore를 도입하여 컬렉션/문서 구조로 최적화했습니다.

Conceptual Data Model
초기 설계 단계의 데이터 구조도 (Conceptual Model)

설계 포인트

  • 조회 성능 최적화 : 약 정보(Medication) 내에 복약 스케줄(schedules)을 포함하여 N+1 쿼리 문제를 방지
  • 데이터 일관성 : 복약 기록(IntakeRecords)은 데이터 양이 많아질 수 있으므로 별도 컬렉션으로 분리하고 참조(Reference) 방식으로 설계

🚀 핵심 기술적 도전

1. 날짜/시간 데이터 타입 설계 최적화

  • 고민
    LocalDateTime(Java8+) 사용 시 모듈 간 의존성 증가와 API 레벨 호환성(@RequiresApi) 이슈 발생
  • 해결
    • Domain / Data Layer: 플랫폼 의존성을 제거하기 위해 Long(Epoch Milli) 타입으로 데이터 이동 및 정렬 처리
    • Presentation Layer: UI 표시 시점에만 LocalDateTime으로 변환하는 Mapper 패턴 적용
      → 모듈 간 결합도를 낮추고 테스트 및 유지보수성 향상

2. Firestore 기반 반응형 상담 게시판 구현

  • 고민
    게시글 형태의 상담 서비스에서 문의 등록이나 답변 완료 시, 새로고침 없이 즉시 UI에 반영되는 사용자 경험 필요
  • 해결
    Firestore SnapshotListener와 Kotlin callbackFlow를 결합하여
    데이터 변경 사항을 실시간 스트림으로 구독하는 구조를 설계하고 게시글 목록을 반응형으로 동기화

3. 지도 API와 로컬 데이터의 효율적 결합

  • 고민
    Google Maps SDK만으로는 국내 약국의 상세 정보 검색에 한계 존재
  • 해결
    지도 렌더링은 Google Maps SDK를 사용하고,
    약국 검색은 정확도가 높은 Kakao Local API를 활용하여 두 서비스를 결합하는 로직 설계

🩺 트러블슈팅

1. Flow 스트림 충돌로 인한 데이터 누락 해결

  • 문제: Flow 연산자 오용으로 인한 일부 데이터 누락 발생  
  • 원인: onStart { emit(Loading) } 적용 후, .first()가 실제 데이터가 아닌 Loading 상태를 수신하고 스트림을 종료함  
  • 해결:   - 단발성 조회용 suspend 함수(getUserOnce()) 분리로 데이터 누락 문제 해결 및 안정성 확보   - withTimeout(5000L) 적용으로 잠재적인 무한 로딩 및 ANR 위험 사전 제거

2. Google Maps 초기화 타이밍 이슈 (Race Condition)

  • 문제: 지도 진입 시 CameraUpdateFactory is not initialized 크래시 발생
  • 원인: Compose 렌더링이 SDK 초기화보다 빨라 발생한 타이밍 충돌
  • 해결:
    • Application.onCreate()에서 MapsInitializer 선행 호출하여 명시적인 초기화 순서 보장
    • 이를 통해 지도 화면 진입 시 간헐적으로 발생하던 크래시를 원천 차단하고 안정적인 사용자 경험(UX) 제공

3. ViewModel 분리 후 상태 동기화 단절 문제 해결

  • 문제: 글 작성 후 목록 화면 복귀 시 데이터 갱신되지 않음
  • 원인: 화면별로 ViewModel을 분리하면서, 화면 간 상태(State) 공유가 단절되어 갱신 트리거 누락
  • 해결:
    • SavedStateHandle을 활용해 이전 화면에 refresh 플래그 전달 및 구독 처리
    • 불필요한 전역 상태(Global State) 남용 없이, 화면 간 결합도를 낮게 유지하면서도 매끄러운 실시간 데이터 동기화 달성

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages