Merge fix/frontend-bugs-2026-07-08: fix Reports 500, Settings white screen, SidebarGroup exceptions

This commit is contained in:
2026-07-08 10:12:14 +08:00
6 changed files with 67 additions and 6 deletions
@@ -0,0 +1,22 @@
-- Revert reporting_events_rollups to the original (incorrect) init schema structure.
-- WARNING: this restores the broken column names (dimension, dimension_value, metric_name,
-- value, value_in_business_hours, period) that do not match the GORM model.
DROP TABLE IF EXISTS reporting_events_rollups;
CREATE TABLE IF NOT EXISTS reporting_events_rollups (
id SERIAL PRIMARY KEY,
account_id INTEGER NOT NULL,
dimension VARCHAR(50) NOT NULL,
dimension_value VARCHAR(255) NOT NULL,
metric_name VARCHAR(50) NOT NULL,
value DOUBLE PRECISION NOT NULL,
value_in_business_hours DOUBLE PRECISION DEFAULT 0,
period VARCHAR(50) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
deleted_at TIMESTAMP WITH TIME ZONE,
UNIQUE(account_id, dimension, dimension_value, metric_name, period)
);
CREATE INDEX idx_reporting_events_rollups_deleted_at ON reporting_events_rollups(deleted_at);
@@ -0,0 +1,29 @@
-- Fix reporting_events_rollups table structure to match GORM model
-- The init schema (000001) created columns: dimension, dimension_value, metric_name,
-- value, value_in_business_hours, period — but the GORM model and all Go code use:
-- date, dimension_type, dimension_id, metric, count, sum_value, sum_value_business_hours.
-- This migration drops and recreates the table with the correct schema.
-- The table is empty in practice (rollups are computed on-demand), so data loss is negligible.
DROP TABLE IF EXISTS reporting_events_rollups;
CREATE TABLE reporting_events_rollups (
id SERIAL PRIMARY KEY,
account_id INTEGER NOT NULL,
date DATE NOT NULL,
dimension_type VARCHAR(20) NOT NULL,
dimension_id INTEGER NOT NULL,
metric VARCHAR(50) NOT NULL,
count BIGINT NOT NULL DEFAULT 0,
sum_value DOUBLE PRECISION NOT NULL DEFAULT 0,
sum_value_business_hours DOUBLE PRECISION NOT NULL DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
deleted_at TIMESTAMP WITH TIME ZONE,
UNIQUE(account_id, date, dimension_type, dimension_id, metric)
);
CREATE INDEX idx_reporting_events_rollups_deleted_at ON reporting_events_rollups(deleted_at);
CREATE INDEX idx_reporting_events_rollups_account_id ON reporting_events_rollups(account_id) WHERE deleted_at IS NULL;
CREATE INDEX idx_reporting_events_rollups_date ON reporting_events_rollups(date) WHERE deleted_at IS NULL;
CREATE INDEX idx_reporting_events_rollups_dimension ON reporting_events_rollups(dimension_type, dimension_id) WHERE deleted_at IS NULL;
@@ -143,7 +143,7 @@ const activeChild = computed(() => {
if (activeOnPages.length > 0) {
const rankedPage = activeOnPages.find(child => {
return Object.keys(child.to.params)
return Object.keys(child.to?.params ?? {})
.map(key => {
return String(child.to.params[key]) === String(route.params[key]);
})
@@ -8,7 +8,10 @@ import SectionLayout from './SectionLayout.vue';
const { t } = useI18n();
const { currentAccount } = useAccount();
const getAccountId = computed(() => currentAccount.value.id.toString());
const getAccountId = computed(() => {
const id = currentAccount.value?.id;
return id != null ? id.toString() : '';
});
</script>
<template>
@@ -25,11 +25,14 @@ const hasAnUpdateAvailable = computed(() => {
});
const gitSha = computed(() => {
return globalConfig.value.gitSha.substring(0, 7);
const sha = globalConfig.value?.gitSha;
return sha ? sha.substring(0, 7) : '';
});
const copyGitSha = () => {
copyTextToClipboard(globalConfig.value.gitSha);
if (globalConfig.value?.gitSha) {
copyTextToClipboard(globalConfig.value.gitSha);
}
};
</script>
@@ -43,8 +46,9 @@ const copyGitSha = () => {
}}
</div>
<div class="divide-x divide-n-slate-9">
<span class="px-2">{{ `v${globalConfig.appVersion}` }}</span>
<span class="px-2">{{ `v${globalConfig?.appVersion ?? ''}` }}</span>
<span
v-if="gitSha"
v-tooltip="t('COMPONENTS.CODE.BUTTON_TEXT')"
class="px-2 build-id cursor-pointer"
@click="copyGitSha"
@@ -8,7 +8,10 @@ import { isOnOnboardingView } from 'v3/helpers/RouteHelper';
import AnalyticsHelper from '../helper/AnalyticsHelper';
const ONBOARDING_STEPS = ['account_details', 'enrichment'];
const routes = [...dashboard.routes];
const routes = [
{ path: '/', redirect: '/app/login' },
...dashboard.routes,
];
export const router = createRouter({ history: createWebHistory(), routes });