Skip to content

Latest commit

 

History

History
186 lines (166 loc) · 14.5 KB

File metadata and controls

186 lines (166 loc) · 14.5 KB

몽그루 품질 검증 기준

최종 갱신: 2026-08-06

현재 반복 실행할 수 있는 검사와 아직 확인하지 못한 항목을 기록한다. 기능·UI·콘텐츠를 바꾼 뒤에는 자동 검사와 주요 사용자 흐름을 다시 확인한다.

1. 자동 검사

영역 명령 현재 기준
Flutter 정적 분석 cd app; dart analyze 경고·오류 0
Flutter 단위/위젯 cd app; flutter test 전체 통과, 실패·건너뜀 0
Web 릴리스 빌드 cd app; flutter build web --wasm --release --no-web-resources-cdn --dart-define=API_BASE_URL=... 성공
서버 전체 cd server; pytest -q 전체 통과, 실패·건너뜀 0
Python import/문법 python -m compileall server/app server/tests 성공
API 계약 cd server; python -m app.export_openapi server/openapi.json과 일치
Python 보안 감사 lock export 후 pip-audit 알려진 취약점 0
저장소 보안 감사 Trivy filesystem(vuln,misconfig, HIGH/CRITICAL) lockfile 취약점 0, Dockerfile 위반 0
GitHub Actions actionlint 오류 0, 외부 action commit SHA 고정
공백·줄끝 검사 git diff --check 오류 0

Android APK/AAB는 Android SDK와 release keystore가 준비된 환경에서 별도로 검증한다. 현재 개발 PC는 Android SDK가 없어 Web 빌드까지만 실행 가능하다. CI는 MySQL 8.4 production 설정에서 migration → 민감정보 암호화 → readiness → 가입·일기·원문 비저장·데이터 export·RESTRICT 이력 포함 계정 삭제를 smoke test한다.

2. 핵심 사용자 여정

390×844 모바일 Web에서 실제 API·worker·DB를 연결해 다음 순서를 검증한다.

  1. 로그아웃 상태의 첫 히어로와 주 CTA가 마음 기록 → 성장을 먼저 설명하고 탐험 지도를 대표 이미지로 쓰지 않는지 확인 → 회원가입 없이 3분 체험 → 로컬 일기 → 감정별 성장 → 지도 갈림길 → 스탯 사건 → 발견물 귀환. API 요청 0, 기기 저장 복원, 손상 캐시 초기화, 저장소 차단 시 소실 안내, 가입 화면 이동 시 체험 일기 미전송을 함께 확인
  2. 가입 → starter 캐릭터 자동 장착 → 로그인/토큰 갱신
  3. 감정을 직접 고르지 않고 일기 작성 → 본문 분석 → XP/씨앗 즉시 반영
  4. 방 테마 미리보기 → 씨앗 구매 → 도감 소유 상태 → 바로 적용·저장
  5. 퀘스트 누적/7일 연속/구미호 보유/아이템 5종 조건의 잠금 진행도 → 달성 후 해금받기 → 중복 claim 없이 적용
  6. 홈에서 저장한 메인 캐릭터와 재화가 즉시 동기화되는지 확인
  7. 대화 시작 → worker 응답 → 실패/재시도와 빈 입력 방지
  8. 캘린더 일자 상세 → 월간 리포트·차트 연결
  9. 씨앗·새싹 공통 성장 → 줄기부터 외형·성격 분기 → 만개 모습 그대로 수확 → 최근 10그루/대표 10그루 박물관 전시 → 선택 해제와 10그루 제한 오류 복구
  10. 위기 표현 기록 → 안전 화면 즉시 이동 → 퀘스트 억제 → 공식 지원 경로 노출
  11. 50자 일기 전 탐험 잠금 → 일기 후 순찰 → 귀환 수집 → 던전 발견·1일 1회 탐험 → 네 가지 접근 방식별 스탯·의상·예상 수집량 확인 → 선택 결과 스냅샷 → 던전 내부 장면 공개 → 같은 제목·본문이 최근 기록에 보존되는지 확인 → 성장 4단계 옥상 순찰·별빛 보관고 발견 → 연구 후 순찰 시간 5분 단축 → 성장 5단계 수관 회랑·마음나무 관측실 → 온실 밖 탐험 1장 완성 상태 → 표본 연구 재료 차감·중복 완료 방지·다음 탐험 수집 보너스 → 완료한 순찰·던전의 최근 기록과 발견/클리어 누계 확인 → 출발 중 발견 이야기 비공개 → 귀환 공개 → 출발 당시 성장 결 대사와 함께 기록장에 보존되는지 확인 → 탐험 이야기 도감의 전체 24개 진행률·발견 장면 재열람·미발견 제목 비공개 확인 → 순찰 카드의 의상·연구 반영 예상 수집량과 단일 추천 경로 확인 → 주간 일기·순찰·던전 진행도와 목표별 1회 씨앗 수령 확인 → 장기 발자국 다섯 개의 원장 기반 진행도·현재 칭호·무보상 계약 확인 → 미완성 연구 재료 예약 → 여분 표본 3개 기증 → 2씨앗·일일 제한 확인 → 캐릭터 성장·씨앗 잔액·의상 성능 동기화
  12. 만 18세·약관·개인정보·민감정보 동의가 모두 없으면 real-data 가입 거절 → 계정 화면 JSON export에서 비밀번호·토큰 제외 → 비밀번호와 정확한 확인 문구로 탐험 이력과 완료된 AI 작업을 포함한 계정 영구 삭제 → 기존 access/refresh로 재접근 불가
  13. 평문 demo fixture를 real-data로 승격 → 17개 보호 컬럼 전수 암호화 → active key 회전 → 변조 ciphertext 복호화 거절 → 현재 schema/key의 검증 마커가 없으면 readiness 503

