@howmuchhome-web/native-app-shared
native 앱이 의미를 소유하지만, 앱 밖(예: OTA 서버)에서도 같은 값을 참조해야 하는 중립 계약을 담는 패키지입니다.
package.json 은 private: true 이고 main/.(루트) export 가 없습니다. 진입점은 subpath export 하나뿐입니다.
{
"name": "@howmuchhome-web/native-app-shared",
"exports": {
"./ota": "./ota/index.ts"
},
"private": true
}왜 이 패키지가 있나
OTA 적용 정책 같은 값은 native 앱이 의미를 정합니다(어떤 정책일 때 어떻게 적용할지). 그런데 그 값을 실제로 만들어 서빙하는 쪽은 OTA 서버(apps/api)입니다. 즉 native 와 서버가 같은 계약을 참조해야 하는데, 이 정의는 기존 공유 패키지 어디에도 맞지 않습니다.
@howmuchhome-web/ui·@howmuchhome-web/logger처럼 여러 앱이 재사용하는 공유물이 아닙니다. 재사용 자산이 아니라 native 소유의 계약입니다.@howmuchhome-web/domains같은 제품 도메인(글·카페·유저 등 비즈니스 개체) 정의도 아닙니다. 앱 운영/배포 관점의 계약입니다.
그래서 “native 가 의미를 소유하되, 앱 밖에서도 참조해야 하는 중립 정의”를 담을 자리로 이 패키지를 둡니다.
중립성 규칙
이 패키지는 native 앱뿐 아니라 apps/api(Node/서버)도 import 합니다. 따라서 여기 들어가는 코드는 어느 런타임에서든 안전해야 합니다.
react-native/expo등 native 전용 런타임 의존 금지.- 순수한 enum · 타입 · 상수만 둡니다. 부작용(side-effect) 없는 정의만 허용합니다.
이 규칙이 깨지면(예: expo 모듈 import) 서버 빌드가 native 런타임을 끌어와 깨지므로, 중립성은 이 패키지의 존재 조건입니다.
구조와 소비처
진입점은 subpath 로만 노출합니다. 루트 배럴을 두지 않아, 소비처는 필요한 계약을 명시적으로 집습니다.
import {UpdatePolicy} from '@howmuchhome-web/native-app-shared/ota';./ota 계약의 소비처:
| 위치 | 역할 |
|---|---|
apps/api/src/app/api/updates/release/route.ts | release payload 의 updatePolicy 타입 |
apps/api/src/features/expoUpdates/manifest.ts | manifest extra.updatePolicy 서빙 |
apps/native-app/src/features/ota/OtaUpdateGate.tsx | 매니페스트의 정책 값으로 적용 방식 분기 |
./ota
첫 입주 계약입니다. OTA(self-hosted Expo Updates) 적용 정책을 정의합니다.
export enum UpdatePolicy {
Immediate = 1,
Notify = 2,
Default = 3,
}숫자 값은 wire/DB(정수) 포맷이므로 바꾸지 않습니다. release 시 지정된 값이 manifest 의 extra.updatePolicy 로 서빙되고, 클라이언트가 이 값으로 적용 방식을 분기합니다.
각 값의 동작 의미와 OTA 파이프라인 맥락은 OTA 문서를 참조하세요. 이 문서는 패키지 관점(어디에 두고 왜 노출하는지)만 다룹니다.
향후
./ota 외에도 “native 가 의미를 소유하되 앱 밖에서도 참조해야 하는 중립 계약”이 생기면, 같은 방식으로 subpath export 를 추가해 여기 둡니다. 각 계약은 자신의 subpath(./<name>)로 노출하고, 루트 배럴은 두지 않습니다.