걸음 수 Health Connect·HealthKit · 위치 퀘스트 사진·QR 인증 · 행성 형태 확정

This commit is contained in:
Sn-Kinos
2026-10-05 23:57:01 +09:00
parent dc9861df38
commit dce2f64362
44 changed files with 930 additions and 66 deletions
+34 -2
View File
@@ -6,6 +6,8 @@
/// - 퀘스트 생성 `523:18152`~`523:18188` · Admin 정의 `567:19531`
library;
import 'dart:typed_data' show Uint8List;
import '../../core/data/backend.dart' show BackendException;
import '../../core/monetization/rewarded_ad.dart';
import '../../core/i18n/app_locale.dart';
@@ -432,10 +434,19 @@ class QuestDetail {
this.reviews = const [],
this.publishState = '',
this.moderationReason,
this.verifyMethods = const [],
this.qrCode,
});
final QuestCard card;
/// 위치 Quest 의 인증 수단(`quests.verifyMethods` — `gps` · `photo` · `qr`, 원장 C-03). PRD-05
/// 「장소 상세에서 인증 방법 … 확인」. GPS 는 항상, 사진 · QR 은 생성 때 고른 추가 수단이다.
final List<String> verifyMethods;
/// 생성자에게만 — 현장에 붙일 QR 의 값(`questSecrets/{id}.qrCode`). 참여자에게는 null.
final String? qrCode;
/// 사용자 생성 Quest 의 공개 상태(`quests.status`) — `review`(검수 대기) · `published` ·
/// `rejected`(운영 반려) · `cancelled` · `ended`. 운영 Quest 는 빈 값.
final String publishState;
@@ -464,6 +475,17 @@ class QuestDetail {
final List<QuestSubmission> reviews;
}
/// 위치 Quest 의 추가 인증 증거(원장 C-03 · PRD-05 「사진 인증 · QR 인증」). GPS 좌표는 저장소가 따로 잰다.
class PlaceProof {
const PlaceProof({this.qr, this.photo});
/// 현장 QR 을 스캔한 값.
final String? qr;
/// 방문 인증 사진(JPEG 바이트). 저장소가 Storage 에 올리고 경로를 보낸다.
final Uint8List? photo;
}
/// 목록 탭. 명세 — *전체 / 진행중 / 완료 / 내 퀘스트*.
enum QuestTab {
all,
@@ -502,8 +524,12 @@ class QuestDraft {
this.placeId,
this.pin,
this.goal,
this.extraVerify = const [],
});
/// 위치 Quest 의 추가 인증 수단(`photo` · `qr`, 원장 C-03). GPS 는 서버가 항상 넣는다.
final List<String> extraVerify;
/// 지도에 꽂은 핀(등록 장소가 아닐 때) — 서버가 그 좌표로 장소를 만든다.
final QuestPlace? pin;
@@ -597,7 +623,10 @@ abstract interface class QuestRepository {
/// **판정도 지급도 서버가 한다.** 앱은 증거(걸음 수·좌표)만 싣고, 실패는
/// 에러 카탈로그 코드로 돌아온다(E-QST-01 미완주 · E-QST-02 비정상 ·
/// E-QST-03 반경 밖 · E-POP-03 중복).
Future<QuestReward> verify(QuestCard card);
Future<QuestReward> verify(
QuestCard card, {
PlaceProof proof = const PlaceProof(),
});
/// 보상형 광고 한 편을 불러온다. 불러오지 못하면 E-AD-01 이다.
///
@@ -831,7 +860,10 @@ class SampleQuestRepository implements QuestRepository {
void recordShake(ShakeJudge run) {}
@override
Future<QuestReward> verify(QuestCard card) async {
Future<QuestReward> verify(
QuestCard card, {
PlaceProof proof = const PlaceProof(),
}) async {
_claimed.add(card.id);
return QuestReward(
rewardedPop: card.rewardPop ?? 0,