퀘스트는 36종·10개 카테고리이며, 같은 사용자/날짜에 결정적으로 재현된다. 최근 14일 중복을 피하고 직전 2회의 같은 카테고리를 피하는 회전 테스트와 30일 시뮬레이션을 유지한다. 보상은 기록 저장·퀘스트 완료·대화 시작 각각의 서버 원장 이벤트로 한 번만 지급되어야 한다.

3. UI·접근성 회귀 범위

  • 360px/390px 모바일, 1440px 데스크톱
  • 밝은/어두운 테마
  • 200% 글자 배율
  • 움직임 줄이기 설정(prefers-reduced-motion, Flutter disableAnimations)
  • 키보드 포커스, 최소 48×48 logical pixel 터치 영역, 의미 레이블
  • 긴 한국어 문구, 빈 상태, 로딩·오류·재시도·저장 충돌 상태
  • 가입 전 체험의 320px/200% 글자, 375px/390px 세로, 모바일 가로, 밝은/어두운 테마와 reduced motion. 각 단계 전환 때 스크롤이 맨 위로 돌아가고 앱바 제목·초기화 버튼·주 CTA가 겹치지 않아야 한다.
  • 가입 전 첫 프레임은 마음 기록과 성장 캐릭터를 보여 주고 탐험은 보조 활동을 명시한다. 탐험 통합 지형은 일기 작성과 성장 피드백이 끝나기 전에는 렌더하지 않는다.
  • 가입 전 체험 저장값에 일기 평문이 노출되지 않고, 체험 중 /api/v1 요청이 0이며, 새로고침 뒤 마지막 단계가 복원되는지 확인한다. 저장소 쓰기 실패는 플레이를 막지 않고 해당 화면을 닫으면 사라진다는 문구를 즉시 읽어 줘야 한다.
  • 방 테마 6종의 16:9 crop, 잠금 scrim, 긴 획득 조건, 진행도 0/중간/달성, 구매·claim 중복 탭, 획득 직후 바로 적용과 reduced motion 상태
  • 탐험 탭의 1초 로컬 카운트다운, 백그라운드 복귀 후 서버 귀환 시각 보정, 일기·안전 잠금, 1일 제한, 360px/200% 글자에서 버튼과 스탯 레이블 오버플로 없음
  • 직접 탐험 준비 화면의 목적지 → 편성 → 출발 방식 순서와 통합 2.5D 지형 크롭을 확인한다. 동굴·땅굴·우물·보물고·소굴·탑·귀환 터널이 원형 아이콘이 아니라 실제 지형지물로 이어지고 48px 상호작용 영역, 비콘·발자국·문구로 상태를 구분해야 한다.
  • 활성 탐험에서 노드 이동 → 사건 → 캐릭터·스킬 선택 → 다음 갈림길을 실제 API로 진행한다. 현재 장소와 다음 구역 선택 카드에 scene_key에 맞는 실제 원화가 보이고, 통합 지형은 주 무대에 남고 현장 확대는 사건·스킬 때 나타나야 한다. 폐허 던전·침수 동굴·뿌리 땅굴·메아리 우물·보물고·몬스터 소굴·기억탑 일곱 키와 번들 에셋이 누락 없이 1:1이어야 한다.
  • 현재 장소와 서버가 열어 준 다음 경로 원화 최대 2장만 화면 물리 픽셀에 맞춰 미리 디코드한다. 현장과 이동 카드가 같은 이미지 캐시 키를 공유하며, 이동 중 이전·다음 장면 교차 전환에 단색·빈 프레임·누락 이미지가 없어야 한다. 배경의 저주파 시차와 광점은 reduced motion에서 완전히 멈춰야 하며, 320px/200% 글자에서도 심도·위험도·이동 비용이 넘치지 않아야 한다.
  • 가입 없는 체험에서도 던전 입구 → 침수 동굴 또는 뿌리 땅굴 → 보물고를 실제 장면으로 보여 주고, 아이콘 지도만으로 선택을 대체하지 않는다.
  • 지형 이동에서 선택한 1~3명 실제 캐릭터가 940ms 동안 원화의 길 중심선 polyline을 따라 함께 이동하고, 발자국이 같은 경로를 쓰는지 확인한다. 지도 템플릿별 좌표 override와 배경 pan·scale 때문에 랜드마크가 밀리는 경우는 0이어야 한다.
  • 장부지기 수호전은 적 의도·대상·위력·약점을 명령 확정 전에 보여 준다. 살아 있는 대원 전원의 행동이 빠지면 확정할 수 없고, 순서를 바꿔 공유 집중력과 front 피격 대상이 바뀌는지 확인한다. 자동 지휘는 초기 OFF이고, 사용자가 ON으로 바꾼 수호전에서는 라운드 상태 반영 중에도 유지되어야 한다.
  • 서버 last_exchange와 앱의 장벽·HP·방어·집중력 수치가 일치하고, 대원별 행동 뒤에 예고한 적 공격이 한 번만 재생돼야 한다. 승리 라운드의 적 공격은 0회여야 한다.
  • 약점 공격·일반 충돌·적 예고·피격·방어·승리·패배 효과음이 서로 구분되고, 승패 문구는 최소 850ms 유지된 뒤 다음 화면이 열려야 한다. 오디오 초기화 실패가 입력·결과 적용을 막지 않아야 한다. 화면 흔들림 3.5px 이하, 연속 섬광 0, reduce motion에서도 live region과 최종 수치가 빠지지 않아야 한다.
  • 수호전 배경과 수호자 idle/attack은 분리된 레이어로 렌더한다. 공격 자세 전환 중 배경이 바뀌거나 잠든 수호자가 겹치거나 플레이 캐릭터·HUD까지 흔들리는 프레임은 0이어야 한다.
  • 탐험 기록장의 빈 상태·최근 6건·성장 공명 표시와 320px/200% 글자에서 히어로 및 기록 행의 세로 오버플로 없음
  • 탐험 이야기 도감의 0/24·부분 수집·24/24 상태, 장별 접기/펼치기, 발견 항목의 최초 스냅샷과 미발견 항목의 장소만 노출되는 계약을 확인. 도감 열람·완료로 원장이나 보상이 생기지 않아야 하며 320px/200% 글자에서도 행 오버플로가 없어야 함
  • 주간 탐험 약속의 날짜·진행도·수령 상태와 320px/200% 글자에서 목표 카드 및 보상 버튼 오버플로 없음
  • 탐험 발자국의 잠금·달성·현재 칭호 표시와 320px/200% 글자에서 다섯 칭호 카드 오버플로 없음
  • 표본별 연구 보관·기증 가능 수량, 확인 취소·실행, 일일 완료 상태와 320px/200% 글자에서 수집품 카드·확인 창 오버플로 없음
  • 순찰의 예상 수집량이 실제 출발 결과와 일치하고, 동률 추천·잠긴 경로 숨김·고정 XP/씨앗 계약이 유지되는지 확인. 네 경로별 이야기 3종의 코드 중복, 출발 스냅샷, 귀환 전 비공개와 기록장 공개, 여섯 성장 결별 반응 2종과 지연 없는 귀환 메시지도 함께 검증
  • 네 던전별 내부 장면 3종의 코드·문구 중복, 접근 방식 포함 결정성, 실행 스냅샷과 기록장 보존을 검증하며 장면별 보상 차이가 생기지 않는지 확인
  • BI 심볼 16/24/34/160px 가독성, favicon 16/32/48px, PWA normal/maskable 안전영역, Android adaptive/monochrome resource, native splash와 첫 Flutter frame 색 일치

