← Work

Plan Do!

할 일·캘린더·팀 협업·메시지·AI 에이전트·위치 알림을 한 앱에 묶은 생산성 앱. 기획부터 App Store 심사까지 1인으로 만들고 운영합니다.

Year
2026
Role
1인 · 기획 · 디자인 · 풀스택 · 배포 · 운영
Platform
iOS · Web
Web
plando.imjaewoo.dev ↗
App Store
iOS에서 다운로드 ↗
React NativeExpo SDK 56React 19Spring BootSpring AIPostgreSQLAWS Lightsail
Plan Do! 대표 이미지

한눈에

기간2025년 6월 ~ 운영 중 (15개월)
규모커밋 1,319개 · 리포 3개 (iOS 앱 · 백엔드 · 웹)
출시iOS App Store 서비스 중 — 최신 2.0.22

할 일, 캘린더, 팀 협업, 메시지, AI 에이전트, 위치 기반 알림을 한 앱 안에 묶었습니다. 웹 PWA로 시작해 iOS는 Capacitor로 감쌌다가, 모바일을 React Native로 다시 짜서 지금은 네이티브 앱으로 서비스합니다. 백엔드는 한 벌 그대로 두고 프론트만 갈아끼웠습니다.

왜 만들었나

생산성 앱들이 저마다 한 가지에 특화돼 있어서 일정과 메시지 사이를 계속 오가야 했습니다. 혼자 쓰는 도구와 팀에서 쓰는 도구가 갈라져 있는 것도 불편했고요.

결정

웹 PWA로 시작 — React 19 SPA 한 벌로 빠르게 만들고, 쓰면서 필요한 걸 붙여나갔습니다.

iOS는 처음엔 Capacitor — 1인 개발에서는 코드베이스를 하나로 유지하는 게 최우선이었습니다.

모바일은 결국 React Native로 리라이트 — 웹뷰 특유의 버벅임과 네이티브 감 때문에. 백엔드는 안 건드리고 프론트만 다시 짰고, OpenAPI → TS 타입 자동생성으로 API 계약이 어긋날 여지를 없애 리라이트 리스크를 줄였습니다.

AI는 역할로 나누고 도구를 제한 — 하나의 만능 비서 대신 “정리 도우미”, “점검 도우미”처럼 역할을 두고, 각 역할이 쓸 수 있는 도구를 제한했습니다. 무엇을 도와주느냐보다 무엇까지 건드릴 수 있느냐가 사용자에게 더 중요한 구분이라고 봤습니다.

예약 실행은 조회 전용 역할만 — 역할을 시각에 걸어둘 수 있는데, 데이터를 바꾸는 역할은 걸지 못하게 막았습니다. 보고 있지 않은 사이에 마감이 옮겨지면 아침에 열었을 때 누가 한 일인지 알 수 없기 때문입니다. 예약은 알려주기만 하고, 고치는 건 사람이 정합니다.

삭제는 제목이 정확히 맞을 때만 — AI가 “비슷한 제목”으로 엉뚱한 할 일을 지우던 결함을 고치면서 세운 규칙입니다. 여럿이면 되묻고, 지운 뒤엔 무엇을 지웠는지 제목으로 알립니다.

부딪힌 것

코드서명이 이름 충돌로 막힘 — 팀의 배포 인증서가 전부 이름이 같아서, 다른 프로젝트의 키체인이 검색 목록에 끼어 있으면 후보가 여러 개가 되어 codesign이 고르지 못합니다. 익스텐션이 먼저 서명되는 탓에 늘 엉뚱한 자리에서 처음 터져서 원인을 찾기 어려웠습니다.

카카오맵 네이티브 SDK가 RN 0.85에서 동작하지 않음 — 맵 엔진 델리게이트가 끝내 불리지 않아 빈 화면만 나왔습니다. SDK 버전을 내려도 같길래, 지도 탭만 WebView로 카카오 JS SDK를 띄우는 쪽으로 돌렸습니다. 한 탭에 격리하고 나머지는 네이티브로 남겼습니다.

이런 함정은 릴리즈 플레이북에 그때그때 적어둡니다. 같은 데서 두 번 막히지 않으려고요.

결과

  • iOS App Store 서비스 중 — 2.0.22까지 출시. 심사 제출·출시를 App Store Connect API로 자동화
  • 웹 — plando.imjaewoo.dev, 무중단 blue/green 배포
  • 사용 안내서 — 기능을 고치면 안내 문서도 1:1로 같이 고칩니다
  • 위젯·푸시 같은 작은 표면에 대한 반응이 가장 좋았습니다

관련 글

기술 결정은 글로 따로 남겼습니다.