김정원
← 프로젝트 목록

2025.11 — 현재 · 운영 중 · v1.5.2

CCC 커뮤니티

부산CCC 공식 커뮤니티 앱

CCC 커뮤니티 앱 아이콘

개요

대학 선교단체 부산CCC의 공식 커뮤니티 앱입니다. 게시판과 스토리 같은 소셜 기능뿐 아니라 기도·QT·영적 일기, GPS 채플 출석, 제자훈련 콘텐츠, 수련회 외국인 참가자용 실시간 통번역까지 사역 흐름을 한 앱에 모았습니다. React Native(Expo) 앱과 Supabase(Postgres·Auth·RLS·RPC·pg_cron), Deno Edge Functions를 직접 설계·운영하며 유저 400+, MAU 200+, DAU 40+ 규모로 서비스를 키우고 있습니다.

주요 기능

커뮤니티 & 소셜

  • 게시글/댓글/좋아요, 익명 게시, 지역(district)·리더십 게시판, 24시간 이미지 스토리
  • PostRepository 인터페이스 → Supabase 구현체 → Factory로 데이터 접근을 추상화

영성 콘텐츠

  • 기도제목 나눔, 매일 QT 묵상과 그룹 공유/반응, 오늘의 말씀(500구절), 영적 일기, 주간 주보
  • 채플 설교 요약: 관리자 웹에서 Claude structured outputs로 초안 생성 → 앱에서 영상 상단 고정, 타임스탬프 탭 시 해당 지점 재생

채플 출석 & 리더보드

  • GPS 출석 — Haversine 거리, 장소별 반경(기본 150m) 검증, 출석 순간에만 위치 사용
  • pg_cron이 Edge Function을 5분마다 호출해 채플 시작 1시간 전 자동 푸시
  • 학기별 MVP 리더보드·보상, 수련회 출석/리더보드

실시간 통번역

  • 외부 통번역 서버와 WebSocket 직접 연결, 전사문·번역문·TTS 오디오 스트리밍
  • 언어 전환 시 히스토리 재동기화, sinceSeq 기반 재접속 백필, 지수 백오프 + 지터 재연결
  • 프로토콜 명세 문서화와 로컬 mock 서버 스크립트 작성

제자훈련 · 게임화 · 소그룹

  • 트랙 → 코스 → 강의 → 섹션 → 블록 계층. 보충설명은 기본 접힘, 예화는 카드, 성경구절은 칩+바텀시트
  • 활동별 XP와 일일 제한, 레벨·배지, 업적 신청 후 관리자 승인(거절 사유 포함)
  • 그룹 생성/활동, 공유 비율 기반 트렌딩, 같은 그룹만 프로필 조회 가능한 RLS

운영

  • 개발자 모드, 앱 버전 강제 업데이트, 계정 삭제·알림 설정 RPC, 라이트/다크 테마
  • 알림 유형별 딥링크(route:id) 라우팅, EAS Build(dev/preview/production)와 OTA

문제와 개선

OTA 사고 방지 설계

AS-IS

네이티브 변경이 섞인 JS 번들을 구버전 빌드에 OTA로 내보내면 런타임이 깨질 수 있습니다. 스토어 심사 없이 핫픽스를 보내는 환경일수록 이 위험이 커집니다.

TO-BE

runtimeVersion을 fingerprint 정책으로 두어 네이티브에 영향을 주는 변경이 생기면 런타임 버전을 자동으로 올립니다. JS만 바뀐 수정은 EAS Update로 배포하고, 네이티브가 바뀌면 새 빌드를 올리도록 사고 경로를 구조적으로 차단했습니다.

푸시 신뢰성의 닫힌 루프

AS-IS

푸시를 보내기만 하면 실패 토큰과 유실을 추적하기 어렵습니다. 알림이 안 갔는지, 토큰이 죽었는지 구분이 안 됩니다.

TO-BE

DB 트리거 → Edge Function → Expo Push API로 발송한 뒤 티켓 ID를 저장하고, 5분 후 receipts API를 배치 조회해 실패 토큰을 정리합니다. 소그룹 공지·수련회/채플 출석 등 목적별 Edge Function을 분리해 유실을 추적할 수 있게 했습니다.

보안 로직의 단일 소스

AS-IS

통번역 비공개 세션 비밀번호를 앱과 관리자 웹에서 각각 해시해 검증 방식이 어긋났고, 로그인이 실패하는 버그가 났습니다.

TO-BE

해시 생성·검증을 Postgres 함수(SECURITY DEFINER, pgcrypto bcrypt)로 일원화했습니다. 시도 제한(10분 8회)도 DB에서 처리해 클라이언트 간 불일치를 원천 제거했습니다.

RLS 중심 권한 설계

AS-IS

프로필·일기·소그룹 데이터를 앱 단에서만 가리면 클라이언트를 우회했을 때 접근 제어가 무너집니다.

TO-BE

같은 그룹 멤버만 프로필을 볼 수 있는 정책, 일기 공유 범위 등을 Postgres RLS로 처리했습니다. 멤버 수 집계도 트리거로 유지해 권한과 집계의 기준을 DB에 두었습니다.

설계에서 남긴 판단

콘텐츠 UX를 원문 문법에서 설계

제자훈련 원문의 명제/보충/예화/구절 문법을 분석해 저피로 읽기 UI로 바꿨습니다. 설계는 docs/discipleship-design.md를 기준으로 강의별 퀴즈와 개발자 프리뷰 게이팅까지 이어집니다.

관리자 웹과의 계약

채플 요약·통번역 세션은 별도 Next.js 관리자 웹에서 등록하고 앱은 소비합니다. 스키마 마이그레이션과 프로토콜 문서로 계약을 고정해 1인 개발에서도 경계를 명확히 했습니다.

회고

사역 현장을 아는 상태로 기획부터 운영까지 혼자 닫아 보니, 기능 추가보다 권한·배포·알림처럼 깨지면 공동체가 멈추는 축을 먼저 단단히 하는 일이 중요하다는 걸 배웠습니다. 앱과 관리자 웹, 통번역 서버의 계약을 문서와 DB 함수로 고정한 뒤에야 안정적으로 기능을 쌓을 수 있었습니다.