@howmuchhome-web/domains
얼마집의 제품 도메인 타입·enum·상수를 담는 플랫폼 중립 패키지입니다. 매물(listing), 조합(union), 카페(cafe), 채팅(chat), 사용자(user), 투표(vote) 등 서비스 개념을 TypeScript 타입으로 정의하고, 웹·native·API 패키지가 이를 공용 어휘로 공유합니다.
이 패키지는 런타임 로직이 거의 없고 타입 중심입니다. React 훅·유틸이 일부 있지만 (아래 참고) 핵심은 여러 앱이 같은 도메인 모델을 참조하도록 하는 것입니다.
무엇을 담고, 무엇을 담지 않는가
담는 것: 제품 도메인 데이터의 형태. “매물이란 무엇인가”, “조합의 부동산 종류는 어떤 값을 가지는가”, “사용자 온보딩 단계는 무엇인가” 같은 비즈니스 개념.
담지 않는 것: 인프라·전송 계약(wire contract). 예를 들어 OTA 업데이트 정책
UpdatePolicy enum은 native 클라이언트와 OTA 서버(apps/api)가 공유하는 인프라
계약이므로 domains 가 아니라 @howmuchhome-web/native-app-shared
의 ./ota 진입점에 있습니다. 그 파일은 react-native/expo 런타임 의존 없이 순수해야 하고
서버·클라이언트 양쪽 배포에 묶이는 계약이라, 제품 도메인 어휘와는 경계가 다릅니다.
이 구분의 기준은 “이 값이 제품 개념을 서술하는가, 아니면 두 시스템이 맞춰야 하는 프로토콜 상수인가”입니다. 후자라면 domains 에 두지 않습니다.
디렉토리 구조
| 디렉토리 | 역할 |
|---|---|
types/ | 도메인 타입·인터페이스·enum 정의 (패키지의 대부분) |
constants/ | 도메인 값 목록 상수 (예: 은행·통신사 목록) |
functions/ | 순수 판별/변환 함수 |
utils/ | 도메인 파생값 계산 유틸 (상태 라벨 등) |
hooks/ | 도메인 관련 React 훅 ('use client') |
루트 index.ts 가 types/*, utils, functions/*, constants/listing,
hooks/auth 를 재노출하므로 대부분은 @howmuchhome-web/domains 에서 바로 import 합니다.
import {Listing, ListingStatus, User, ChatProfile} from '@howmuchhome-web/domains';package.json 의 exports 는 서브패스도 열어 둡니다
(./types/, ./constants/, ./functions/, ./utils/, ./hooks/, ./types/user).
./server / ./server/ 도 선언되어 있으나 현재 server/ 디렉토리는 존재하지 않습니다.
도메인 타입
types/ 아래에 도메인별 파일이 있습니다.
| 파일 | 대표 심볼 |
|---|---|
listing.ts | Listing, Complex, Apartment, AreaSize, ListingStatus, ListingCertification, OwnerType, PhoneCarrier |
user.ts | User, UserAddress, ChatProfile, OnboardingStatus, MyAddressType, Certificate |
common.ts | IdentityVerificationMethod, IdentityVerificationStatus, BankExtra, PhoneExtra |
union.ts | RegionPhase, BusinessType, EstateType, EstateOwnType, ResidenceStatus, SurveyRespondentType 등 |
cafe.ts | Cafe, Post, CafePostCategory, EditorVersion, MyPageTapType |
chat.ts | ChatRoom, ChatRoomNicknameFormat |
vote.ts | VoteStatus, SubmissionStatus, AttendanceStatus, AttendanceMethod 등 |
dashboard.ts | DashboardMemberType, DashboardPermissionAction, ResidenceType 등 |
document.ts | DocumentStatus |
transaction.ts | TransactionType, TaxInvoiceStatus, CashReceiptType |
이 외에도 advertiser.ts, assembly.ts, consultation.ts, contribution.ts,
matching.ts, news.ts, principal-owner.ts, quiz.ts, survey.ts,
idCard.ts, auth.ts 등이 있습니다. 참고로 content.ts, error.ts 는
루트 index.ts 에서 재노출되지 않으므로 서브패스(./types/content 등)로 import 합니다.
타입은 서로 조합됩니다. 예를 들어 Listing 은 Complex·Apartment·ListingStatus
를, CertifiedListingDetail 은 Post(cafe)·ChatRoom(chat)·ChatProfile(user) 을
참조합니다. 도메인 파일 간 import 로 하나의 모델 그래프를 이룹니다.
enum 컨벤션
상태·분류 값은 대부분 const enum 으로 정의합니다.
export const enum ListingStatus {
WRITING = 'writing',
IDENTITY_CERTIFYING = 'identity_certifying',
WAIT_CERTIFYING = 'wait_certifying',
WAIT = 'wait',
PENDING = 'pending',
CERTIFIED = 'certified',
REJECTED = 'rejected',
}const enum 은 native(Expo)에서도 그대로 쓸 수 있습니다 — babel-preset-expo 가
런타임 enum 객체로 컴파일하므로 문자열 캐스팅으로 우회할 필요가 없습니다.
일부(OnboardingStatus, MyAddressType, ResidenceType 등)는 일반 enum 입니다.
상수
constants/listing.ts 는 도메인 값의 목록을 제공합니다. 타입은 types/ 에,
그 타입을 채우는 실제 데이터는 constants/ 에 두는 구성입니다.
import {phoneCarriers, banks, accountIdentityBanks} from '@howmuchhome-web/domains';
// phoneCarriers: {key: PhoneCarrier; label: string}[]
// banks / accountIdentityBanks: Bank[] ({key, name, code})phoneCarriers 는 PhoneCarrier 유니온을, banks/accountIdentityBanks 는
Bank 인터페이스(둘 다 types/listing.ts)를 채웁니다.
함수·유틸·훅
타입 외에 얇은 런타임 코드도 포함합니다.
functions/
순수 판별·변환 함수입니다.
import {isValidChatProfile} from '@howmuchhome-web/domains';
// functions/user.ts, functions/apartment.tsutils/
도메인 값에서 표시용 파생값을 계산합니다. 예를 들어 getListingCertificationStatus
는 Listing 의 status·identityVerification 을 읽어 한국어 상태 라벨
('작성 중', '인증 대기 중' 등)을 반환합니다. utils/index.ts 가
listing, union, cafe, cookie, vote, dashboard, document, chat 을 묶어
재노출합니다.
hooks/
hooks/auth.ts 는 'use client' 훅을 제공합니다 (useAccessToken, useSignOut).
쿠키 기반 액세스 토큰을 읽고 쓰며 @howmuchhome-web/next-cookies 에 의존합니다.
훅은 클라이언트 환경에서만 사용하세요.
API 스키마와의 관계
domains 는 개념(모델) 을, @howmuchhome-web/api 는
그 개념을 실은 요청/응답 계약 을 담당합니다. 둘을 분리해 도메인 모델이
특정 엔드포인트 형태에 묶이지 않게 합니다.
@howmuchhome-web/api 는 domains 를 의존성으로 선언하고, 스키마에서 도메인 타입을
직접 조합합니다.
// packages/api/lib/chat/schema.ts
import {ChatProfile, ChatRoom, SelectedListing} from '@howmuchhome-web/domains';
export type GetMyChatProfileResponse = {
profile: ChatProfile | null;
};EstateType(union), DocumentStatus(document) 등의 enum 도 여러 api 스키마에서
쓰입니다. 즉 api 는 domains 를 소비하는 상위 계층이며, 반대 방향 의존은 없습니다
(domains 는 api 를 import 하지 않습니다).
소비하는 곳
플랫폼 중립 패키지로, 웹과 native 양쪽에서 사용합니다.
apps/app(웹뷰),apps/dashboard(관리자) —package.json에 직접 의존 선언apps/native-app(Expo) — 다수 화면에서 도메인 타입 사용packages/api,packages/chart,packages/common-components,packages/app,packages/bridge-protocol등 공유 패키지
native 에서도 문제없이 쓰이는 이유는 이 패키지가 타입 중심이고, 런타임 코드
(const enum, 순수 함수)가 RN 세이프하기 때문입니다. 웹 전용 API(예: DOM,
next/navigation)에 직접 의존하지 않습니다. 단, hooks/auth.ts 는
@howmuchhome-web/next-cookies 에 의존하는 클라이언트 훅이므로 타입/enum 과 같은
층위로 취급하지 마세요.
관련 문서
@howmuchhome-web/api— 도메인 타입을 조합한 API 계약@howmuchhome-web/native-app-shared— 인프라 계약(OTAUpdatePolicy등)