Flutter semantics를 활성화한 모바일 Lighthouse snapshot은 화면에 따라 접근성 93~94, Best Practices 100, SEO 100을 기록했다. 접근성 감점은 Flutter 3.44 엔진이 런타임에 주입하는 maximum-scale=1, user-scalable=no viewport 한 건이다. 앱 위젯 수준의 대비·레이블·확대 글자 검증은 별도 테스트로 유지하며, Flutter 업그레이드 때 이 엔진 제약을 다시 확인한다.

4. Web 성능 기준

전투·탐험 렌더링의 프레임 예산, 측정 절차와 변경 시 확인할 항목은 performance.md를 따른다.

2026-07-15 릴리스 빌드에서 다음을 확인했다.

  • main.dart.wasm: 압축 전 3,578,353 bytes
  • 방 배경 WebP: 파일당 약 50~130KB
  • 390×844 박물관 화면에서는 night-museum-ink.webp를 요청하지 않고 세로 목록만 렌더링
  • CSP에서 inline script를 허용하지 않도록 로딩 제어를 mongroo-shell.js로 분리했다. 로딩 셸은 Flutter 첫 프레임까지 유지되며, 20초가 지나면 네트워크 안내와 다시 불러오기 버튼을 표시한다.
  • 실제 화면 흐름에서 브라우저 콘솔 오류·경고 0

