export type KbxWorkspaceLaunchMode = 'tab' | 'replace' | 'external' export type KbxRecentPolicy = 'screen' | 'route' | 'none' export interface KbxNavigationEntry { screenId: string path: string section: string group?: string keywords?: string[] order?: number launchMode?: KbxWorkspaceLaunchMode menuVisible?: boolean favoriteAllowed?: boolean /** Persist only a safe catalog path by default. Route mode is opt-in for non-sensitive parameterized routes. */ recentPolicy?: KbxRecentPolicy /** Menu discovery can be narrower than direct screen access. */ permissions?: string[] /** Lower values are surfaced first in Home quick-start. Omit when the screen should not be promoted. */ homePriority?: number /** Stable business-oriented group used by Home without inventing dashboard categories. */ homeGroup?: string } export interface KbxNavigationResolvedEntry extends KbxNavigationEntry { title: string module: 'OMS' | 'ERP' | 'WMS' | 'COMMON' permissions?: string[] } export interface KbxNavigationSection { key: string label: string module?: 'OMS' | 'ERP' | 'WMS' | 'COMMON' entries: KbxNavigationResolvedEntry[] } export interface KbxRecentNavigation { screenId: string path: string title: string visitedAt: string } export interface KbxWorkspaceTab { key: string screenId: string title: string path: string dirty?: boolean pinned?: boolean /** Safe route-only workspace restored from sessionStorage. Never implies restored form data. */ resumed?: boolean openedAt: string lastActivatedAt: string } export interface KbxNavigationPreference { favorites: string[] recents: KbxRecentNavigation[] sideNavCollapsed: boolean workspaceMaxTabs: number /** Visual preference only. Authorization and business state never depend on theme. */ themeMode?: 'light' | 'dark' /** Versioned key used to prevent cross-user/tenant preference leakage. */ scopeKey?: string } export type KbxHomeLaunchSource = 'dirty' | 'pinned' | 'open' | 'favorite' | 'recent' | 'priority' export interface KbxHomeLaunchItem { /** Stable UI key. Open workspace instances use tabKey so multiple records from one screen can coexist. */ launchKey: string screenId: string title: string module: 'OMS' | 'ERP' | 'WMS' | 'COMMON' section: string path: string source: KbxHomeLaunchSource sourceLabel: string tabKey?: string /** Optional human-readable route instance hint for multiple open records of the same screen. */ instanceLabel?: string homeGroup?: string } export type KbxHomeAttentionSource = 'dirty' | 'operation-failed' | 'notification-urgent' | 'operation-running' | 'notification' export interface KbxHomeAttentionItem { key: string source: KbxHomeAttentionSource priority: number /** Used for deterministic newest-first ordering inside the same business priority. */ occurredAt: string title: string detail?: string actionLabel: string screenId?: string path?: string tabKey?: string operationId?: string notificationId?: string } export interface KbxHomeAttentionQueue { items: KbxHomeAttentionItem[] totalCount: number overflowCount: number sourceCounts: Partial> } export interface KbxMenuSearchResult { screenId: string title: string module: 'OMS' | 'ERP' | 'WMS' | 'COMMON' section: string path: string keywords: string[] score: number }