사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
모듈 규칙▾
배달 기능 추가하기
아이스크림 가게가 너무 성황이라 배달 주문이 쏟아지고 있습니다! 이제 배달 주문을 관리해야 합니다. 배달 기사는 한 번에 여러 주문을 배달할 수 있으므로, 배달과 주문 간의 관계를 만들어야 합니다. 이것은 전형적인 일대다 관계입니다 - 하나의 Delivery가 여러 IcecreamOrder를 포함합니다.
이 튜토리얼에서 배울 내용:
🔗
임베디드 참조를 사용하여 모델 간 관계 정의
⚡
관계된 데이터 생성 시 부수 효과 트리거
🎨
관계된 데이터를 선택하고 표시하는 UI 컴포넌트 구축
배달 모듈 생성하기
먼저 CLI를 사용하여 Delivery 모듈을 생성합니다. 이 모듈은 여러 아이스크림 주문을 하나의 배달 묶음으로 연결합니다.
Terminal
관계 정의하기
이제 IcecreamOrder와의 관계를 가진 Delivery 모델을 정의합니다. 핵심은 LightIcecreamOrder를 필드 타입으로 사용하는 것입니다 - 이것은 필수 주문 데이터를 배달 문서에 직접 저장하는 임베디드 참조를 생성합니다.
apps/koyo/lib/delivery/delivery.constant.ts
핵심 관계 패턴을 이해해봅시다:
🔗field([LightIcecreamOrder], { minlength: 1 })
LightIcecreamOrder 배열을 임베딩하여 일대다 관계를 정의합니다. "Light" 버전은 필수 필드만 포함합니다 (serveType, size, toppings, status). 전체 문서를 복제하지 않고 임베딩할 수 있습니다.
📦임베디드 vs 참조
LightIcecreamOrder를 임베딩함으로써, 배달 문서는 추가 데이터베이스 쿼리 없이 모든 필요한 주문 정보를 포함합니다. 이것은 함께 자주 읽히는 데이터에 이상적입니다.
Delivery 모델에 대한 dictionary 항목을 추가합니다:
apps/koyo/lib/delivery/delivery.dictionary.ts
이제 라이프사이클 훅이 있는 서비스 레이어를 구현합니다. 배달이 생성되면 모든 연관된 주문을 완료 처리해야 합니다:
apps/koyo/lib/delivery/delivery.service.ts
관계 데이터를 위한 주요 서비스 패턴:
🔌service<srv.IcecreamOrderService>()
IcecreamOrderService를 주입하여 DeliveryService가 주문과 상호작용할 수 있게 합니다. 이를 통해 모델 간 작업이 가능해집니다.
⚡_postCreate
배달이 생성된 후 실행되는 라이프사이클 훅입니다. 모든 연결된 주문을 순회하며 완료 처리합니다. 연쇄 업데이트를 처리합니다.
🚫_preUpdate
Revert 오류를 발생시켜 배달 수정을 방지합니다. 배달이 생성되면 불변이 됩니다 - 데이터 무결성을 보장합니다.
이제 관련 주문을 선택하기 위한 Template 컴포넌트를 만듭니다. Field.Children 컴포넌트는 관계 데이터 선택을 위해 특별히 설계되었습니다:
apps/koyo/lib/delivery/Delivery.Template.tsx
Field.Children의 주요 기능:
📋
sliceName: 선택 가능한 옵션을 제공하는 슬라이스를 지정합니다. 여기서는 배달 가능한 주문으로 필터링된 'icecreamOrderInDelivery'입니다.
🎯
initArgs: 슬라이스 쿼리에 전달되는 초기 인자입니다. ["served"]는 배달 준비가 된 주문만 표시하도록 필터링합니다.
🎨
renderOption: 선택 가능한 각 옵션에 대한 커스텀 렌더 함수입니다. 쉬운 식별을 위해 주문 ID를 표시합니다.
배달 선택 UI를 위해 IcecreamOrder에 새 슬라이스를 추가합니다. 이것은 상태와 서빙 타입으로 주문을 필터링합니다:
apps/koyo/lib/icecreamOrder/icecreamOrder.signal.ts
도큐먼트의 byStatuses 쿼리 선언에서 serveType 필터링을 지원하기 위해 인자를 추가해봅시다.
apps/koyo/lib/icecreamOrder/icecreamOrder.document.ts
새 슬라이스에 대한 dictionary 항목을 추가합니다:
apps/koyo/lib/icecreamOrder/icecreamOrder.dictionary.ts
이제 관련 주문과 함께 배달을 표시하는 Unit 컴포넌트를 만듭니다. 이것은 임베디드 데이터가 어떻게 함께 렌더링될 수 있는지 보여줍니다:
apps/koyo/lib/delivery/Delivery.Unit.tsx
delivery.icecreamOrders를 순회하며 각각을 IcecreamOrder.Unit.Card 컴포넌트로 렌더링하는 방식에 주목하세요. 임베디드 데이터는 추가 쿼리 없이 즉시 사용 가능합니다!
새 배달 생성을 위한 모달이 있는 Zone 컴포넌트를 만듭니다:
apps/koyo/lib/delivery/Delivery.Zone.tsx
submitOption.onSuccess 콜백은 완료된 주문으로 로컬 상태를 업데이트하여, UI를 데이터베이스 변경과 동기화 상태로 유지합니다.
마지막으로, Tab 컴포넌트를 사용하여 주문과 배달을 정리하고 메인 페이지에 모든 것을 통합합니다:
apps/koyo/app/[lang]/page.tsx
이 통합된 페이지의 주요 기능:
📑
Tab: 관련 콘텐츠를 전환 가능한 패널로 정리합니다. 사용자가 주문과 배달 사이를 쉽게 탐색할 수 있습니다.
⚡
Promise.all: 최적의 성능을 위해 icecreamOrder와 delivery 데이터를 병렬로 로드합니다.
요약
💡모범 사례
- 문서 비대화를 피하기 위해 임베디드 데이터에 LightModel 사용
- 자주 함께 읽히는 데이터를 임베딩
- 데이터 일관성 유지를 위해 라이프사이클 훅 사용
- 관계 선택 UI를 위한 전용 슬라이스 생성
모든 핵심 튜토리얼을 완료했습니다. System Architecture 섹션에서 모든 것이 어떻게 함께 작동하는지 더 깊이 알아보세요.