Files
fanuzu/app/README.md

141 lines
7.9 KiB
Markdown

# FANUZU 앱 · 서버 소스
발주사 (주)팬케이크 / 수행사 스위치 주식회사(Sweech)
이 저장소는 FANUZU 모바일 앱(Flutter)과 서버(Firebase — Cloud Functions · Firestore 보안 규칙 · 인덱스)의 전체 소스입니다.
| 폴더 | 내용 |
|---|---|
| `lib/` | 앱 소스 (화면 · 데이터 저장소) |
| `test/` · `integration_test/` | 앱 테스트 |
| `firebase/functions/` | Cloud Functions (TypeScript, Node.js 22) · 서버 테스트 `firebase/functions/test/` |
| `firebase/firestore.rules` · `firebase/firestore.indexes.json` | 보안 규칙 · 인덱스 |
| `firebase/test/` | 보안 규칙 테스트 |
| `android/` · `ios/` | 플랫폼 설정 |
---
## 1. 개발 환경
| 항목 | 버전 |
|---|---|
| Flutter | **3.47.2** (`.fvmrc` 로 고정 — [fvm](https://fvm.app) 사용 권장) |
| Dart | 3.11.5 이상 |
| JDK (Android 빌드) | **17** (Temurin 17 권장. Android Studio 번들 JDK 25 는 현재 Gradle 8.14 와 호환되지 않아 빌드가 실패합니다) |
| JDK (Firebase 에뮬레이터) | **21 이상** (firebase-tools 요구) |
| Android | minSdk 29 (Android 10) · Android SDK build-tools 35 |
| iOS | 15.0 이상 · Xcode 26 |
| Node.js | 22 (Cloud Functions 런타임과 동일) |
| Firebase CLI | 최신 (`npm i -g firebase-tools`) |
`fvm` 을 쓰지 않는 경우 아래 명령의 `fvm flutter` 를 `flutter` 로 바꾸고, Flutter 3.47.2 를 직접 설치해 주십시오.
JDK 17 을 Flutter 에 지정합니다.
```bash
fvm flutter config --jdk-dir <JDK 17 경로>
```
## 2. 이 브랜치 · 태그와 제출 빌드
| 브랜치 · 태그 | 커밋 | 대응 제출 빌드 | 산출물 SHA-256 |
|---|---|---|---|
| `project-1` · 태그 `v0.1.1+14` | `0d2394c` | 1차 보완 빌드 0.1.1(14) — Android APK · iOS TestFlight 같은 소스 | APK `7d2ebadc624666c7992ac92ac3aa5d2c5e7b4bd0c602efeabc194ec73c99eb52` · IPA `d00870facdb27d38b458cdadc5723190b9fb18bfba06c64f578e0705a28627c8` |
| 태그 `v0.2.0+10` | `be99511` | 2차 제출 빌드 0.2.0(10) | APK `856e15781d002aff066a02da0d53f9d8eeada9e1fc6b6fc139c0705c77342c2c`(릴리스 「2차 제출 빌드 v0.2.0+10」 첨부) |
| `project-2` | `4236d75` | 제출 빌드 없음 — 태그 `v0.2.0+10` 에 1차 보완(0.1.1+14) 내용을 합친 최신 코드 | — |
**재빌드 확인.** 태그를 체크아웃한 뒤 아래 3절 명령으로 빌드하면 같은 버전 · 빌드 번호의 APK 가 나옵니다. 서명 키가 달라 서명 블록은 다르므로, 비교는 `unzip -l` 로 본 파일 목록과 `classes*.dex` · `lib/*/libapp.so` 의 SHA-256 으로 합니다. 제출본과 같은 서명으로 다시 만들어야 하면 서명 키를 별도 보안 경로로 요청해 주십시오.
## 3. 저장소에 포함하지 않은 파일
아래 파일은 보안상 저장소에 넣지 않았습니다. 빌드 전에 준비해 주십시오.
| 파일 | 받는 곳 |
|---|---|
| `android/app/google-services.json` | Firebase 콘솔 → 프로젝트 `fanuzu-dev-b020d` → 프로젝트 설정 → Android 앱(`kr.co.fanuzu.app`) |
| `ios/Runner/GoogleService-Info.plist` | 같은 화면의 iOS 앱 |
| `config/kakao.env` | `config/kakao.env.example` 을 복사해 `FANUZU_KAKAO_NATIVE_APP_KEY`(카카오 네이티브 앱 키) · `FANUZU_LINE_CHANNEL_ID`(LINE Login 채널 ID)를 적습니다. 없으면 카카오 · LINE 로그인만 「설정 전」으로 막힙니다 |
| `firebase/functions/.env.<프로젝트>` | 서버 `fnAuthKakao` 의 `KAKAO_APP_ID`(카카오 앱 ID) · `fnAuthLine` 의 `LINE_CHANNEL_ID` 를 적습니다 |
| `android/key.properties` · 업로드 서명 키 | **릴리스(서명) 빌드에만** 필요합니다. 요청하시면 별도 보안 경로로 전달합니다. 디버그 빌드에는 필요 없습니다 |
설정 파일이 없으면 앱은 표본 데이터로 동작하는 목(mock) 모드로 뜹니다(디버그 빌드에서만 진입 가능).
## 4. 앱 빌드 · 실행
```bash
cd app
fvm flutter pub get
fvm flutter run --dart-define-from-file=config/kakao.env # 연결된 실기기 · 에뮬레이터에서 실행
fvm flutter build apk --debug # 디버그 APK → build/app/outputs/flutter-apk/app-debug.apk
fvm flutter build apk --release # 서명 릴리스 APK (key.properties 필요)
fvm flutter build ios --no-codesign # iOS 빌드 확인
```
선택 빌드 설정(`--dart-define`):
| 키 | 용도 | 없을 때 |
|---|---|---|
| `FANUZU_SHARE_BASE_URL` | 공유 링크 주소(웹 브릿지) | 공유 시 링크 없이 카드 · 문구만 보냅니다 |
| `FANUZU_EMULATOR_HOST` | 로컬 Firebase 에뮬레이터 연결(개발용) | 실서버에 연결합니다 |
## 5. 테스트
```bash
cd app
fvm flutter analyze # 정적 분석 — 0건이어야 합니다
fvm flutter test # 앱 테스트
cd firebase/test
npm ci # 에뮬레이터용 Firebase CLI 포함 — 서버 테스트도 이것을 씁니다
npm run test:emulator # 보안 규칙 테스트 (JDK 21 필요)
cd ../functions
npm ci
npm run typecheck # 서버 타입 검사
npm run test:emulator # 서버 테스트 (Firestore 에뮬레이터 · JDK 21 필요)
```
의존성을 바꾼 경우 `analyze` · `test` 만으로는 Android 네이티브 컴파일 오류를 잡지 못하므로 `fvm flutter build apk --debug` 까지 확인해 주십시오. `pubspec.lock` 의 `firebase_core` 는 4.13.0 이어야 합니다(4.14.0 에서 Android 컴파일이 실패합니다).
## 6. 서버 배포
```bash
cd app/firebase
npm --prefix functions ci
npm --prefix functions run build
firebase deploy --only firestore,functions --project fanuzu-dev-b020d
```
## 7. 로그인 구성
1차 로그인은 Google · Apple · Kakao · LINE 4종입니다(별첨 B). 이메일 · 비밀번호 가입과 X 로그인은 없습니다.
| 제공자 | 앱 쪽 | 서버 쪽 | Firebase 사용자 식별 |
|---|---|---|---|
| Google | Google 로그인 SDK | Firebase Authentication | `google.com` |
| Apple | iOS 는 Apple 로그인 SDK, Android 는 Firebase 웹 흐름 | Firebase Authentication | `apple.com` |
| Kakao | 카카오 SDK 로그인 | `fnAuthKakao` 가 카카오 토큰을 확인하고 Firebase 커스텀 토큰 발급 | `oidc.kakao` 제공자 ID 로 기록 |
| LINE | LINE SDK 로그인(앱 설치 시 LINE 앱, 없으면 웹 로그인) | `fnAuthLine` 이 LINE 토큰을 확인하고 Firebase 커스텀 토큰 발급 | `oidc.line` 제공자 ID 로 기록 |
- Kakao · LINE 은 Firebase OIDC 웹 흐름이 아니라 각 SDK 와 서버 커스텀 토큰으로 로그인합니다. 제공자 ID `oidc.kakao` · `oidc.line` 은 이전 가입자의 UID 를 유지하려고 그대로 씁니다.
- Kakao · LINE 이메일은 선택 동의 항목입니다. 이메일이 없어도 제공자 고유 식별값으로 가입 · 로그인합니다.
- **SNS 연결(MY › 설정)** 은 서버가 현재 로그인과 새 제공자의 인증 자격을 확인해 붙입니다. 이메일이 같은지는 보지 않으며, 다른 FANUZU 계정에 이미 붙은 제공자는 거부합니다. 마지막 남은 제공자는 뗄 수 없습니다.
## 8. 폰트
`pubspec.yaml` 에 등록되어 앱에 들어가 있습니다.
| 패밀리 | 파일 | 쓰임 |
|---|---|---|
| 42dot Sans | `assets/fonts/42dotSans[wght].ttf` | 본문(디자인 토큰 `font-body`) |
| ABeeZee | `assets/fonts/ABeeZee-Regular.ttf` | 제목 · 수치(디자인 토큰 `font-display` · `font-mono`) |
## 9. 테스트 계정 · 권한
- 로그인은 위 4종 가운데 각자의 계정으로 가입하시면 됩니다.
- 운영 기능은 운영자 권한이 있는 계정만 호출할 수 있습니다. 권한을 드릴 Google 계정을 알려 주시면 운영자 권한을 부여합니다.
## 10. 실기기에서만 확인 가능한 기능
1차 범위의 Kakao · LINE 로그인은 각 제공자 앱이 설치된 실기기에서 확인해 주십시오. 센서 · 결제 · 푸시를 쓰는 기능은 2차 이후 범위이며 `project-2` README 에 적었습니다.