초안 — 법률 검토 전입니다. 공개 전에 내용이 바뀔 수 있습니다.
개인정보 처리방침
믹스 마스터(이하 "이 앱")는 PIXEL DISTILLERY가 만든 조주기능사 필기·실기 학습 앱이다. 이 문서에서는 이 앱이 어떤 정보를 어디에 얼마나 보관하는지와 삭제 방법을 안내한다.
1. 이 앱이 저장하는 것
이 앱은 별도의 계정 생성 절차 없이 익명 계정으로 시작한다. 기본 학습 기능이 서버 데이터베이스(Supabase Postgres)에 담는 값은 다음과 같다. 커뮤니티를 여는 배포에서 추가로 처리하는 정보는 §1-2에 적었다.
| 항목 | 내용 |
|---|---|
| 익명 계정 식별자 | 서버가 발급한 uid |
| 닉네임 | 사용자가 정한 표시 이름 (순위표에 쓰인다) |
| 학습 진도 | 유닛별 숙련도 |
| 세션 기록 | 점수, 정확도, 소요 시간 |
| 주간 XP | 주간 순위 집계값 |
| 역대 누적 기록 | 역대 순위 집계값 — 전체 기간 XP 합계, 제조 시뮬 시험 최고 점수와 시도 횟수 |
| 제조 시뮬 기록 | 모드, 점수, 완료 시각 |
이메일·실명·전화번호·주소·결제정보를 기본 학습 테이블에 별도 입력받아 저장하지 않는다. 이는 "수집하지 않는다"는 뜻이 아니다. 계정 연결과 광고·구매 서비스에서 처리하는 정보는 §2와 §4에 적었다. 커뮤니티 글과 사진에는 이용자가 직접 입력하거나 선택한 정보가 포함될 수 있다(§1-2).
1-1. 순위표 공개 범위
기본 학습 기능에서 다른 이용자에게 보이는 것은 순위표(리더보드)에 실리는 값뿐이다.
| 순위표 | 다른 이용자에게 보이는 항목 |
|---|---|
| XP (주간 · 역대) | 닉네임, XP 합계, 순위 |
| 제조 시뮬 (주간 · 역대) | 닉네임, 시험 모드 최고 점수, 시도 횟수, 순위 |
- 공개 대상은 Apple 또는 Google 계정을 연결한 계정뿐이다. 연결하지 않은 익명 계정은 순위표와 "내 순위" 어디에도 나오지 않는다.
- 계정을 연결하는 순간, 익명으로 쓰던 기간에 쌓은 누적 기록도 함께 공개된다. 역대 순위는 계정이 만들어진 뒤의 전체 기록을 합산하기 때문이다(주간 순위는 이번 주 몫만).
- uid·이메일·학습 진도·세션별 기록은 순위표에 실리지 않는다.
1-2. 커뮤니티를 여는 배포
Apple 또는 Google 계정을 연결하고 운영 규칙에 동의한 이용자는 글·댓글·사진을 게시할 수 있다. 글 종류는 오늘의 한 잔, 질문, 나만의 레시피다. 레시피 글은 재료명·수량·단위를 함께 저장한다. 게시글에는 사진을 한 장까지 붙일 수 있다. 글·댓글, 표시 이름, 선택한 사진은 다른 이용자에게 보인다. 원본 계정 식별자와 이메일은 게시글에 표시하지 않는다. 신고 내용, 검수 결과, 작성 제한과 이의신청 내용은 공개하지 않는다.
게시한 글·댓글은 먼저 공개되고 자동 검수를 받는다. 검수가 지연되면 게시 후 5분부터 공개 조회에서 빠지며, 위반 또는 판정 불확실성이 확인되면 숨겨질 수 있다. 사진 파일은 비공개 저장소에 보관하고, 공개 가능한 게시글에 한해 짧게 유효한 사진 보기 주소를 발급한다. 글이나 계정을 삭제하면 사진 삭제 작업을 예약한다. 이미 발급된 업로드 주소가 만료된 뒤 정리하도록 사진 파일 삭제를 최소 2시간 10분 늦춘다. 정리 작업이 늦어지면 실제 삭제 시점도 더 늦어질 수 있다.
글·댓글·사진은 자동 검수를 위해 OpenAI API로 전송된다. API 요청에서 응답 저장을 끄더라도 제공자의 오남용 감시 목적 보관까지 없어지는 것은 아니다. 서비스 공개 전 사진·신고·이의신청 기록의 확정 보관 기간, 외부 처리 범위, 처리 위탁 및 국외 이전 항목을 이 문서에 채우고 법률 검토를 받는다. [사용자 기입: 커뮤니티 데이터별 확정 보관 기간과 OpenAI 처리 위탁·국외 이전 고지]
2. 계정을 연결하면 추가로 저장되는 것
Apple 또는 Google로 계정을 연결하면, 제공자가 돌려주는 이메일 주소가 서버의 인증 저장소에 저장된다. Apple의 "이메일 가리기"를 고른 사용자는 비공개 릴레이 주소(…@privaterelay.appleid.com)가 같은 자리에 저장된다.
같은 저장소에 다음도 함께 남는다.
- 제공자 식별자(sub/uid)
- 인증 메타데이터 — 마지막 로그인 시각, 로그인 갱신 토큰 기록
앱 코드가 이 정보를 읽거나 쓰지 않더라도, 이 앱이 보관하는 개인정보이므로 여기에 적는다. 계정을 연결하지 않으면 이 절의 어떤 값도 생기지 않는다.
3. 저장 위치
- 서버: Supabase(Postgres).
- 커뮤니티를 여는 배포의 서버: 게시글·댓글·신고·검수·이의신청 기록은 Supabase Postgres, 게시 사진은 비공개 Supabase Storage에 보관한다. 자동 검수 과정에서 게시 내용과 사진은 OpenAI API로 전송된다(§1-2).
- 기기: 같은 학습 진도가 기기의 SQLite에도 남는다(오프라인 우선 동작). 앱에서 계정을 삭제하면 기기의 학습 데이터(오류 로그 포함)를 비운다. 예외는 §8의 리마인더를 비롯한 이 기기의 표시·알림 설정 한 행과, 이 기기의 동작 기록 몇 가지(처음 쓰는 방법 안내를 이미 보았는지, 오류 자동 보고를 껐는지 같은 이 기기의 선택)이다 — 계정에 속한 값이 아니라 이 기기의 설정이라 남는다. 다만 앱이 스토어 리뷰를 마지막으로 요청한 시각(기기에만 저장되고 서버로 보내지 않는다)은 기기 동작 기록이지만 계정 삭제 시 함께 지운다.
- 기기 — 숨긴 사용자 목록: 리더보드에서 특정 닉네임을 숨기면 그 닉네임 문자열이 같은 설정 행에 최대 200개까지 기기에만 저장된다(§9의 권한과 무관, 서버로 보내지 않는다). 이 목록은 기기의 설정이지만 계정 삭제 시 함께 비워진다. 다른 이용자의 이름을 담고 있기 때문이다.
기기의 입장 하트 잔액·충전 시각·고정 시간대와 광고 표시/보상 중복 방지 내역도 기기에 보관한다. 계정 삭제 후에도 이 단말의 재화와 광고 한도를 유지하기 위해 이 내역은 남는다. 학습 런의 진행 상태와 결과는 계정 삭제 시 지운다.
4. 제3자 제공·추적·분석
- 서버 동기화와 오류 보고는 아래에 적은 서비스로 처리한다. 수익화 기능을 켠 네이티브 배포에서는 광고·구매 서비스에도 정보가 전송된다. 설정이 없는 배포·웹 미리보기에서는 광고·구매 SDK를 초기화하지 않는다.
- 앱 자체의 학습 이용 행태를 분석하는 별도 SDK는 없다. 광고 SDK는 광고 요청·노출·동작·진단 정보를 처리하므로 모든 SDK에 대해 분석이나 식별자 수집이 없다고 말할 수는 없다.
- 광고는 사용자가 선택한 보상광고만 요청하며 비개인화 광고로 요청한다. 비개인화 요청도 SDK의 정보 전송이 없는 것은 아니다. 동의가 필요한 경우 광고 서비스의 동의 화면을 거치고, SDK가 광고 요청을 허용하는 상태일 때만 광고를 요청한다.
오류 수집: Sentry
오류 수집: Sentry(Functional Software, Inc.). 오류 수집 키(DSN)를 넣어 만든 배포 빌드에서, 이용자가 끄지 않았을 때만 켜진다. 목적은 앱 안정성(오류 원인 파악) 하나이고, 광고·추적 목적은 없다.
- 전송 항목: 오류 종류·오류 메시지·스택(코드 위치), 오류가 난 화면 경로와 오류 분류 (
render/sync/db/auth), 오류 직전의 기록(breadcrumb) — 앱의 콘솔 오류 문장, 서버 요청의 방식·응답 코드·쿼리를 뗀 주소 경로, 앱 버전·빌드 환경, 기기 정보(모델·제조사·OS 버전·메모리와 저장공간 상태·화면 크기 등 오류 분석 SDK가 붙이는 기기 문맥), 언어·시간대. - 보내지 않는 것: 이용자 식별자(uid·닉네임·이메일), 기기 이름, 요청 주소의 쿼리·요청 헤더·본문, 화면 캡처·화면 구조, 세션 리플레이, 성능 추적, 사용 세션 집계. 전송 전에 앱 안에서 이메일·JWT·
Bearer토큰·uuid를 가린다(§7의 오류 로그와 같은 마스킹 규칙). 앱 코드는 IP 주소를 보내지 않고 서버의 IP 추정도 요청하지 않는다. 오류 분석 서비스 쪽의 IP 주소 저장 방지·민감정보 자동 제거 설정은 출시 전에 켠다. - 전송 한도: 앱 코드(JS)가 보내는 오류는 한 번 실행에 최대 20건, 같은 오류는 한 번만 보낸다. 앱이 스스로 잡은 오류와 처리되지 않은 오류가 같은 한도를 나눠 쓴다.
- 한계 — 네이티브 크래시: 앱의 네이티브 계층(Android·iOS)이 멈춘 경우의 보고는 위의 20건 한도와 앱 코드의 마스킹 단계를 거치지 않는다. 이 앱은 네이티브 계층에 이용자 입력을 두지 않는다. 네이티브 SDK가 붙일 수 있는 설치 단위 식별자·기기 이름은 오류 분석 서비스 쪽 삭제 규칙으로 지운다.
- 거부 방법과 효과:
프로필 → 문제 신고의 "오류 자동 보고"를 끄기로 바꾼다(기본은 켜기). 끄면 그 즉시 이 기기에서 오류를 보내지 않고(오류 분석 SDK를 닫는다), 다음 실행부터는 SDK를 켜지 않는다. 앱의 다른 기능에는 영향이 없다 — 오류 원인을 찾는 데 쓸 정보가 줄어들 뿐이다. 이 선택은 기기에 저장되고 계정 삭제로도 되돌아가지 않는다. 다시 켜면 그때부터 보낸다. 설정 저장에 실패하면 화면에 알리며, 그때는 다시 끄기를 해야 한다 — 그 실행 동안은 끈 상태가 유지되지만, 저장되지 않은 선택은 다음 실행에 남지 않는다. (한계: 앱이 저장된 선택을 읽기 전 — 데이터베이스가 열리기 전 — 의 오류는 켠 사람의 것도 보내지 않는다.) - 처리 위탁·국외 이전: 수탁자 Functional Software, Inc.(Sentry) · 이전 국가 [사용자 기입: Sentry 조직의 데이터 리전 — 미국 또는 EU] · 이전 항목 위 "전송 항목" · 이전 시기·방법 오류가 날 때마다 전송 구간 암호화(HTTPS)로 · 보유 기간 [사용자 기입: Sentry 플랜의 이벤트 보존 기간] · 거부 방법 위 "거부 방법과 효과".
선택형 보상광고: Google AdMob
수익화 기능을 켠 네이티브 배포에서 이용자가 보상광고를 선택하면 사용한다. 광고 요청과 보상 처리를 위해 광고 시도 식별자와 현재 앱 이용자 식별자가 전달될 수 있다. 앱은 닉네임·이메일·문항 답안을 광고 요청에 넣지 않는다.
광고 SDK는 IP 주소, 기기·계정 식별자, 광고 관련 동작과 진단 정보를 처리할 수 있다. IP로 대략적인 위치를 추정할 수 있으며 Android 광고 식별자 등 실제 항목은 OS·동의·SDK 설정에 따라 달라진다. 이 앱의 비개인화 광고 요청만으로 이러한 처리가 전부 꺼지는 것은 아니다.
- 목적: 광고 제공·보상 처리·부정 이용 방지·광고 진단.
- 이용자 선택: 광고를 시청하지 않아도 자동 충전·무료 복습을 이용할 수 있다. 광고 동의 설정은 앱의 광고 개인정보 선택에서 다시 확인할 수 있다.
- [사용자 기입: Google 광고 서비스의 계약상 제공자·국외 이전 국가·항목·시기·방법·보유 기간·거부 방법 및 효과]
일회성 구매 확인: RevenueCat·앱 스토어
수익화 기능을 켠 네이티브 배포에서 영구 무제한 이용권의 가격·구매·복원·권한을 확인한다. RevenueCat은 앱 이용자 식별자와 구매 이력·상품·거래 및 권한 정보를 처리하며, 스토어와 구매 상태를 확인한다. 앱은 닉네임·이메일을 별도의 구매 고객 속성으로 보내지 않는다. 이 앱은 카드 번호나 결제 비밀번호를 입력받지 않으며, 결제는 스토어가 처리한다.
스토어가 확인한 영구권의 정보는 오프라인에서도 권한을 확인하도록 SDK의 기기 캐시에 남을 수 있다. 기간제 구독이나 자동 갱신 상품은 제공하지 않는다. 앱은 임의의 설정값으로 유료 권한을 만들지 않는다.
- 목적: 구매 확인·무제한 이용권 제공·복원·환불에 따른 권한 갱신.
- 계정 삭제: 이 앱에서 계정을 삭제해도 RevenueCat이나 스토어의 구매 이력이 자동으로 삭제되거나 결제가 환불되지는 않는다. 해당 서비스의 정보 삭제가 필요하면 지원 메일로 요청한다. 운영자가 서비스의 삭제 절차와 스토어의 보존 범위를 확인해 안내한다.
- [사용자 기입: RevenueCat·스토어 서비스의 계약상 제공자·국외 이전 국가·항목·시기·방법·보유 기간·삭제 요청 처리 방법]
5. 보관 기간
서버의 앱 학습 데이터는 계정이 유지되는 동안 보관한다. 삭제를 요청하면 즉시 지운다. 기기 하트·광고 내역과 외부 광고·구매 서비스의 정보는 §3·§4·§6의 별도 범위에 따른다. 그 밖에 서버가 스스로 정리하는 두 가지가 있다. 두 기간은 주 1회 배치로 집행된다.
주간 순위 기록은 8주
주간 XP와 제조 시뮬 주간 최고점(§1)은 8주가 지나면 지워진다. 역대 순위 집계값(전체 기간 XP 합계, 제조 시뮬 시험 최고 점수와 시도 횟수)은 이 정리 대상이 아니다 — 계정이 살아 있는 동안 보관하고, 계정을 삭제하면 함께 지운다.
연결되지 않은 익명 계정은 180일
Apple/Google을 연결하지 않은 익명 계정이 180일 동안 쓰이지 않으면 계정과 연결된 앱 데이터 전부가 지워진다.
계정 연결은 기간과 무관하다. Apple/Google 계정 연결 기록이 남아 있으면 얼마나 오래 쓰지 않았든 이 이유로는 지워지지 않는다. 180일 사용 여부를 확인하는 대상이 아니다.
연결하지 않은 계정에 대해 "쓰이지 않았다"는 아래 네 가지가 180일 안에 하나도 없는 상태를 말한다. 하나라도 있으면 남는다.
- 마지막 로그인
- 앱 실행에 따른 로그인 상태 갱신 — 앱을 열기만 해도 사용한 것으로 본다. 문제를 풀거나 기록을 남기지 않아도, 앱이 켜지면서 로그인 상태를 갱신하는 것만으로 이 신호가 최신이 된다. 학습 기록을 서버에 남기지 않는 기능(오답노트 복습, 필기·실기 모의고사, 제조 시뮬의 시험 외 모드)만 매일 쓰는 경우에도 계정이 지워지지 않는 이유가 이것이다.
- 학습 세션 기록
- 제조 시뮬 기록
익명 계정의 학습 진도는 기기에도 남아 있으므로(§3), 서버 데이터가 삭제돼도 그 기기의 기록은 그대로다. 사라지는 것은 다른 기기로 옮길 수 있었던 백업이다.
6. 삭제 요청 경로와 삭제 범위
앱 안에서 프로필 → 계정 삭제(2단계 확인)로 요청한다.
앱을 지웠거나 열 수 없다면 계정 삭제 요청 안내의 방법으로 요청할 수 있다.
삭제가 지우는 것:
- 서버의 계정 연결 학습 데이터와 커뮤니티 글·댓글·신고·이의신청 기록(§1). 사진 파일은 §1-2의 지연 정리 절차로 삭제한다.
- 기기의 학습 데이터(오류 로그 포함). 예외는 §8의 리마인더를 비롯한 표시·알림 설정 한 행과 기기 동작 기록 몇 가지(§3)다 — 계정에 속한 값이 아니라 이 기기의 설정이고, 동기화되지도 않는다.
- 앱이 스토어 리뷰를 마지막으로 요청한 시각(§3). 기기 동작 기록 가운데 이것만은 지운다.
- 기기의 숨긴 사용자 목록(§3). 설정 행에 있지만 예외가 아니다: 다른 이용자의 닉네임을 담고 있으므로 계정 삭제와 함께 비워진다.
- 기기의 학습 런 진행·결과 기록도 함께 지운다.
남는 것: 이 기기의 하트 잔액·충전 기준·고정 시간대와 광고 표시/보상 중복 방지 내역. 계정 삭제로 새로운 하트나 광고 한도를 지급하지 않는다. 광고 내역은 단말의 시도 식별자와 날짜·상태를 저장하며 학습 답안은 담지 않는다. 이 기기의 내역을 지우려면 앱 데이터를 지우거나 앱을 삭제한다.
외부 광고·구매 서비스와 스토어의 거래 기록은 이 앱 계정 삭제만으로 자동 삭제되거나 환불되지 않는다. 별도 삭제 문의는 지원 메일로 요청한다(§4).
남는 표시·알림 설정에는 학습 리마인더 설정(§8)이 포함된다. 켬/끔과 시각은 기기에만 있으며, 동기화되지 않는다. 지우려면 앱에서 리마인더를 끄거나 앱을 삭제한다.
7. 오류 로그
기기의 SQLite에 최근 50건까지 순환 기록으로 남는다. 한 줄은 시각·종류 (render/sync/db/auth)·화면 경로·드라이버의 원문 메시지다.
error_log표 자체는 서버로 전송되지 않는다. 다만 오류 수집이 켜진 빌드에서는 같은 실패가 §4의 오류 수집(Sentry)으로 가린 형태로 한 번 전송될 수 있다(실행당 최대 20건,프로필 → 문제 신고의 "오류 자동 보고"를 끄면 보내지 않는다).- 기록되는 순간 마스킹 규칙이 이메일·JWT·
Bearer토큰·uuid를 가리므로, uid·이메일·토큰은 열 자체에 남지 않는다. - 진도·점수·닉네임은 애초에 기록 대상이 아니다.
- 사용자가
프로필 → 문제 신고에서 보낼 내용을 먼저 읽고 직접 복사해 외부로 보낼 때만 기기 밖으로 나간다. - 계정 삭제 시 함께 비워진다.
신고 본문에 함께 담기는 것. 신고를 어디서 열었는지에 따라 본문 위쪽에 신고 대상 한 줄이 붙는다. 학습 화면에서 열면 문항 id·유닛·종류와 지문 일부이고, 리더보드에서 행을 길게 눌러 열면 신고 대상의 닉네임·기간(주차 또는 역대)·순위다. 리더보드의 닉네임은 이미 리더보드가 모든 이용자에게 공개하는 값이며, 신고에서 그것을 빼면 무엇을 신고하는지 전할 수 없다. 어느 경우에도 신고하는 사람의 uid·이메일·토큰·점수·진도는 담기지 않는다. 이 본문 역시 사용자가 눈으로 읽고 직접 복사하거나 메일 초안을 열 때만, §11의 지원 메일 주소로 전송된다. 앱이 자동으로 보내지 않는다.
8. 학습 리마인더
사용자가 켠 경우에만, 고른 시각에 기기가 스스로 알림을 띄운다.
- 푸시 토큰을 받지 않고 푸시 알림 서버(FCM/APNs·Expo Push Service)를 쓰지 않는다 — 서버에서 보내는 알림은 없다.
- 알림 본문은 예약 시점에 기기에서 만들어지며 스트릭·XP 같은 숫자를 담지 않는다.
- 켬/끔과 시각은 기기의 설정 한 행에만 있고 동기화되지 않는다.
9. 기기 권한과 센서
아래 표에는 기본 빌드의 권한과 수익화 기능을 켠 배포에서 광고 SDK가 추가할 수 있는 항목을 적었다. 실제 권한은 설치된 빌드의 OS 권한 설정과 SDK 구성에 따른다.
| 권한 / 키 | 플랫폼 | 앱이 쓰는 곳 | 저장·전송 |
|---|---|---|---|
NSMotionUsageDescription | iOS | 제조 시뮬레이션의 셰이크 기법 판정. 기기가 흔들렸는지만 그 순간에 본다 | 없음. 동작 데이터를 저장하지도 전송하지도 않는다 |
NSFaceIDUsageDescription | iOS | 세션 토큰 보관함(Keychain)을 여는 데 OS가 쓴다 | 없음. 생체 정보는 OS 안에서 처리되고 앱은 그 값을 받지 않는다 |
NSPhotoLibraryUsageDescription | iOS | 커뮤니티 글에 붙일 사진 한 장을 이용자가 선택한다 | 선택한 사진을 JPG로 바꿔 비공개 저장소에 업로드한다(§1-2) |
android.permission.POST_NOTIFICATIONS | Android | 학습 리마인더 표시(§8) | 없음 |
android.permission.RECEIVE_BOOT_COMPLETED | Android | 재부팅 후 리마인더 예약 복원 | 없음 |
android.permission.VIBRATE | Android | 즉시 판정 햅틱 | 없음 |
android.permission.INTERNET | Android | 서버 동기화·활성 배포의 광고/구매 확인 | §1·§2·§4 |
android.permission.ACCESS_NETWORK_STATE · android.permission.WAKE_LOCK | Android | 광고 라이브러리의 네트워크 상태·화면 동작 지원 | 광고/구매 SDK 처리 범위는 §4 |
com.google.android.gms.permission.AD_ID | Android | 광고 SDK 의존성이 병합할 수 있는 광고 식별자 권한 | 실제 빌드에서의 수집/사용 범위는 OS·동의·SDK 설정에 따라 달라진다(§4) |
android.permission.MODIFY_AUDIO_SETTINGS | Android | 효과음 재생 전 오디오 모드 설정 | 없음 |
android.permission.READ_EXTERNAL_STORAGE · WRITE_EXTERNAL_STORAGE | Android | 앱 코드가 쓰지 않는다 — 라이브러리가 넣는다 | 없음 |
android.permission.SYSTEM_ALERT_WINDOW | Android | 앱 코드가 쓰지 않는다 — 빌드 도구의 매니페스트 기본값 | 없음 |
마이크 권한은 없다. 소리는 재생 전용이고 녹음 기능을 쓰지 않아, NSMicrophoneUsageDescription과 android.permission.RECORD_AUDIO를 빌드 설정에서 껐다. 카메라·위치·연락처 권한은 없다. 사진은 이용자가 게시할 때 선택한 것만 처리한다.
일부 권한은 앱이 직접 요구한 것이 아니라 사용하는 라이브러리나 빌드 도구가 매니페스트에 병합하는 것이다. 권한 목록에는 나타나므로 여기에 적되, 무엇에 쓰이는지도 함께 적는다.
10. 아동
이 앱은 연령을 수집하지 않는다. 조주기능사는 주류를 다루는 국가기술자격이다. [사용자 기입: 아동 대상 앱 여부와 그 근거(주 이용자층, 콘텐츠 성격) — 스토어에 선언하는 대상 연령과 같게]
11. 문의
개인정보에 관한 문의와 삭제 요청은 지원 메일(support@pixeldistillery.com)로 보낸다. 앱 안에서는 프로필 → 문제 신고에서 보낼 내용을 만들 수 있다.
부록 — 오픈소스 고지
폰트 3종(Do Hyeon · Gothic A1 · Press Start 2P)의 SIL Open Font License 1.1 전문과 사용 패키지 목록은 앱 안에서 프로필 → 앱 정보 → 오픈소스 라이선스로 볼 수 있다.