Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container prepare 2026/09/20 03:55:50 Entrypoint initialization Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container place-scripts 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-0-ds6k9 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-1-2v4dh 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-2-6wthh 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-3-q97t8 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-4-mljvb 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-5-2h54g 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-6-f7k5k 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-7-74tpc 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-8-qbqgx 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-9-jpjlg 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-10-zq7cj 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-11-rzdzn 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-12-dpxm8 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-14-ckbww 2026/09/20 03:55:51 Decoded script /tekton/scripts/script-15-p2fsc Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container working-dir-initializer Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-git-clone git cloning url: https://github.com/greencapitaltrade/flash.git version refs/pull/439/head:PR-439@105a3a341ccaa0f94457abfb2476937db74a74ed to dir: source Cloning into 'source'... From https://github.com/greencapitaltrade/flash * [new ref] refs/pull/439/head -> PR-439 Switched to branch 'PR-439' HEAD is now at 105a3a34 fix(auth): retain magic-link consumption state checked out revision: refs/pull/439/head:PR-439@105a3a341ccaa0f94457abfb2476937db74a74ed to dir: source Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-git-merge setup git user email jenkins-x@googlegroups.com Using SHAs from PULL_REFS=main:cbf1ab88a7c5ff227c724de7de55a2f1bc6d74a2,439:105a3a341ccaa0f94457abfb2476937db74a74ed:refs/pull/439/head using base branch main and base sha cbf1ab88a7c5ff227c724de7de55a2f1bc6d74a2 merging sha: 105a3a341ccaa0f94457abfb2476937db74a74ed Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-jx-variables WARNING: no $GIT_SECRET_MOUNT_PATH environment variable set about to run: git clone --no-checkout --filter=blob:none --depth=1 https://github.com/greencapitaltrade/mcu.git /tmp/jx-git-3350295482 in dir /tmp Cloning into '/tmp/jx-git-3350295482'... about to run: git sparse-checkout set --no-cone jx-requirements.yml .jx/gitops/source-config.yaml in dir /tmp/jx-git-3350295482 about to run: git checkout in dir /tmp/jx-git-3350295482 Your branch is up to date with 'origin/main'. export APP_NAME='flash' export BRANCH_NAME='PR-439' export BUILD_NUMBER='2' export DOCKERFILE_PATH='Dockerfile' export DOCKER_REGISTRY='417755753340.dkr.ecr.ap-south-1.amazonaws.com' export DOCKER_REGISTRY_ORG='greencapitaltrade' export DOMAIN='gc-t.in' about to run: git rev-parse --abbrev-ref HEAD in dir . main export GIT_BRANCH='main' export JENKINS_X_URL='https://dashboard-jx.gc-t.in/greencapitaltrade/flash/PR-439/2' export JX_CHART_REPOSITORY='http://jenkins-x-chartmuseum.jx.svc.cluster.local:8080' export KANIKO_FLAGS='--skip-unused-stages --snapshotMode=redo' export MINK_AS='tekton-bot' version file VERSION does not exist export MINK_IMAGE='417755753340.dkr.ecr.ap-south-1.amazonaws.com/greencapitaltrade/flash:0.0.0-PR-439-2-SNAPSHOT' export NAMESPACE_SUB_DOMAIN='-jx.' export PIPELINE_KIND='pullrequest' export PUSH_CONTAINER_REGISTRY='417755753340.dkr.ecr.ap-south-1.amazonaws.com' export REPO_NAME='flash' export REPO_OWNER='greencapitaltrade' version file VERSION does not exist export VERSION='0.0.0-PR-439-2-SNAPSHOT' added variables to file: .jx/variables.sh added variables to file: .jx/variables.sh Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-build-yarn-install ➤ YN0000: Successfully set npmScopes.greencapitaltrade.npmRegistryServer to 'https://npm.pkg.github.com' ➤ YN0000: Successfully set npmScopes.greencapitaltrade.npmAuthToken to '********' ➤ YN0000: · Yarn 4.5.0 ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + expo-secure-store@npm:57.0.4, typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=8c6c40, typescript@npm:6.0.3 ➤ YN0000: └ Completed in 1s 41ms ➤ YN0000: ┌ Post-resolution validation ➤ YN0086: │ Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details. ➤ YN0000: └ Completed ➤ YN0000: ┌ Fetch step ➤ YN0066: │ typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=8c6c40: Cannot apply hunk #1 ➤ YN0066: │ typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=8c6c40: Cannot apply hunk #1 ➤ YN0000: └ Completed in 1m 1s ➤ YN0000: ┌ Link step ➤ YN0007: │ @biomejs/biome@npm:1.9.4 must be built because it never has been before or the last one failed ➤ YN0007: │ esbuild@npm:0.21.5 must be built because it never has been before or the last one failed ➤ YN0007: │ esbuild@npm:0.27.2 must be built because it never has been before or the last one failed ➤ YN0007: │ esbuild@npm:0.27.7 must be built because it never has been before or the last one failed ➤ YN0007: │ @pact-foundation/pact-core@npm:19.2.0 must be built because it never has been before or the last one failed ➤ YN0007: │ @scarf/scarf@npm:1.4.0 must be built because it never has been before or the last one failed ➤ YN0007: │ esbuild@npm:0.14.47 must be built because it never has been before or the last one failed ➤ YN0007: │ sharp@npm:0.34.5 must be built because it never has been before or the last one failed ➤ YN0007: │ esbuild@npm:0.25.10 must be built because it never has been before or the last one failed ➤ YN0007: │ @swc/core@npm:1.15.11 [ca773] must be built because it never has been before or the last one failed ➤ YN0007: │ unrs-resolver@npm:1.11.1 must be built because it never has been before or the last one failed ➤ YN0007: │ protobufjs@npm:7.6.4 must be built because it never has been before or the last one failed ➤ YN0007: │ starter-free@workspace:. must be built because it never has been before or the last one failed ➤ YN0000: │ starter-free@workspace:. STDOUT Tamagui dependencies look good ✅ ➤ YN0000: │ starter-free@workspace:. STDOUT API package built ➤ YN0000: │ starter-free@workspace:. STDOUT [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` ➤ YN0000: │ starter-free@workspace:. STDOUT built @my/config in 718 ms ➤ YN0000: │ starter-free@workspace:. STDOUT npm warn Unknown user config "unsafe-perm". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options. ➤ YN0000: │ starter-free@workspace:. STDOUT [baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` ➤ YN0000: │ starter-free@workspace:. STDOUT built @my/ui in 670 ms ➤ YN0000: │ starter-free@workspace:. STDOUT Done in 7s 162ms ➤ YN0000: └ Completed in 49s 820ms ➤ YN0000: · Done with warnings in 1m 52s Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-build-yarn-install-errors Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-pact-consumer RUN v2.1.9 /workspace/source 2026-09-20T03:58:05.266010Z WARN ThreadId(01) pact_models::pact: Note: Existing pact is an older specification version (V3), and will be upgraded ✓ apps/next/__tests__/pact/telemetry-consumer.pact.test.ts (2 tests) 6ms Test Files 1 passed (1) Tests 2 passed (2) Start at 03:58:04 Duration 755ms (transform 58ms, setup 0ms, collect 410ms, tests 6ms, environment 0ms, prepare 72ms) Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-pact-publish ➤ YN0000: · Yarn 4.5.0 ➤ YN0000: ┌ Resolution step ➤ YN0085: │ + @pact-foundation/pact-cli@npm:18.1.2, @pact-foundation/pact-cli-darwin-arm64@npm:18.1.2, @pact-foundation/pact-cli-darwin-x64@npm:18.1.2, and 4 more. ➤ YN0000: └ Completed in 0s 897ms ➤ YN0000: ┌ Fetch step ➤ YN0000: └ Completed in 3s 503ms ➤ YN0000: ┌ Link step ➤ YN0007: │ @pact-foundation/pact-cli@npm:18.1.2 must be built because it never has been before or the last one failed ➤ YN0000: └ Completed in 0s 299ms ➤ YN0000: · Done in 4s 717ms 📨 Attempting to publish pact for consumer: flash against provider: deadpool ✅ Created flash version 105a3a34 with tags main Next steps: Configure the version branch to be the value of your repository branch. Pact successfully published for flash version 105a3a34 and provider deadpool. View the published pact at http://pact-broker.jx.svc.cluster.local/pacts/provider/deadpool/consumer/flash/version/105a3a34 Events detected: contract_published (pact content is the same as previous version with tag main and no new tags were applied) Next steps: * Add Pact verification tests to the deadpool build. See https://docs.pact.io/go/provider_verification * Configure separate deadpool pact verification build and webhook to trigger it when the pact content changes. See https://docs.pact.io/go/webhooks Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-typecheck Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-typecheck-errors Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-unit-tests RUN v2.1.9 /workspace/source ✓ packages/app/features/asset/hooks/__tests__/useAssetTelemetry.test.ts (20 tests) 150ms stderr | packages/app/features/asset/screens/__tests__/reports-filters.test.tsx > ReportsScreen — Trips tab rendering (flag OFF by default) > Trips tab is visible regardless of enabled_features when flag is off React does not recognize the `alignItems` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `alignitems` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `justifyContent` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `justifycontent` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `flexBasis` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `flexbasis` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `flexGrow` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `flexgrow` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `maxWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `maxwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `minWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `minwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `numberOfLines` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `numberoflines` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `zIndex` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `zindex` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `flexWrap` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `flexwrap` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `backgroundColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `backgroundcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `hoverStyle` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `hoverstyle` instead. If you accidentally passed it from a parent component, remove it from the DOM element. Received `true` for a non-boolean attribute `horizontal`. If you want to write it to the DOM, pass a string instead: horizontal="true" or horizontal={value.toString()}. React does not recognize the `showsHorizontalScrollIndicator` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `showshorizontalscrollindicator` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `paddingTop` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `paddingtop` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `showsVerticalScrollIndicator` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `showsverticalscrollindicator` instead. If you accidentally passed it from a parent component, remove it from the DOM element. Unknown event handler property `onValueChange`. It will be ignored. React does not recognize the `flexDirection` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `flexdirection` instead. If you accidentally passed it from a parent component, remove it from the DOM element. stderr | packages/app/features/asset/screens/__tests__/reports-filters.test.tsx > ReportsScreen — legacy filter bar (flag OFF) > clicking the Asset trigger opens the options panel React does not recognize the `paddingHorizontal` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `paddinghorizontal` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `paddingVertical` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `paddingvertical` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `maxHeight` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `maxheight` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `marginTop` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `margintop` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `bordercolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderRadius` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderradius` instead. If you accidentally passed it from a parent component, remove it from the DOM element. stderr | packages/app/features/asset/screens/__tests__/reports-filters.test.tsx > ReportsScreen — v2 flag ON: filter bar, search, error, trips gating > renders the v2 filter bar with a Search input Invalid attribute name: `$lg` stderr | packages/app/features/asset/screens/__tests__/reports-filters.test.tsx > ReportsScreen — v2 flag ON: filter bar, search, error, trips gating > search input filters rows by license_plate after 300ms debounce React does not recognize the `textAlign` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `textalign` instead. If you accidentally passed it from a parent component, remove it from the DOM element. Invalid attribute name: `$md` ✓ packages/app/features/asset/screens/__tests__/reports-filters.test.tsx (25 tests) 981ms stderr | apps/next/__tests__/components/geofences-page.test.tsx > GeofencesPage component > renders without crashing React does not recognize the `textTransform` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `texttransform` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `marginTop` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `margintop` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `justifyContent` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `justifycontent` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `alignItems` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `alignitems` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `backgroundColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `backgroundcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderRadius` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderradius` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `bordercolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `minWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `minwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderBottomWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderbottomwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderBottomColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderbottomcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `paddingHorizontal` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `paddinghorizontal` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `numberOfLines` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `numberoflines` instead. If you accidentally passed it from a parent component, remove it from the DOM element. Received `true` for a non-boolean attribute `circular`. If you want to write it to the DOM, pass a string instead: circular="true" or circular={value.toString()}. Received `true` for a non-boolean attribute `chromeless`. If you want to write it to the DOM, pass a string instead: chromeless="true" or chromeless={value.toString()}. React does not recognize the `hoverStyle` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `hoverstyle` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderTopWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `bordertopwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderTopColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `bordertopcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderLeftWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderleftwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. React does not recognize the `borderLeftColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `borderleftcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element. stderr | apps/next/__tests__/components/geofences-page.test.tsx > GeofencesPage component > no search matches shows appropriate message React does not recognize the `textAlign` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `textalign` instead. If you accidentally passed it from a parent component, remove it from the DOM element. stderr | apps/next/__tests__/components/geofences-page.test.tsx > geofences feature gate > renders the not-enabled screen when the module is off React does not recognize the `maxWidth` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `maxwidth` instead. If you accidentally passed it from a parent component, remove it from the DOM element. ✓ apps/next/__tests__/components/geofences-page.test.tsx (20 tests) 757ms stderr | apps/next/__tests__/components/create-team-client.test.tsx > CreateTeamPageClient > renders without crashing Invalid value for prop `icon` on ) } // Stat card for speed, odometer etc function StatCard({ label, value, unit, trend, trendLabel, }: { label: string value: string | number unit: string trend?: 'up' | 'down' trendLabel?: string }) { return ( {label} {value} {unit} {trendLabel && ( {trendLabel} )} ) } // Status badge pill function StatusBadge({ icon, label, active, }: { icon: React.ReactNode label: string active: boolean }) { return ( {icon} {label} ) } // Recent event row function RecentEvent({ icon, iconBg, title, description, time, }: { icon: React.ReactNode iconBg: string title: string description: string time: string }) { return ( {icon} {title} {time} {description} ) } export function AssetTrackingScreen({ asset, breadcrumbItems = [] }: AssetTrackingScreenProps) { const [selectedIoTDevices, setSelectedIoTDevices] = useState([]) const [showCoordinates, setShowCoordinates] = useState(false) const router = useRouter() const { width: viewportWidth } = useWindowDimensions() const isNarrow = viewportWidth < 900 const params = useParams<{ team_id?: string }>() const teamId = params?.team_id // Asset routes are all team-scoped (`/[team_id]/assets/...`), so these // carry the prefix useTeamHref applies. const eventsHref = assetEventsPath(asset.id, teamId) const replayHref = assetReplayPath(asset.id, teamId) // Recent events preview — real data, not mocks. Full feed lives at // /assets//events. Empty state when there's nothing recent. const numericAssetId = typeof asset.id === 'number' ? asset.id : Number.parseInt(String(asset.id), 10) const { data: alertsData } = useQuery(GET_ASSET_ALERTS, { variables: { asset_id: numericAssetId, limit: 3 }, skip: !Number.isFinite(numericAssetId), fetchPolicy: 'cache-and-network', // Bifrost evaluates geofences on every ingested position; poll so // entry/exit breaches surface while the screen is open. pollInterval: 30_000, }) const recentAlerts: Array<{ id: string alert_type: string severity: string message: string timestamp: string }> = ((alertsData as any)?.assetAlerts as any[] | undefined) ?? [] const alertSeverityStyles: Record = { critical: { iconColor: '$red10', iconBg: '$red2' }, high: { iconColor: '$red10', iconBg: '$red2' }, warning: { iconColor: '$yellow10', iconBg: '$yellow2' }, medium: { iconColor: '$yellow10', iconBg: '$yellow2' }, info: { iconColor: '$accentColor', iconBg: '$blue2' }, low: { iconColor: '$accentColor', iconBg: '$blue2' }, } const formatAlertTime = (raw: string): string => { if (!raw) return '' // Backend returns ISO or \"YYYY-MM-DD HH:MM:SS\" — render the HH:MM // tail so the panel matches the existing visual rhythm. const m = raw.match(/(\\d{2}:\\d{2})(?::\\d{2})?/) return m ? m[1]! : raw.substring(0, 5) } // Canonical AssetLocation shape from the GraphQL schema is // { latitude, longitude } — Map, IoT devices, and the coordinate // display below all read those field names. Using {lat, lng} for the // fallback (and reading .lat/.lng later) silently crashed the screen // when asset.location was present (.toFixed on undefined → VC-MPKY-U). const assetLocation = asset.location // Map centre needs LatLng (lat/lng), not AssetLocation (latitude/longitude). const mapCenter = assetLocation ? { lat: assetLocation.latitude, lng: assetLocation.longitude } : undefined // Initialize selected IoT devices useEffect(() => { if (asset?.iot_devices) { setSelectedIoTDevices(asset.iot_devices.map((device) => String(device.id))) } }, [asset]) const handleIoTToggle = useCallback((deviceId: string) => { setSelectedIoTDevices((prev) => prev.includes(deviceId) ? prev.filter((i) => i !== deviceId) : [...prev, deviceId] ) }, []) const activeDevicesWithData = useMemo(() => { return ( asset?.iot_devices?.map((device) => ({ ...device, isVisible: selectedIoTDevices.includes(String(device.id)), })) || [] ) }, [asset?.iot_devices, selectedIoTDevices]) const mapConfig = useMemo(() => { return { center: mapCenter, zoom: 14, bounds: null } }, [mapCenter?.lat, mapCenter?.lng]) const vehicleDevice = asset.iot_devices.find((device) => deviceRole(device) === 'vehicle') const engineState = stateValue(vehicleDevice, 'engine_status') ?? stateValue(vehicleDevice, 'ignition') const hasEngineState = engineState != null const engineOn = engineState === true || engineState === 'on' || engineState === 'running' const isAnyConnected = asset.iot_devices.some((device) => device.connection_status === 'connected') return ( {breadcrumbItems.length > 0 && } {/* Main 60/40 Split Layout */} {/* Left: Map (60%) */} ({ ...device, active: device.active && device.isVisible, })), }, ]} selectedAsset={asset} center={mapConfig.center} zoom={mapConfig.zoom} onAssetSelect={() => {}} onOpenSettings={(assetId) => { const id = assetId || asset.id router.push(assetSettingsPath(id, teamId)) }} /> {/* Right: Telemetry Sidebar (40%) */} {/* Asset Header */} {getAssetLabel(asset)} setShowCoordinates(!showCoordinates)} > {assetLocation ? (showCoordinates || !asset.location?.address ? `${assetLocation.latitude.toFixed(4)}, ${assetLocation.longitude.toFixed(4)}` : asset.location.address) : 'Location not reported'} {asset.location?.latitude != null && asset.location?.longitude != null && ( )} {asset.status} Updated {asset.lastUpdate} {/* Quick Actions */} } label=\"History\" /> } label=\"Alerts\" /> {/* Module States */} Module States {hasEngineState && ( } label=\"Engine On\" active={engineOn} /> )} {hasEngineState && } label=\"Ignition\" active={engineOn} />} {asset.iot_devices.length > 0 && } label=\"IoT Link\" active={isAnyConnected} />} {/* IoT Devices */} {activeDevicesWithData.length > 0 && ( IoT Devices {activeDevicesWithData.map((device) => ( {device.name || device.device_id} {deviceDisplayRole(device)} {deviceRole(device) === 'battery' && finiteStateValue(device, 'battery_soc', 'soc') != null && ( <> {finiteStateValue(device, 'battery_soc', 'soc')}% )} {device.signal_strength != null && <> {device.signal_strength}/{IOT_CONFIG.SIGNAL.bars_max} } ))} )} {batteryDevices(asset).map((device) => ( ))} {asset.iot_devices.length === 0 && ( No devices attached Vehicle, battery, and other telemetry are not reported for this asset. )} {/* Recent Events */} Recent Events View All {recentAlerts.length > 0 ? ( {recentAlerts.map((alert) => { const style = alertSeverityStyles[(alert.severity || 'info').toLowerCase()] ?? alertSeverityStyles['info']! const Icon = alert.alert_type === 'geofence' ? MapPin : AlertCircle return ( } iconBg={style.iconBg} title={alert.alert_type.replace(/_/g, ' ')} description={alert.message} time={formatAlertTime(alert.timestamp)} /> ) })} ) : ( No recent events. )} ) } function BatteryDeviceSummary({ device }: { device: Asset['iot_devices'][number] }) { const socEntry = deviceState(device, 'battery_soc') ?? deviceState(device, 'soc') const sohEntry = deviceState(device, 'battery_soh') ?? deviceState(device, 'soh') const voltageEntry = deviceState(device, 'pack_voltage') ?? deviceState(device, 'battery_voltage') ?? deviceState(device, 'voltage') const currentAEntry = deviceState(device, 'current_a') ?? deviceState(device, 'pack_current') const currentMaEntry = deviceState(device, 'current_ma') const powerEntry = deviceState(device, 'power_w') ?? deviceState(device, 'pack_power') ?? deviceState(device, 'battery_power') ?? deviceState(device, 'power') const cyclesEntry = deviceState(device, 'cycle_count') ?? deviceState(device, 'cycles') const voltages = cellVoltages(device) const cellMin = voltages.length ? Math.min(...voltages) : undefined const cellMax = voltages.length ? Math.max(...voltages) : undefined const cellDelta = cellMin != null && cellMax != null ? cellMax - cellMin : undefined const chargeState = batteryChargeState(device) const chargeStatePending = pendingDeviceState(device, 'charge_state') ?? pendingDeviceState(device, 'charging') ?? pendingDeviceState(device, 'discharging') const isolationEntry = deviceState(device, 'isolation') ?? deviceState(device, 'isolation_status') const faultsEntry = deviceState(device, 'faults') ?? deviceState(device, 'fault') const freshness = device.last_data_received || device.last_seen const metric = (entry: typeof socEntry, unit = '') => { const value = finiteStateValue(device, entry?.key || '') return value == null ? 'Not reported' : `${value}${unit}` } const readable = (value: unknown): string => { if (value == null) return 'Not reported' if (typeof value === 'object') { try { return JSON.stringify(value) } catch { return 'Reported value' } } return String(value) } const metrics: Array<{ label: string; value: string }> = [] if (socEntry) metrics.push({ label: 'SoC', value: metric(socEntry, '%') }) if (sohEntry) metrics.push({ label: 'SoH', value: metric(sohEntry, '%') }) if (voltageEntry) metrics.push({ label: 'Pack voltage', value: metric(voltageEntry, ' V') }) if (currentAEntry) metrics.push({ label: 'Current', value: metric(currentAEntry, ' A') }) else if (currentMaEntry) metrics.push({ label: 'Current', value: metric(currentMaEntry, ' mA') }) if (powerEntry) metrics.push({ label: 'Pack power', value: metric(powerEntry, ' W') }) if (chargeState != null) metrics.push({ label: 'Charge state', value: chargeState }) else if (chargeStatePending) metrics.push({ label: 'Charge state', value: 'Pending confirmation' }) if (cyclesEntry) metrics.push({ label: 'Cycles', value: metric(cyclesEntry) }) if (isolationEntry) metrics.push({ label: 'Isolation', value: readable(stateValue(device, isolationEntry.key)) }) if (cellMin != null && cellMax != null) metrics.push({ label: 'Cell V min/max', value: `${cellMin} V / ${cellMax} V` }) if (cellDelta != null) metrics.push({ label: 'Cell delta', value: `${cellDelta} V` }) if (faultsEntry) metrics.push({ label: 'Faults', value: readable(stateValue(device, faultsEntry.key)) }) return ( Battery device {device.name || device.device_id} {device.active === false ? 'Disabled' : device.connection_status === 'connected' ? 'Connected' : device.connection_status === 'disconnected' ? 'Disconnected' : 'Unknown'} {metrics.length > 0 ? ( {metrics.map((item) => )} ) : ( No battery telemetry reported. )} {freshness ? `Last data ${freshness}` : 'Freshness not reported'} ) } function BatteryMetric({ label, value }: { label: string; value: string }) { return ( {label} {value} ) } " ❯ packages/app/features/asset/screens/__tests__/asset-tracking-location-shape.test.ts:59:26 57| // MapWrapper, the IoT device clones, and the coordinate display 58| // — all of which expect the canonical shape. 59| expect(screenSource).toMatch( | ^ 60| /asset\.location\s*\?\?\s*\{\s*latitude:[^}]*longitude:[^}]*\}/, 61| ) ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯ Test Files 2 failed | 107 passed | 1 skipped (110) Tests 2 failed | 922 passed | 10 skipped (934) Start at 03:58:44 Duration 62.34s (transform 5.65s, setup 0ms, collect 38.52s, tests 18.10s, environment 81.40s, prepare 14.47s) Showing logs for build greencapitaltrade/flash/pr-439 #2 stage from-build-pack and container step-unit-tests-errors commented on pull request #439 on repository greencapitaltrade/flash  Pipeline failed on stage 'from-build-pack' : container 'step-unit-tests-errors'. The execution of the pipeline has stopped.