로컬 Python 정적 서버는 압축·캐시·COOP/COEP 헤더를 제공하지 않으므로 여기서 얻은 로드 시간은 공개 환경의 성능 수치로 쓰지 않는다. Core Web Vitals, 전송 용량과 캐시 적중률은 최종 CDN에서 모바일 네트워크 조건으로 다시 측정한다. 공개 배포 설정은 deployment.md를 따른다.

5. 외부 환경에서 마쳐야 할 출시 입력·검증

코드와 CI는 real-data 암호화·동의·권리행사·MySQL lifecycle·릴리스 산출물 생성을 fail-closed로 구성했다. 다음 항목은 저장소에서 임의값으로 대신할 수 없으므로 실제 운영 환경에서 입력하고 확인한다.

  • 실제 운영자명·주소·개인정보 문의 이메일·호스팅 사업자/리전/국가와 해당 국가의 법률·스토어 심사에 맞춘 최종 약관 검토
  • 무작위 운영 JWT/필드 암호화 키, DB 비밀번호, HTTPS 도메인·인증서, 정확한 CORS/Host, 암호화 백업과 복구 리허설
  • 실제 MySQL 인스턴스의 다중 API 프로세스 동시성·목표 트래픽 부하 테스트
  • GitHub release variables/secrets 입력 후 운영 keystore로 서명된 AAB 설치·스토어 내부 테스트와 계정 생성/삭제 확인. 앱과 서버의 약관·개인정보·민감정보 동의 버전이 같은지도 함께 확인
  • 실제 CDN/LB에서 Brotli/gzip, Wasm MIME, CSP/COOP/COEP/HSTS, SSE buffering, 캐시 무효화와 직전 immutable 이미지 롤백 확인
  • AI_MODE=local을 선택하는 경우 실제 모델의 안전 분류·품질·latency·장애 격리 재검증. 기본 rules 모드는 외부 모델 없이 동작한다.