Build: productFlavors 추가 — demo(동결 안정판) / dev(개발 진행) + docs 정리
방광 모형 테스트가 100% 통과하는 시점을 demo flavor로 동결하고, 모든
신규 작업은 dev에서만 진행하기 위한 빌드 분기 셋업.
gradle (app/build.gradle.kts):
- flavorDimensions: "channel"
- demo: applicationIdSuffix=".demo", versionNameSuffix="-demo",
BuildConfig.IS_DEMO=true, FLAVOR_LABEL="demo"
- dev: BuildConfig.IS_DEMO=false, FLAVOR_LABEL="dev"
- 두 flavor 동시 설치 가능 (applicationId 분리)
source set:
- src/demo/res/values/strings.xml — app_name "VesiScan Demo"
- src/dev/res/values/strings.xml — app_name "VesiScan Dev"
- src/demo/java/.gitkeep + src/dev/java/.gitkeep — 격리본 둘 위치 안내
운영 가이드: docs/FLAVOR_DEMO_STABLE.md
- Level 1 (BuildConfig 분기) vs Level 2 (source set 격리) 두 동결 방식
- 새 안정판 동결 시 git tag + src/demo/ 복사 절차
- 어떤 코드를 동결 후보로 둘지 (알고리즘/파라미터 권장, BLE/UI는 공유)
- 트러블슈팅 + 첫 동결 시점 권장 절차
.gitignore: /docs/ 제거 — 팀/iOS 개발자가 접근 가능하도록
- docs/BLE_PROTOCOL_REFERENCE.md
- docs/iOS_PORTING_CLINICAL_MEASUREMENT.md
- docs/FLAVOR_DEMO_STABLE.md 모두 신규 commit
검증:
./gradlew assembleDemoDebug + assembleDevDebug 둘 다 BUILD SUCCESSFUL
→ app/build/outputs/apk/demo/debug/app-demo-debug.apk
→ app/build/outputs/apk/dev/debug/app-dev-debug.apk
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
# Flavor 운영 정책 — demo (동결 안정판) vs dev (개발 진행)
|
||||
|
||||
방광 모형 테스트가 100% 통과하는 시점을 **demo flavor**로 동결하고, 모든 신규 작업은 **dev flavor**에서만 진행하기 위한 가이드.
|
||||
|
||||
---
|
||||
|
||||
## 1. 두 flavor의 정체성
|
||||
|
||||
| 항목 | demo | dev |
|
||||
|---|---|---|
|
||||
| 목적 | 시연/검증 — 결과 재현성 보장 | 개발 진행 — 모든 신규 기능/실험 |
|
||||
| applicationId | `com.example.medilightv2android.demo` | `com.example.medilightv2android` |
|
||||
| 표시명 | VesiScan Demo | VesiScan Dev |
|
||||
| versionName suffix | `-demo` | (없음) |
|
||||
| BuildConfig.IS_DEMO | `true` | `false` |
|
||||
| BuildConfig.FLAVOR_LABEL | `"demo"` | `"dev"` |
|
||||
| 동시 설치 | 가능 (applicationId 다름) | 가능 |
|
||||
|
||||
→ 한 단말에 두 빌드를 동시에 설치해서 같은 측정을 양쪽에서 돌려보고 결과 비교 가능.
|
||||
|
||||
---
|
||||
|
||||
## 2. 빌드 명령
|
||||
|
||||
```bash
|
||||
# demo flavor
|
||||
./gradlew assembleDemoDebug # debug APK
|
||||
./gradlew assembleDemoRelease # release APK
|
||||
|
||||
# dev flavor
|
||||
./gradlew assembleDevDebug # debug APK (일상 개발)
|
||||
./gradlew assembleDevRelease
|
||||
|
||||
# 두 flavor 모두 빌드
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
Android Studio에서는 **Build Variants** 패널에서 `demoDebug` / `devDebug` / ... 중 선택.
|
||||
|
||||
---
|
||||
|
||||
## 3. 동결 메커니즘 — 두 가지 레벨
|
||||
|
||||
### Level 1: BuildConfig flag 분기 (가장 단순)
|
||||
|
||||
코드 안에서 분기:
|
||||
```kotlin
|
||||
if (BuildConfig.IS_DEMO) {
|
||||
// demo 전용 동작 (예: 디버그 panel 숨김, 특정 알고리즘 강제)
|
||||
} else {
|
||||
// dev 전용
|
||||
}
|
||||
```
|
||||
|
||||
장점: 같은 파일에서 처리 가능.
|
||||
단점: 시간이 지나면서 main 코드가 변경되면 demo 동작도 같이 영향받음. **진정한 동결은 안 됨.**
|
||||
|
||||
### Level 2: Source set 격리 (★ 진짜 동결)
|
||||
|
||||
`src/demo/java/` 또는 `src/demo/res/` 에 동결 시점의 클래스/리소스를 복사하면, **dev 작업 중 main이 바뀌어도 demo flavor 빌드는 이 격리본을 사용**합니다.
|
||||
|
||||
**Gradle 컴파일 우선순위:**
|
||||
```
|
||||
demo flavor 빌드 → src/main/* + src/demo/* (같은 클래스명이면 src/demo/가 우선)
|
||||
dev flavor 빌드 → src/main/* + src/dev/*
|
||||
```
|
||||
|
||||
**예시:** V4.1 wall detection 알고리즘을 2026-06-08 시점에 동결하려면:
|
||||
```
|
||||
src/main/java/com/example/.../walldetect/V41Detector.kt ← 계속 변경됨 (dev에서 사용)
|
||||
src/demo/java/com/example/.../walldetect/V41Detector.kt ← 2026-06-08 시점 복사본 (demo에서 사용)
|
||||
```
|
||||
|
||||
main의 V41Detector를 리팩토링/실험해도 demo 빌드는 항상 격리본을 컴파일.
|
||||
|
||||
⚠️ **주의:**
|
||||
- 격리한 클래스의 시그니처가 main의 의존 코드와 호환되어야 함 (메서드 이름/파라미터 동일하게 유지)
|
||||
- main에서 V41Detector 호출부의 시그니처가 바뀌면 demo flavor 빌드 깨짐 — 그땐 src/demo/도 같이 업데이트하거나, 인터페이스를 두고 그 구현만 분리
|
||||
|
||||
---
|
||||
|
||||
## 4. 권장 동결 운영 절차
|
||||
|
||||
### 4.1 새 안정판 동결 시
|
||||
|
||||
방광 모형 테스트가 100% 통과하는 시점을 확인하면:
|
||||
|
||||
```bash
|
||||
# 1) 현재 상태에 tag 부여 (snapshot 보존)
|
||||
git tag -a demo-stable-v1.0 -m "Demo stable: bladder phantom 100% pass — 2026-06-08"
|
||||
git push origin demo-stable-v1.0
|
||||
|
||||
# 2) 동결할 핵심 클래스/리소스를 src/demo/로 복사
|
||||
# 예: V4.1, PiezoSettings 기본값, GreenZoneConstants 등
|
||||
cp app/src/main/java/.../walldetect/V41Detector.kt \
|
||||
app/src/demo/java/.../walldetect/V41Detector.kt
|
||||
|
||||
# 3) demo flavor가 격리본을 잘 쓰는지 빌드 + 시연용 폰에 설치해 검증
|
||||
./gradlew installDemoDebug
|
||||
|
||||
# 4) commit
|
||||
git add app/src/demo/ && git commit -m "Demo flavor: freeze V4.1/PiezoSettings (v1.0)"
|
||||
```
|
||||
|
||||
### 4.2 일상 개발 (dev)
|
||||
|
||||
- `src/main/` 만 변경 — `src/demo/`는 건드리지 않음
|
||||
- `assembleDevDebug` 로만 작업
|
||||
- demo 격리본의 시그니처를 깨뜨리는 API 변경은 피하거나, demo도 같이 업데이트
|
||||
|
||||
### 4.3 다음 안정판 갱신
|
||||
|
||||
새로운 안정판이 검증되면:
|
||||
```bash
|
||||
# 이전 격리본 백업 (옵션 — git history에 남아있음)
|
||||
mv app/src/demo/java/.../V41Detector.kt /tmp/V41Detector.v1.0.kt
|
||||
|
||||
# 최신 main 코드를 다시 src/demo/로 복사
|
||||
cp app/src/main/java/.../V41Detector.kt app/src/demo/java/.../V41Detector.kt
|
||||
|
||||
# 새 tag
|
||||
git tag -a demo-stable-v1.1 -m "Demo stable v1.1: ..."
|
||||
|
||||
# commit
|
||||
git add app/src/demo/ && git commit -m "Demo flavor: refresh freeze to v1.1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 어떤 코드를 동결 후보로?
|
||||
|
||||
방광 모형 테스트 결과에 직접 영향을 주는 것들:
|
||||
|
||||
| 카테고리 | 후보 | 위치 |
|
||||
|---|---|---|
|
||||
| Wall detection | `V41Detector`, `PiezoEchoAnalyzer*` | `walldetect/`, `managers/PiezoEchoAnalyzer*.kt` |
|
||||
| 측정 파라미터 | `PiezoSettings` 기본값, `GreenZoneConstants`, `PiezoHW` preset | `models/`, `managers/` |
|
||||
| BLE 파싱 | `PiezoPacketCollector`, `ImuPacketCollector` | `ble/` |
|
||||
| Volume 계산 | `PiezoConstants.volumeMl()` 식 | `managers/PiezoEchoAnalyzer.kt` |
|
||||
|
||||
⚠️ **BLE 통신 layer (BleManager, CRC16)는 펌웨어와 직결되므로 보통 같이 가야 함** — 동결하면 펌웨어 업데이트 대응 불가.
|
||||
|
||||
⚠️ **UI/저장/labdb는 동결할 필요 거의 없음** — 결과값 자체에는 영향 안 줌.
|
||||
|
||||
→ 처음엔 **알고리즘 + 측정 파라미터**만 동결, 나머지는 main 공유 권장.
|
||||
|
||||
---
|
||||
|
||||
## 6. BuildConfig 활용 예시
|
||||
|
||||
런타임 분기가 필요한 경우 (격리할 만큼 크지 않은 케이스):
|
||||
|
||||
```kotlin
|
||||
// 예: dev에만 Clinical 메뉴 노출
|
||||
if (com.example.medilightv2android.BuildConfig.IS_DEMO.not()) {
|
||||
Button(onClick = { goClinicalHome() }) { Text("Clinical R&D") }
|
||||
}
|
||||
|
||||
// 예: demo에서는 항상 fixed parameter
|
||||
val maxVolume = if (com.example.medilightv2android.BuildConfig.IS_DEMO) {
|
||||
500 // 동결 기본값
|
||||
} else {
|
||||
appState.piezoSettings.maxVolume // 사용자 조정 허용
|
||||
}
|
||||
|
||||
// UI에서 flavor 표시 (디버그용)
|
||||
Text("v${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR_LABEL})",
|
||||
fontSize = 10.sp, color = MlSecondaryText)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. CI / 배포 시 주의
|
||||
|
||||
- **demo flavor APK는 출시/시연 전용** — Play Store 등 외부 배포는 dev flavor 사용
|
||||
- demo flavor의 applicationId가 `.demo`로 끝나므로 ANR/crash 리포트도 자동 구분됨
|
||||
- demo는 안정성 보장이 핵심 — 새 라이브러리/SDK 업데이트도 보수적으로
|
||||
|
||||
---
|
||||
|
||||
## 8. 트러블슈팅
|
||||
|
||||
### Q. demo flavor 빌드 시 main의 변경사항이 자꾸 반영됨
|
||||
A. src/demo/ 에 격리본을 복사하지 않았기 때문. Level 2 동결을 적용해야 함. BuildConfig.IS_DEMO 분기만으로는 진짜 동결 안 됨.
|
||||
|
||||
### Q. 같은 클래스를 src/main/과 src/demo/에 둘 다 두면 어떻게 됨?
|
||||
A. demo flavor 빌드에서는 src/demo/ 가 우선. dev flavor 빌드에서는 src/main/ 만 사용 (src/demo는 무시).
|
||||
|
||||
### Q. src/demo/와 src/dev/ 둘 다 같은 클래스가 있으면?
|
||||
A. 각 flavor 빌드는 자기 flavor source set만 봄. demo 빌드 = main + demo, dev 빌드 = main + dev. 충돌 안 남.
|
||||
|
||||
### Q. Test (src/test/, src/androidTest/) 는 flavor 별로 분리되나?
|
||||
A. 가능. `src/testDemo/`, `src/testDev/`로 분리. 다만 현재 프로젝트엔 테스트가 거의 없어 신경 안 써도 됨.
|
||||
|
||||
### Q. Gradle sync 후 Build Variants에 demo/dev가 안 보임
|
||||
A. Android Studio 좌측 하단 **Build Variants** 패널을 켜고 Gradle sync 재실행. 처음 한 번은 sync에 30초~1분 걸림.
|
||||
|
||||
---
|
||||
|
||||
## 9. 첫 동결 시점 권장 절차 (지금 바로 할 일)
|
||||
|
||||
1. 현재 dev 빌드를 방광 모형으로 검증 — 결과값이 만족스러우면 진행
|
||||
2. `git tag -a demo-stable-v1.0 -m "Demo baseline 2026-06-08"` + push
|
||||
3. 검증된 알고리즘 클래스를 `src/demo/java/...` 로 복사
|
||||
4. `./gradlew installDemoDebug` 로 시연 폰에 설치
|
||||
5. 같은 모형으로 demo 빌드 한 번 더 측정 — 동일 결과 확인
|
||||
6. 이후 dev에서 자유롭게 작업. demo는 건드리지 않음.
|
||||
|
||||
---
|
||||
|
||||
**관련 파일:**
|
||||
- `app/build.gradle.kts` — productFlavors 정의
|
||||
- `app/src/demo/`, `app/src/dev/` — flavor 전용 source set
|
||||
- `app/src/demo/res/values/strings.xml` — app_name "VesiScan Demo"
|
||||
- `app/src/dev/res/values/strings.xml` — app_name "VesiScan Dev"
|
||||
Reference in New Issue
Block a user