feat(b09): 화면 틀 ↔ 탭 파일 계약 — B09Tab · B09TabContext (탭마다 파일 하나 · 틀은 등록만)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
2026-09-14 01:10:54 +09:00
co-authored by Claude Opus 5
parent bdc08c3251
commit 314c00406e
@@ -0,0 +1,33 @@
/* =============================================================================
* B09_Estimation_UI_Shell_Types.ts
* B09 원가계산 화면 틀 ↔ 탭 파일 계약 (PLAN 12장 · 2026-09-14 브레인 판정)
*
* - 탭마다 파일 하나: `B09_Estimation_UI_Tab_<이름>.ts` 가 `B09Tab` 하나를 내보냄.
* - 틀(`B09_Estimation_UI_Shell.ts`)은 **등록 한 줄씩**만 가짐. 등록 권한 = 랩탑_서브.
* - 틀은 탭을 고를 때마다 `body`·`panel` 을 비우고 `render(ctx, arg)` 를 부름.
* 탭의 자료·상태는 탭 파일이 스스로 들고 있음(다시 그릴 때 다시 받을지도 탭이 정함).
* - [재계산]·[확정]·[저장] 같은 단추는 탭이 자기 `panel`·`body` 에 둠 — 틀에 훅 없음.
* - ⚠ 화면이 값을 만들지 않음 — 표시·입력만. 계산은 서버.
* ========================================================================== */
export interface B09TabContext {
/** 지금 프로젝트 — 없으면 탭이 「프로젝트를 고르세요」 식으로 비워 둠. */
projectId: string | null;
/** 탭 본문 자리 — 고를 때마다 비워서 줌. */
body: HTMLElement;
/** 좌측 칸 자리 — 고를 때마다 비워서 줌. 안 쓰면 비워 둠. */
panel: HTMLElement;
/** 페이지 뿌리 — 근거 토글(`createProvenanceToggle`) 따위가 씀. */
root: HTMLElement;
/** 다른 탭으로 들어가기 — 내역 줄 → 일위대가 호표 → 단가산출근거처럼. `arg` 는 받는 탭이 읽음. */
open: (key: string, arg?: string) => void;
}
export interface B09Tab {
/** 탭 id — 틀 안에서 유일(`cost_sheet` · `boq` · `unit_price` · `price_basis` …). */
key: string;
/** 탭 제목 — 언어 바뀜을 따르게 함수로. */
label: () => string;
/** 고를 때마다 불림. `arg` = 다른 탭이 `open(key, arg)` 로 넘긴 값(없으면 undefined). */
render: (ctx: B09TabContext, arg?: string) => void;
}