개인용 일기 앱

약 4년간 직접 사용하며 개선해 온 개인 일기 서비스.

Overview

2022년부터 현재까지 직접 사용하며 기능을 개선하고, 실제 사용 과정에서 발견한 요구사항에 맞춰 여러 차례 재설계한 일기 서비스입니다.

Motivation

2020년부터 카카오톡 나와의 채팅방에 일기를 작성했지만, 지난 기록을 찾아보거나 날짜별로 관리하기 어려웠습니다. 기록의 가독성과 접근성을 높이고 원하는 기능을 직접 추가하기 위해 일기 서비스를 개발했습니다.

Stack

기술 선택 이유

Android Jetpack

위젯, 생체 인증 등 안드로이드 네이티브 기능을 연동하기 위해 사용했습니다.

Next.js

웹과 안드로이드 WebView에서 하나의 UI를 재사용하고, 사용자 인증을 처리하기 위해 사용했습니다.

Spring Boot

일기와 미디어 데이터를 관리하는 REST API를 구현하고 저장소별 백업 로직을 운영하기 위해 사용했습니다.

TanStack Query

일기 데이터를 캐싱하고 Optimistic 업데이트와 Infinite Query를 구현하기 위해 사용했습니다.

TanStack Virtual

장기간 누적된 일기 목록에서 화면에 보이는 항목만 렌더링해 스크롤 성능을 개선하기 위해 사용했습니다.

PostgreSQL

날짜별 일기 내용과 관련 데이터를 영속적으로 저장하기 위해 사용했습니다.

Key Features

  • 텍스트, 사진, Spotify 음악을 조합한 일기 작성과 미디어 업로드 진행률·재시도 지원
  • 캘린더·키워드 검색과 검색어 강조를 통한 과거 일기 조회
  • 홈 화면 위젯을 통한 일기 작성 화면 빠른 실행
  • 생체 인증을 활용한 앱 잠금 및 개인 기록 보호

Architecture

  • Next.js로 구현한 UI를 웹과 Android WebView에서 함께 사용하고, 네이티브 기능은 JavaScript Interface를 통해 연결했습니다.
  • 웹과 백엔드 모두 presentation/application/domain/infrastructure 계층으로 나누고, 인터페이스와 의존성 주입을 활용해 구현체를 교체할 수 있도록 구성했습니다.
  • Spring Boot REST API가 일기 데이터를 PostgreSQL에 저장하고, 사진은 로컬 파일 시스템과 Firebase Storage에 각각 저장하도록 구성했습니다.
  • PostgreSQL 원본과 별도로 Firestore 백업을 운영하며, 백업되는 일기 내용은 AES/GCM으로 암호화했습니다. Android 앱은 생체 인증 잠금 화면으로 기록 접근을 보호했습니다.
  • Android WebView에서는 TanStack Query 캐시를 IndexedDB에 영속화하고, 월별 Infinite Query와 가상화 목록을 결합해 누적된 일기를 효율적으로 조회하도록 구성했습니다.
  • TanStack Query 캐시와 Optimistic 업데이트를 적용해 일기 작성 결과를 즉시 반영하고, 실패 시 이전 데이터로 복구하도록 구성했습니다.

Result

2022년부터 현재까지 실제 일기 기록에 사용하며, 누적 데이터의 조회 성능과 다중 저장소 백업 신뢰성을 개선하는 등 장기간 운영 과정에서 생긴 요구사항을 지속적으로 반영했습니다.

Troubleshooting

문제와 해결

웹 UI를 안드로이드에서도 재사용하면서 생체 인증, 위젯 같은 네이티브 기능을 사용해야 했던 문제

Next.js 화면을 WebView로 제공하고 JavaScript Interface와 기능별 provider를 구현해 웹 코드와 안드로이드 네이티브 기능을 연결했습니다.

PostgreSQL 원본과 Firestore 백업, 로컬 파일 시스템과 Firebase Storage 사이에 누락이나 불일치가 생겨도 즉시 확인하기 어려운 문제

정기 백업 감사 작업에서 일기 원본과 Firestore 백업을 비교하고, 미디어는 크기와 MD5 지문을 저장소별로 검증했습니다. 불일치와 오류는 Telegram 알림으로 전달하도록 구성했습니다.

고용량 사진을 그대로 업로드하면 전송 시간이 길어지고 저장 공간을 많이 사용하는 문제

업로드 전에 브라우저에서 사진을 압축하고, 업로드 진행률과 실패 시 재시도 기능을 제공하도록 구현했습니다.

일기 작성 후 서버 응답을 기다리는 동안 새 기록이 바로 화면에 표시되지 않는 문제

TanStack Query의 Optimistic 업데이트로 작성 내용을 즉시 캐시에 반영하고, 요청 실패 시 기존 데이터로 롤백하도록 구현했습니다.

장기간 누적된 일기를 한 목록에 렌더링하면서 스크롤 성능이 저하되고 특정 날짜 이동 위치가 부정확해지는 문제

TanStack Virtual로 화면 주변 항목만 렌더링하고, 동적 높이를 측정한 뒤 requestAnimationFrame으로 목표 날짜 위치를 보정했습니다.