export interface MuseumFloor { id: string label: string order: number } export type GuideDiagnosticsStatus = 'OK' | 'WARN' | 'ERROR' export type GuideDataIssueSeverity = 'info' | 'warn' | 'error' export interface GuideFloorDetail extends MuseumFloor { sourceCode?: string sourceName?: string modelReady?: boolean poiCount?: number spaceCount?: number guideStopCount?: number navigablePlaceCount?: number routeNodeCount?: number routeEdgeCount?: number routePlanningReady?: boolean warnings: string[] } export interface GuideMapDiagnosticsSummary { floorCount: number modelReadyFloorCount: number poiCount: number spaceCount: number guideStopCount: number navigablePlaceCount: number routeNodeCount: number routeEdgeCount: number } export interface GuideMapDiagnostics { mapId: string mapName: string sdkVersion?: string status: GuideDiagnosticsStatus floors: GuideFloorDetail[] summary: GuideMapDiagnosticsSummary warnings: string[] } export interface GuideDataIntegrityIssue { id: string scope: 'floor' | 'poi' severity: GuideDataIssueSeverity message: string floorId?: string floorLabel?: string poiId?: string fields?: string[] } export interface GuideDataIntegrityReport { status: GuideDiagnosticsStatus summary: { floorCount: number poiCount: number issueCount: number errorCount: number warningCount: number } issues: GuideDataIntegrityIssue[] warnings: string[] } export interface MuseumCategory { id: string label: string iconType?: string } export type MuseumPoiKind = 'facility' | 'hall' | 'hall_entrance' | 'guide' | 'space' export interface MuseumPoiEntrance { id: string name: string floorId: string floorLabel: string positionGltf?: [number, number, number] sourceObjectName?: string sourcePlaceId?: string routeNodeId?: string } export interface MuseumPoi { id: string name: string floorId: string floorLabel: string primaryCategory: MuseumCategory categories: MuseumCategory[] positionGltf?: [number, number, number] sourceObjectName?: string sourceConfidence?: string navigationReadiness?: string /** Explicit visitor-search eligibility supplied by the source or adapter policy. */ visitorVisible?: boolean accessible: boolean kind?: MuseumPoiKind hallId?: string hallName?: string spaceId?: string sourcePlaceId?: string sourceSpaceId?: string entrances?: MuseumPoiEntrance[] displayPolicy?: import('@/domain/poiDisplay').PoiDisplayPolicy } export type GuideLocationResolutionStatus = 'exact' | 'hallFallback' | 'candidate' | 'unavailable' export interface GuideLocationResolution { status: GuideLocationResolutionStatus poiId?: string sourcePoiId?: string actionText: string previewOnly: boolean confidence?: string method?: string floorId?: string floorLabel?: string note?: string } export interface MuseumHall { id: string name: string floorId?: string floorLabel?: string description?: string image?: string exhibitCount?: number outlineCount?: number stopCount?: number linkedExhibitCount?: number audioReadyStopCount?: number hasAudio?: boolean audioStatus?: string supportedLanguages?: string[] area?: string poiId?: string location?: GuideLocationResolution } export interface MuseumExhibit { id: string name: string hallId?: string hallName?: string floorId?: string floorLabel?: string image?: string description?: string poiId?: string sourcePoiId?: string mapX?: number mapY?: number location?: GuideLocationResolution artist?: string year?: string material?: string size?: string tags?: string[] guideContentId?: string guideTitle?: string guideText?: string audioUrl?: string audioDuration?: number audioLanguage?: string audioSubtitleUrl?: string audioHasText?: boolean audioText?: string audioTextLength?: number audioTextHash?: string audioNarrationTier?: 'STANDARD' | 'EXTENDED' audioUnavailableReason?: string audioAvailable?: boolean audioStatus?: string supportedLanguages?: string[] audioVariants?: Record imageStatus?: string imageSource?: string galleryUrls?: string[] linkedExhibitCount?: number isSharedStop?: boolean linkedExhibits?: Array<{ id: string name: string nameEn?: string code?: string exhibitCode?: string coverImageUrl?: string galleryUrls?: string[] sortOrder?: number }> stopInfoAvailable?: boolean stopInfoReason?: string resolvedStopId?: string playTargetType?: AudioPlayTargetType playTargetId?: string } export interface ExplainGuideStop { id: string name: string hallId?: string hallName?: string floorId?: string targetType?: AudioPlayTargetType targetId?: string coverImageUrl?: string description?: string hasAudio?: boolean audioStatus?: string supportedLanguages?: string[] hasTextRecord?: boolean poiId?: string mapX?: number mapY?: number outlineId?: string outlineName?: string sort?: number guideLevel?: string imageStatus?: string linkedExhibitCount?: number isSharedStop?: boolean linkedExhibits?: Array<{ id: string name: string nameEn?: string code?: string exhibitCode?: string coverImageUrl?: string galleryUrls?: string[] sortOrder?: number }> playTargetType?: AudioPlayTargetType playTargetId?: string } export interface ExplainGuideStopPage { items: ExplainGuideStop[] total: number pageNo: number pageSize: number hasMore: boolean } export interface ExplainBusinessUnit { id: string name: string hallId: string parentId?: string code?: string description?: string sort?: number level?: number previewImageUrl?: string guideStopCount: number linkedExhibitCount?: number audioReadyStopCount?: number hasAudio?: boolean audioStatus?: string supportedLanguages?: string[] stops: ExplainGuideStop[] } export interface GuideLocationPreview { poiId: string name: string floorId: string floorLabel: string primaryCategoryZh?: string positionGltf?: [number, number, number] sourceObjectName?: string kind?: MuseumPoiKind hallId?: string hallName?: string entrances?: MuseumPoiEntrance[] } export interface GuideStartLocation { label: string floor?: string source?: string } export interface GuidePreviewStep { id: string text: string } export interface GuideLocationPreviewPlan { id: string facilityId: string target: string summary: string steps: GuidePreviewStep[] targetLocation: GuideLocationPreview | null startLocation: GuideStartLocation | null } export interface GuideRouteReadiness { ready: boolean message: string requiredData: string[] } export interface GuideRouteTarget { poiId: string name: string floorId: string floorLabel: string categoryLabel?: string positionGltf?: [number, number, number] routeNodeId: string } export interface GuideRoutePoint { nodeId: string floorId: string position: [number, number, number] } export interface GuideRouteFloorSegment { floorId: string floorLabel: string points: GuideRoutePoint[] } export interface GuideRouteConnectorPoint { nodeId: string floorId: string floorLabel: string position: [number, number, number] connectorType?: string } export interface GuideRouteEndpoint { poiId: string name: string floorId: string floorLabel: string routeNodeId: string position: [number, number, number] } export interface GuideRouteResult { id: string start: GuideRouteEndpoint end: GuideRouteEndpoint distanceMeters: number nodeIds: string[] points: GuideRoutePoint[] floorSegments: GuideRouteFloorSegment[] connectorPoints: GuideRouteConnectorPoint[] } export interface MediaAsset { id: string type: 'audio' | 'image' | 'transcript' url?: string duration?: number language?: string available: boolean unavailableReason?: string } export type AudioPlayTargetType = 'ITEM' | 'STOP' export interface ExplainTrack { id: string exhibitId?: string hallId?: string title: string summary?: string mediaId?: string coverImage?: string poiId?: string sourcePoiId?: string location?: GuideLocationResolution floorId?: string available: boolean playTargetType?: AudioPlayTargetType playTargetId?: string } export interface SearchIndexItem { id: string name: string desc: string type: 'exhibit' | 'hall' | 'facility' poiId?: string floorId?: string exhibitId?: string hallId?: string }