Resource Projection
공용 Board·Calendar·Resource Scheduler·Schedule 화면과 App 소유 동작·생성 경계, 현재 SDK 공개 상태를 설명합니다.
SDK React 컴포넌트로 App 레코드를 Board, Calendar, Resource Scheduler, Schedule에 표시합니다.
App API와 화면 연결
- 아래 컴포넌트 중 필요한 보기를 선택하고, 사용자 권한을 적용한 App API에서 해당 projection 형식을 반환합니다. 볼 수 있는 레코드와 허용된 동작만 포함하세요.
- SDK 루트에서 projection 타입을,
/host에서 렌더러를 가져옵니다. 로딩·오류·빈 결과·읽기 전용 상태도 전달합니다. onMove또는onAction을 App 변경 API로 연결합니다. 서버에서 조직, 현재 권한, 예상 버전, 멱등성, 업무 규칙을 확인하고 확정 projection 또는 거절 결과를 반환합니다.onSelectRange와onCreateResource는 App 생성 화면을 여는 데 사용하고, 저장 성공 후 다시 조회합니다.
먼저 읽기 전용 Board adapter를 연결합니다. 호출하는 화면이 권한을 적용한 projection과 번역 label을 전달하며, 빈 결과는 빈 lanes 배열로 표현합니다. 보호된 변경 API를 구현한 뒤에 onMove를 추가하세요.
import type { ResourceBoardProps } from "@nexia/sdk";
import { ResourceBoard } from "@nexia/sdk/host";
type BoardViewProps = Pick<
ResourceBoardProps,
"projection" | "state" | "labels" | "onRetry" | "onOpenResource"
>;
export function BoardView(props: BoardViewProps) {
return <ResourceBoard {...props} readOnly />;
}결과 확인
허가된 조작은 레코드와 화면에 반영되고, 권한 부족이나 오래된 버전은 확정된 화면으로 복원되어야 합니다. 빈 영역 선택 자체로 레코드가 저장되지는 않습니다. 화면 등록은 App 화면 만들기, 검사는 App 테스트하기를 따릅니다.
컴포넌트와 상호작용 계약
Resource Projection은 App 소유 레코드를 공용 비목록 화면으로 표현합니다. Host는 renderer와 전송 형태를 제공하지만, 보이는 레코드를 고르고 모든 업무 동작을 수행하는 책임은 소유 App에 남습니다.
| Projection | 화면 | 소유자 동작 |
|---|---|---|
| Board | Kanban lane과 card | App이 정의한 동작으로 card 이동 |
| Calendar | 월·주·일·목록 occurrence | occurrence 일정 이동 또는 길이 변경 |
| Resource Scheduler | resource timeline 또는 resource time-grid lane | occurrence 일정 이동·길이 변경·lane 재할당, 빈 lane 범위를 선택해 호출자 소유 생성 시작 |
| Schedule | Gantt grid 또는 schedule timeline | 일정 이동 또는 dependency 생성·삭제 |
공개 frontend 경계는 package root에서 순수 projection 타입을, /host에서 lazy
binding된 React renderer를 제공합니다. 다음 import는
packages/app-sdk/packages/react/src/resources/resource-projections.ts와
packages/app-sdk/packages/react/src/host.ts가 소유합니다.
import type {
NxCalendarOccurrence,
NxResourceSchedulerActionCommand,
NxResourceSchedulerOccurrence,
NxResourceSchedulerResource,
NxResourceSchedulerSelection,
ResourceBoardProjection,
ResourceScheduleProjection,
} from "@nexia/sdk";
import {
NxCalendar,
NxResourceScheduler,
ResourceBoard,
ResourceSchedule,
} from "@nexia/sdk/host";각 컴포넌트는 actor-authorized projection을 받고, mutation은 타입 있는 callback으로
App에 돌아갑니다. 현재 설계 소유자는
docs/reference/RESOURCE-PROJECTIONS.md입니다.
어떻게 맞물리는가
네 projection은 같은 소유 흐름을 따릅니다.
| 계층 | 책임 |
|---|---|
| App domain | 레코드, 업무 상태, 날짜, dependency, 권한, audit, outbox 쓰기 소유 |
| Projection provider | 행위자에게 보이는 레코드를 고르고 허용된 action만 공개 |
| 공용 계약 | 안정적인 Resource Reference, version, 표시 필드, 타입 있는 command 전달 |
| Host renderer | Board·Calendar·Resource Scheduler·Schedule을 그리고 되돌릴 수 있는 optimistic feedback 적용 |
소유 App이 소비자에게 이미 cache됐을 수 있는 projection을 commit한 뒤에는
ResourceProjectionChanged::draft(...)를 게시할 수 있습니다.
resource.projection.changed.v1 payload에는 명시적 Legal Entity scope 아래의 정규 App
key, Resource key, public record id만 들어갑니다. Frontend 소비자는 그 정확한
identity에 useResourceProjectionChange()를 사용하고 인가된 자기 API로 다시
조회합니다. Event는 표시 데이터를 담지 않으며 권한을 부여하지 않습니다.
Projection의 레코드는 App key와 Resource key, public record identity, 표시 값, 선택적 소유자 route를 가진 Resource Reference로 경계를 넘습니다. 이 값은 Eloquent model을 노출하지 않고, 참조 뒤 레코드에 대한 접근 권한도 부여하지 않습니다.
Board lane은 받아들일 action key를 선언합니다. Calendar occurrence는 전체 공개, 중립적인 busy time으로 redaction, 완전 제외 중 하나가 될 수 있습니다. Schedule item은 task·milestone 날짜, 진행률, 선택적 baseline·actual 날짜, dependency 참조를 담습니다. Renderer가 받기 전에 provider가 활성 actor와 선택적 Legal Entity context로 item과 action을 모두 걸러냅니다.
Resource Scheduler는 NxResourceSchedulerResource를 lane 계약으로,
NxResourceSchedulerOccurrence를 occurrence 계약으로 사용합니다. 각 occurrence는
resource_ids와 타입 있는 allowed-action binding을 가집니다. 같은 lane 안에서
옮기면 reschedule, 길이를 바꾸면 resize, 다른 lane으로 옮기면 reassign
command를 보냅니다. 빈 범위를 선택하면 onSelectRange가 start, end, all_day,
timezone, resource_ids를 담은 NxResourceSchedulerSelection을 받습니다. 이
callback은 App의 생성 UI에 초기값을 채울 수 있지만 renderer가 occurrence를
생성하거나 저장하지는 않습니다.
Calendar는 resource lane 없이 NxCalendarProps.onSelectRange로 같은 호출자 소유
경계를 제공합니다. Schedule은 선택적 parent Resource Reference를 받는
ResourceScheduleProps.onCreateResource를 제공합니다. 이 callback들은 호출자 소유
생성 흐름을 열 뿐이며, 기본 endpoint를 추가하거나 domain 소유권을 Core로 넘기지
않습니다.
경계
SDK는 component facade와 TypeScript 계약을 공개하고 구체 renderer는 공개하지
않습니다. Core가 NxCalendar, NxResourceScheduler, ResourceBoard,
ResourceSchedule 구현을 자기 alias 뒤에 유지하고 Host 설정 때 lazy binding합니다.
App Package는 @nexia/sdk와 /host subpath만 import합니다.
@shared/*나 @shell-primitives/* import는 계속 금지입니다.
컴포넌트는 기본 endpoint도 제공하지 않습니다. App이 자기 actor-authorized
projection을 읽고 타입 있는 onMove 또는 onAction callback을 App 소유 API
동작에 연결해야 합니다. onSelectRange와 onCreateResource도 App 소유 생성 흐름을
엽니다. Renderer는 drag나 selection gesture를 일반 field patch 또는 저장된
레코드로 바꾸지 않습니다.
Backend provider interface는 여전히 공개 Nexia\*가 아니라
App\ResourceBoard, App\ResourceCalendar, App\ResourceSchedule 아래의 Host
계약입니다. Resource Scheduler는 공개 PHP provider interface를 추가하지 않으며,
공개 frontend occurrence/resource 계약과 App 소유 API를 사용합니다. Production
provider registry도 아직 이를 설치하지 않습니다. App은 자기 API와 공개 React
컴포넌트를 함께 쓸 수 있지만 이 Core PHP interface를 구현하거나 import하면 안
됩니다.
Board는 Business Process도 아닙니다. Board는 상태를 투영하고 소유자 action을 제공하지만 BPMN Process는 장기 실행을 소유합니다. Schedule Timeline은 계획된 작업 화면이고, activity timeline은 시간순 증거이므로 projection action 계약이 없습니다.