chore: expose SGS hall POI diagnostics

This commit is contained in:
lyf
2026-06-30 02:07:47 +08:00
parent 9f59a856e7
commit 24699d2978
2 changed files with 99 additions and 5 deletions

View File

@@ -0,0 +1,24 @@
# Task 3 Report
Status: DONE
Files changed:
- `src/repositories/GuideModelRepository.ts`
Commands run:
- `node scripts/check-sgs-hall-poi-adapter.mjs`
- Output: `SGS hall POI adapter smoke check passed`
- `pnpm type-check`
- Output summary: `vue-tsc --noEmit` completed successfully in the main workspace.
Commits created:
- Main workspace commit will be created by controller after validation.
Self-review notes:
- Added dev-only SGS guide model diagnostics helper.
- Replaced silent floor endpoint catches with guarded diagnostics while preserving empty-array fallback behavior.
- Added hall-generation diagnostics for eligible spaces producing no renderable hall POIs and render filtering removing all hall POIs.
- No page/component SGS payload parsing was added.
Concerns:
- None after main workspace validation.

View File

@@ -12,7 +12,9 @@ import {
isIndoorNavigableFloor
} from '@/domain/guideFloor'
import {
createSgsHallPoiDiagnostics,
formatSgsFloorLabel,
toMuseumHallPoisFromSgs,
toMuseumPoiFromSgs
} from '@/data/adapters/sgsSdkGuideAdapter'
import {
@@ -38,7 +40,9 @@ const toRenderPoi = (poi: StaticNavPoiPayload): GuideRenderPoi => ({
primaryCategoryZh: poi.primaryCategoryZh,
iconType: poi.iconType || poi.primaryCategory,
positionGltf: poi.positionGltf,
sourceObjectName: poi.sourceObjectName
sourceObjectName: poi.sourceObjectName,
kind: poi.primaryCategory === 'touring_poi' ? 'hall' : 'facility',
hallName: poi.primaryCategory === 'touring_poi' ? poi.name : undefined
})
const toSgsRenderPoi = (
@@ -51,9 +55,22 @@ const toSgsRenderPoi = (
primaryCategoryZh: poi.primaryCategory.label,
iconType: poi.primaryCategory.iconType || poi.primaryCategory.id,
positionGltf: poi.positionGltf,
sourceObjectName: poi.sourceObjectName
sourceObjectName: poi.sourceObjectName,
kind: poi.kind,
hallId: poi.hallId,
hallName: poi.hallName,
entrances: poi.entrances
})
const dedupeRenderPoisById = (pois: GuideRenderPoi[]) => {
const seen = new Set<string>()
return pois.filter((poi) => {
if (!poi.id || seen.has(poi.id)) return false
seen.add(poi.id)
return true
})
}
const trimTrailingSlash = (value: string) => value.replace(/\/+$/, '')
const resolveSgsAssetUrl = (url?: string | null) => {
@@ -100,6 +117,14 @@ const isSharedSgsModelAsset = (
return modelUrl === overviewModelUrl || allModelUrls.filter((url) => url === modelUrl).length > 1
}
const warnSgsGuideModelDiagnostics = (
message: string,
payload: Record<string, unknown>
) => {
if (!import.meta.env.DEV) return
console.warn(`[SGS guide model] ${message}`, payload)
}
const getSgsFloorModelMatchKeys = (floor: SgsSdkFloorSummaryPayload, label: string) => (
[
String(floor.floorId),
@@ -210,10 +235,55 @@ export class SgsSdkGuideModelRepository implements GuideModelRepository {
))
if (!matchedFloor) return []
const pois = await this.provider.getFloorPois(String(matchedFloor.floorId))
return pois
.map((poi) => toSgsRenderPoi(toMuseumPoiFromSgs(poi, manifest.floors)))
const resolvedFloorId = String(matchedFloor.floorId)
const loadFloorData = async <T>(
endpoint: 'pois' | 'spaces' | 'navigablePlaces',
loader: () => Promise<T[]>
) => {
try {
return await loader()
} catch (error) {
warnSgsGuideModelDiagnostics('floor data request failed', {
floorId: resolvedFloorId,
endpoint,
error: error instanceof Error ? error.message : String(error)
})
return []
}
}
const [pois, spaces, navigablePlaces] = await Promise.all([
loadFloorData('pois', () => this.provider.getFloorPois(resolvedFloorId)),
loadFloorData('spaces', () => this.provider.getFloorSpaces(resolvedFloorId)),
loadFloorData('navigablePlaces', () => this.provider.getNavigablePlaces(resolvedFloorId))
])
const ordinaryPois = pois.map((poi) => toSgsRenderPoi(toMuseumPoiFromSgs(poi, manifest.floors)))
const museumHallPois = toMuseumHallPoisFromSgs(spaces, navigablePlaces, manifest.floors, resolvedFloorId)
const hallDiagnostics = createSgsHallPoiDiagnostics(spaces, navigablePlaces, museumHallPois)
if (hallDiagnostics.eligibleSpaceCount > 0 && hallDiagnostics.hallPoiWithPositionCount === 0) {
warnSgsGuideModelDiagnostics('eligible hall spaces produced no renderable hall POIs', {
floorId: resolvedFloorId,
...hallDiagnostics
})
}
const hallPois = museumHallPois.map(toSgsRenderPoi)
const renderPois = dedupeRenderPoisById([
...hallPois,
...ordinaryPois
])
.filter((poi) => Array.isArray(poi.positionGltf) && poi.positionGltf.length === 3)
if (hallDiagnostics.hallPoiWithPositionCount > 0 && !renderPois.some((poi) => poi.primaryCategory === 'exhibition_hall')) {
warnSgsGuideModelDiagnostics('render POI filter removed all hall POIs', {
floorId: resolvedFloorId,
...hallDiagnostics,
renderPoiCount: renderPois.length
})
}
return renderPois
}
}