apiVersion: jenkins.io/v1 kind: PipelineActivity metadata: annotations: lighthouse.jenkins-x.io/cloneURI: https://github.com/greencapitaltrade/bifrost.git lighthouse.jenkins-x.io/job: release pipeline.jenkins-x.io/traceID: 8592f5f3f5eb70eb1098f1638e82fca4 creationTimestamp: "2026-08-02T10:55:46Z" generation: 8 labels: branch: main build: "177" context: release created-by-lighthouse: "true" event-GUID: b205c6a4-8e60-11f1-8fc0-666ebeee74ba lighthouse.jenkins-x.io/baseSHA: e4058144c569073ae3fecd82ac24dc30e07f7737 lighthouse.jenkins-x.io/branch: main lighthouse.jenkins-x.io/buildNum: "1785668146520" lighthouse.jenkins-x.io/context: release lighthouse.jenkins-x.io/id: apitaltrade-bifrost-main-release-jmpwf lighthouse.jenkins-x.io/job: release lighthouse.jenkins-x.io/lastCommitSHA: e4058144c569073ae3fecd82ac24dc30e07f7737 lighthouse.jenkins-x.io/refs.org: greencapitaltrade lighthouse.jenkins-x.io/refs.repo: bifrost lighthouse.jenkins-x.io/type: postsubmit owner: greencapitaltrade podName: apitaltrade-bifrost-main-release-j8l8f-from-build-pack-pod provider: github repository: bifrost tekton.dev/pipeline: apitaltrade-bifrost-main-release managedFields: - apiVersion: jenkins.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:labels: f:branch: {} f:context: {} f:owner: {} f:provider: {} f:repository: {} f:spec: f:lastCommitMessage: {} f:lastCommitSHA: {} f:releaseNotesURL: {} f:version: {} manager: jx-changelog-0.10.29 operation: Update time: "2026-08-02T11:04:31Z" - apiVersion: jenkins.io/v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:annotations: .: {} f:lighthouse.jenkins-x.io/cloneURI: {} f:lighthouse.jenkins-x.io/job: {} f:pipeline.jenkins-x.io/traceID: {} f:labels: .: {} f:build: {} f:created-by-lighthouse: {} f:event-GUID: {} f:lighthouse.jenkins-x.io/baseSHA: {} f:lighthouse.jenkins-x.io/branch: {} f:lighthouse.jenkins-x.io/buildNum: {} f:lighthouse.jenkins-x.io/context: {} f:lighthouse.jenkins-x.io/id: {} f:lighthouse.jenkins-x.io/job: {} f:lighthouse.jenkins-x.io/lastCommitSHA: {} f:lighthouse.jenkins-x.io/refs.org: {} f:lighthouse.jenkins-x.io/refs.repo: {} f:lighthouse.jenkins-x.io/type: {} f:podName: {} f:tekton.dev/pipeline: {} f:spec: .: {} f:baseSHA: {} f:batchPipelineActivity: {} f:build: {} f:buildLogsUrl: {} f:completedTimestamp: {} f:context: {} f:gitBranch: {} f:gitOwner: {} f:gitRepository: {} f:gitUrl: {} f:message: {} f:pipeline: {} f:startedTimestamp: {} f:status: {} f:steps: {} manager: jx-build-controller operation: Update time: "2026-08-02T11:07:55Z" name: greencapitaltrade-bifrost-main-177 namespace: jx resourceVersion: "236775629" uid: 5a7088ed-5136-4dae-a09f-49f5e08ff8cc spec: baseSHA: e4058144c569073ae3fecd82ac24dc30e07f7737 batchPipelineActivity: {} build: "177" buildLogsUrl: s3://logs-gct-prod-20260425045301534100000007/jenkins-x/logs/greencapitaltrade/bifrost/main/177.log completedTimestamp: "2026-08-02T11:07:47Z" context: release gitBranch: main gitOwner: greencapitaltrade gitRepository: bifrost gitUrl: https://github.com/greencapitaltrade/bifrost.git lastCommitMessage: | refactor(asset_iot): move the telemetry metric long tail to a JSONB column `asset.iot.data` was purely columnar, so every new device metric cost a column in the model, a column in the TimescaleDB schema, and an edit at every INSERT/read site. Clean Electric made the price plain: its parser ships SOC, pack current, per-cell voltages, cellstack temperatures, cycle count and remaining capacity on every frame, and exactly one of them (`battery_voltage`) was persisted — because that was the only column that existed. Everything else was parsed, sent, and dropped on the floor. Add `metrics` (jsonb) and route the tail through it, keyed on the same vocabulary `asset.iot.device.device_state` already uses so the live snapshot and the history speak one language. A metric nobody has mapped keeps its wire name rather than being dropped, so adding a sensor is new data rather than a migration. That vocabulary keeps exactly one home. `_metric_aliases()` derives from `asset.iot.device._STATE_SOURCES` instead of restating it: the snapshot and the history are two readers of the mapping, never two owners. Merging the tables exposed a live gap — `current_ma` was missing from `_STATE_SOURCES`, so pack current (CE sends it on every frame) never reached device_state. Adding it there fixes both layers at once. Scoped to `power.*`, `telemetry.*` and selected `status.*`. `protocol_data` is excluded on purpose: Deadpool's normalizer already separates measurement channels from the protocol's framing-and-identity channel, and `metrics` must preserve that line rather than collapse it. Terra puts `packet_type`, `seq_num`, `presence` and whole `gps_delta_N` objects there; GT06 puts `imei`, `info_imsi` and `iccid`. Flattening it in would copy location data onto every row of a multi-sample frame, land a subscriber identity and SIM serial in a column read by charting and reporting, and make wire sequence numbers look like device readings. Nothing measurable is lost — CE's `cell_voltage_high/low_mv` duplicate `telemetry.cell_voltages_mv`. Unlike `device_state` this is not deep-merged and carries no per-key timestamps: a row is one immutable sample, the row's own `timestamp` column is the `at` for every key in it and is never copied inside the blob, and a key the frame didn't carry is absent. `get_metric_history()` filters in Python over an ORM search rather than with a SQL `metrics ? key` predicate, so record rules still apply — raw SQL would bypass exactly the ownership-chain scoping that protects location history. Its access path is already served by `idx_asset_iot_data_device_time`, so no GIN index is added yet; that pays only for cross-device key-existence reporting and should land with it. `battery_voltage`, `ext_voltage`, `odometer` and `engine_status` stay dual-written for the transition, guarded by a test asserting the two representations never disagree. Supersedes the interim per-metric column from #351 and the EAV `iot_kv` table proposed in #130. Refs #350 Co-Authored-By: Claude Opus 5 (1M context) lastCommitSHA: f01ab09382cec66c23d0a3312f2758a996746b97 message: 'Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 0' pipeline: greencapitaltrade/bifrost/main releaseNotesURL: https://github.com/greencapitaltrade/bifrost/releases/tag/v6.90.5 startedTimestamp: "2026-08-02T10:55:46Z" status: Succeeded steps: - kind: Stage stage: completedTimestamp: "2026-08-02T11:07:47Z" name: from build pack startedTimestamp: "2026-08-02T10:57:32Z" status: Succeeded steps: - completedTimestamp: "2026-08-02T10:57:59Z" name: Git Clone startedTimestamp: "2026-08-02T10:57:32Z" status: Succeeded - completedTimestamp: "2026-08-02T10:58:08Z" name: Next Version startedTimestamp: "2026-08-02T10:57:59Z" status: Succeeded - completedTimestamp: "2026-08-02T10:58:18Z" name: Jx Variables startedTimestamp: "2026-08-02T10:58:08Z" status: Succeeded - completedTimestamp: "2026-08-02T10:58:19Z" name: Setup Npm Nexus startedTimestamp: "2026-08-02T10:58:19Z" status: Succeeded - completedTimestamp: "2026-08-02T10:58:24Z" name: Setup Pip Cache startedTimestamp: "2026-08-02T10:58:20Z" status: Succeeded - completedTimestamp: "2026-08-02T11:00:38Z" name: Process Config Templates startedTimestamp: "2026-08-02T10:58:24Z" status: Succeeded - completedTimestamp: "2026-08-02T11:00:39Z" name: Update Asset Management Version startedTimestamp: "2026-08-02T11:00:39Z" status: Succeeded - completedTimestamp: "2026-08-02T11:00:42Z" name: Check Registry startedTimestamp: "2026-08-02T11:00:40Z" status: Succeeded - completedTimestamp: "2026-08-02T11:04:20Z" name: Build Container Build startedTimestamp: "2026-08-02T11:00:43Z" status: Succeeded - completedTimestamp: "2026-08-02T11:04:31Z" name: Promote Changelog startedTimestamp: "2026-08-02T11:04:21Z" status: Succeeded - completedTimestamp: "2026-08-02T11:04:36Z" name: Promote Helm Release startedTimestamp: "2026-08-02T11:04:32Z" status: Succeeded - completedTimestamp: "2026-08-02T11:06:06Z" name: Promote Jx Promote startedTimestamp: "2026-08-02T11:04:37Z" status: Succeeded - completedTimestamp: "2026-08-02T11:07:47Z" name: Publish Org Kb startedTimestamp: "2026-08-02T11:06:07Z" status: Succeeded - kind: Promote promote: environment: staging pullRequest: pullRequestURL: https://github.com/greencapitaltrade/mcu/pull/5118 startedTimestamp: "2026-08-02T11:05:32Z" status: Succeeded startedTimestamp: "2026-08-02T11:05:32Z" status: Succeeded - kind: Promote promote: environment: production pullRequest: pullRequestURL: https://github.com/greencapitaltrade/mcu/pull/5119 startedTimestamp: "2026-08-02T11:06:03Z" status: Succeeded startedTimestamp: "2026-08-02T11:06:03Z" status: Succeeded version: 6.90.5 status: {}