尚未检测到更新。GitHub 发布版本后会显示在这里。
구독을 한 곳에 모아 월 지출·결제일·환율·부가세까지 계산해 주는 구독 관리 서비스. 웹·iOS·Android를 FastAPI 하나로 묶은 풀스택 프로젝트
翻译准备中
正在加载完整 README。
查看完整 README ↗흩어진 구독료를 한 곳에 모아, 매달 얼마가 빠져나가는지 보여주는 구독 관리 서비스
웹 · iOS · Android를 하나의 API로 묶은 풀스택 개인 프로젝트
구독은 한 번에 하나씩 늘어난다. 넷플릭스 하나, 스포티파이 하나, 어느새 노션과 ChatGPT까지. 그래서 "내가 지금 구독에 매달 얼마를 쓰고 있지?" 에 바로 답할 수 있는 사람이 드물다. 결제일은 기억나지 않고, 무료 체험은 조용히 유료로 넘어가고, 해외 서비스는 환율에 부가세까지 붙는다.
SubFlow는 카드사 연동 없이 사용자가 직접 기록하는 방식으로 이 문제를 푼다. 금융기관에 연결하지 않으니 민감정보를 다루지 않고, 대신 카탈로그·환율·부가세·알림으로 기록 비용을 최대한 낮췄다.
| 기능 | 설명 | |
|---|---|---|
| 📚 | 서비스 카탈로그 | 15개 카테고리 · 99종 서비스 · 198개 요금제 내장. 없는 요금제는 직접 입력 |
| 📊 | 대시보드 | 월/연 총지출, 활성 구독 수, 다가오는 결제, 구독 건강 점수 |
| 📈 | 지출 분석 | 카테고리별 비중, 3/6/12/24개월 추이, 절약 제안, 중복 구독 감지 |
| 📅 | 결제 캘린더 | 과거·미래 결제일을 달력에서 한눈에 |
| 🕐 | 타임라인 | 가입·요금제 변경·일시정지·해지 이력 추적 |
| 💱 | 환율 + 부가세 | 외화 구독을 실시간 환율로 KRW 환산, 표시가에 붙는 부가세 10% 반영 |
| 👥 | 분담 계산 | 가족·팀 공유 구독의 1인당 실부담액 계산 |
| 🏠 | 렌탈 약정 | 정수기·비데 같은 렌탈의 약정 기간 기록. 진행률(22/36개월 · 62%), 남은 결제 횟수·금액, 종료 30일 전 알림 |
| 🔔 | 알림 | 결제 N일 전 알림을 이메일 + 푸시로 실제 발송, 주간 다이제스트 |
| 💰 | 예산 | 월 예산 설정 및 초과 경고 |
| 📰 | 뉴스 + AI 요약 | 구독 서비스 관련 뉴스, OpenAI 기반 한 줄 요약 |
| 📤 | 내보내기 | 구독 목록 CSV (UTF-8 BOM, Excel 호환) |
| 🌗 | 기타 | 다크모드, 한/영 다국어, 첫 가입 온보딩, 오류 신고(사진 첨부) |
전 기능 무료. 인앱 결제·광고·트래킹 SDK가 없다.
flowchart LR
User["사용자"]
subgraph Clients["클라이언트"]
Web["Web App<br/>React 19 + Vite<br/><i>Cloudflare Pages</i>"]
Mobile["Mobile App<br/>Expo + React Native<br/><i>App Store / Play</i>"]
Landing["Landing + 약관<br/><i>Cloudflare Pages</i>"]
end
subgraph Api["API 서버 · Railway"]
FastAPI["FastAPI<br/>CORS · Rate limit · Lifespan seed"]
Routers["Routers<br/>auth · services · subscriptions<br/>analytics · notifications<br/>categories · news · feedback"]
Sched["APScheduler<br/>갱신 · 알림 발송 · 뉴스 · 다이제스트"]
end
subgraph Domain["도메인 계층"]
Svc["auth · subscription · analytics<br/>notification · renewal · digest<br/>news · ai_summary · delivery"]
Utils["cost · vat · exchange_rate<br/>seed_data · visibility"]
end
subgraph Data["데이터"]
ORM["SQLAlchemy 2.0 async + Alembic"]
PG[("PostgreSQL 16")]
end
subgraph Ext["외부 서비스"]
Resend["Resend<br/>메일 발송"]
Expo["Expo Push<br/>APNs / FCM"]
FX["Frankfurter<br/>환율"]
OAI["OpenAI<br/>gpt-4o-mini"]
RSS["Google News RSS"]
end
User --> Web & Mobile & Landing
Web -->|"Axios /api/v1<br/>access + refresh token"| FastAPI
Mobile -->|"Axios /api/v1<br/>access + refresh token"| FastAPI
FastAPI --> Routers --> Svc --> ORM --> PG
FastAPI --> Sched --> Svc
Svc --> Utils
Svc --> Resend & Expo & OAI & RSS
Utils --> FX
Python 3.13 FastAPI 0.115 SQLAlchemy 2.0 (async) Alembic · PostgreSQL 16 Pydantic v2 JWT (python-jose) + bcrypt slowapi (rate limit) APScheduler httpx · aiosmtplib OpenAI SDK pytest + pytest-asyncio
React 19 + TypeScript Vite 8 Zustand React Router 7 Tailwind CSS 4 Recharts Axios (JWT 인터셉터) lucide-react react-hot-toast date-fns
Expo SDK 54 React Native 0.81 Expo Router (파일 기반) Zustand + AsyncStorage expo-notifications expo-updates (OTA) Reanimated 4 react-native-svg Axios i18n (한/영) EAS Build / Submit
인프라 — Railway (API + PostgreSQL) · Cloudflare Pages (웹앱 · 랜딩 · 약관) · Resend (메일, 도쿄 리전) · Docker Compose (로컬 풀스택)
Python 3.11+ · Node.js 18+ · Docker Desktop
cp .env.example .env # SECRET_KEY 등을 채운다
docker compose up -d --build
웹 http://localhost:3000 (nginx가 SPA 서빙 + /api → 백엔드 프록시)
# 1. DB
docker compose up db -d
# 2. 백엔드
cd backend
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
alembic upgrade head
uvicorn app.main:app --reload # http://localhost:8000/docs
# 3. 웹
cd frontend && npm install && npm run dev # http://localhost:5173
# 4. 모바일
cd mobile && npm install && npx expo start # Expo Go로 QR 스캔
서비스 카탈로그(99종/198요금제)는 서버 기동 시 lifespan 훅이 자동으로 시드한다.
cd backend && pytest # 14개 파일 / 116개 테스트 — 인증·구독·분석·갱신·부가세·알림
테스트는 subscription_test_db를 따로 만들어 쓴다. .env에서 DB_PORT나
POSTGRES_PASSWORD를 기본값에서 바꿨다면 DATABASE_URL과 TEST_DATABASE_URL을
함께 넘겨야 한다 — 둘 중 하나만 넘기면 테스트 DB 생성 단계에서 막힌다.
| 대상 | 위치 | 명령 |
|---|---|---|
| API | Railway → api.mysubflow.app | railway up (깃 연동 아님, 수동 배포) |
| 웹앱 | Cloudflare Pages → app.mysubflow.app | cd frontend && npm run build 후 업로드 |
| 랜딩·약관 | Cloudflare Pages → mysubflow.app | landing/, legal/ 정적 배포 |
| iOS/Android | EAS Build → App Store / Play | npx eas-cli build -p ios --profile productionnpx eas-cli submit -p ios --latest |
빌드 번호는 eas.json의 appVersionSource: remote + autoIncrement로 EAS가 관리한다 — app.json에서 직접 올리지 않는다.
화면 코드(JS)만 바뀐 수정은 스토어 심사 없이 OTA로 내보낸다:
cd mobile && npx eas-cli update --channel production --message "변경 내용"
runtimeVersion이 fingerprint 정책이라, 네이티브 구성(패키지·플러그인·스플래시 등)이 같은 빌드에만
업데이트가 붙는다. 네이티브를 건드렸다면 app.json의 version을 올려 새로 빌드·제출해야 한다.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