Web 2025.01 · Mobile 2025.11 — 현재 · 운영 중 · 가입 400+ · MAU 200+
CCC Community Platform
Mobile App + Web Admin Dashboard
개요
대학 선교단체 부산CCC의 커뮤니티 플랫폼입니다. 사용자는 React Native · Expo 앱으로 커뮤니티, 채플 출석, 수련회, 실시간 통번역 기능을 이용하고, 운영진은 Next.js 기반 Web Admin Dashboard에서 출석 · 수련회 · 콘텐츠 · 실시간 통역처럼 흩어져 있던 운영 업무를 한곳에서 관리합니다. 서비스 기획부터 Frontend · Backend · 배포 · 운영까지 혼자 맡았고, Supabase Auth · RLS · RPC · Edge Functions로 사용자 앱과 관리자 웹의 공통 데이터와 접근 권한을 관리합니다.
주요 기능
Web Admin Dashboard
- Next.js 기반 Back Office 설계 및 개발
- Zod Schema와 Resource Config 기반 공통 CRUD 구조 구현
- 8개 리소스의 데이터 관리 및 권한 검증 기능 통합
- 학기별 출석 집계 · 순위 조회 · Excel 다운로드
Mobile App
- React Native · Expo 기반 iOS/Android 앱 개발 및 배포
- 인증 세션 복원, Push Notification 및 OTA 업데이트 구현
- WebSocket 기반 실시간 통역 데이터 수신 및 연결 복구
- Push 수신 → 대기열 진입 → 현장 위치 확인 → 출석으로 이어지는 출석 흐름
실시간 통번역
- 외국인 유학생을 위한 다국어 통역 자막과 음성 제공
- 관리자 웹에서 음성을 송출하면 통역 서버가 STT → 번역 → TTS로 처리
- 모바일 앱은 JWT · RLS로 직접 접근해 실시간 구독
Backend & Operation
- Supabase Auth · RLS · RPC · Edge Functions 기반 서비스 연동
- 사용자 앱과 관리자 웹의 공통 데이터 및 접근 권한 관리
- Edge Function이 5분마다 채플 일정을 확인해 출석 알림 Push 발송
- 서비스 배포와 운영 과정의 오류 대응 및 유지보수
문제와 개선
WebSocket 연결이 끊긴 동안의 자막 누락 복구
AS-IS
외국인 유학생이 설교를 실시간으로 이해할 수 있도록 다국어 통역 자막을 제공하는데, 연결이 끊긴 동안 서버가 보낸 문장은 앱에 도달하지 않아 다시 연결해도 그 구간이 비는 문제가 있었습니다.
TO-BE
45초 무수신과 포그라운드 복귀로 수신 중단을 감지하고, 1초부터 최대 15초까지 백오프하며 WebSocket을 자동 재연결합니다. 재연결하면서 마지막으로 받은 seq를 sinceSeq로 보내면 서버가 그 이후의 확정 문장만 history로 다시 보내 주고, 앱은 seq 순으로 삽입하며 같은 id를 병합해 빠진 문장을 순서대로 채웁니다.
출석 알림 직후 몰리는 요청 — GCRA 가상 대기열
AS-IS
출석 알림 직후 다수 사용자의 요청이 짧은 시간에 집중되면서 DB가 과부하되어 서비스가 중단되었습니다.
TO-BE
RPC가 처리 슬롯을 배정하는 GCRA 기반 가상 대기열을 구현하고, 출석 INSERT RLS에서 슬롯 통과 여부를 검증해 앱을 거치지 않는 우회를 차단했습니다. 300개 테스트 클라이언트로 동시 요청을 재현해 대기 → 순번 감소 → 출석 완료 흐름을 검증했고, 테스트 중 중복 출석은 발생하지 않았습니다.
8개 관리 리소스를 하나의 CRUD 구조로
AS-IS
출석 · 수련회 · 콘텐츠 · 실시간 통역 등 운영 기능이 흩어져 있었고, 관리 화면을 추가할 때마다 데이터 관리와 권한 검증을 리소스별로 반복 구현해야 했습니다.
TO-BE
Zod Schema와 Resource Config 기반의 공통 CRUD 구조를 8개 관리 리소스에 적용해 중복 구현을 줄이고 관리 화면을 확장할 수 있는 구조를 마련했습니다. 분산된 운영 기능은 하나의 Web Admin Dashboard로 통합했습니다.
설계에서 남긴 판단
규칙은 DB가 검사
본인 여부 · 출석 가능 시간 · 대기열 통과는 INSERT RLS 정책이, 중복 출석은 UNIQUE 제약이 막아 앱을 거치지 않은 요청도 걸러냅니다.
몰려도 버티는 대기열
알림 직후 몰리는 순간에는 초당 입장 인원(기본 30명, 운영 중 조정 가능)만큼씩 순서대로 들여보냅니다.
화면과 엑셀이 같은 숫자
조회와 내보내기가 같은 집계 함수를 써서, 화면에서 본 값이 그대로 엑셀에 담깁니다.
화면
회고
사용자 앱과 관리자 웹을 함께 운영하면서, 화면에서 드러나는 문제의 상당수가 연결 · 권한 · 동시성처럼 보이지 않는 경계에서 시작된다는 것을 배웠습니다. 연결이 끊겨도 자막이 이어지고 요청이 몰려도 출석이 한 번만 기록되도록, 클라이언트와 서버의 책임을 함께 설계하는 것이 사용자 경험을 지키는 방법이라고 생각합니다.