Fix Reports 500, Settings white screen, SidebarGroup exceptions

ISS-01: Fix reporting_events_rollups table schema mismatch
- The init migration (000001) created columns (dimension, dimension_value,
  metric_name, value, value_in_business_hours, period) that do not match
  the GORM model which expects (date, dimension_type, dimension_id, metric,
  count, sum_value, sum_value_business_hours)
- Add migration 000048 to drop and recreate the table with correct schema
  matching the GORM model and all Go code that references it
- Fixes: GET /api/v2/accounts/:id/reports returning HTTP 500 with
  'column date does not exist (SQLSTATE 42703)'

ISS-02: Fix Settings > General page white screen
- AccountId.vue: add null-safe access for currentAccount.value.id before
  calling toString() — currentAccount can be {} when account data not yet
  loaded in store
- BuildInfo.vue: add null-safe access for globalConfig.value.gitSha and
  globalConfig.value.appVersion; guard copyGitSha with existence check;
  add v-if guard on gitSha span in template

ISS-04: Fix SidebarGroup mounted hook exceptions
- SidebarGroup.vue: Object.keys(child.to.params) throws TypeError when
  child.to.params is undefined; add null-safe fallback Object.keys(child.to?.params ?? {})
- This was the source of the 29 recurring JS exceptions on every Settings
  page navigation

ISS-05: Fix Vue Router root path warning
- Add root route { path: '/', redirect: '/app/login' } to silence
  'No match found for location with path /' warning
This commit is contained in:
2026-07-08 10:02:29 +08:00
parent 37f8c01977
commit be38051ac5
6 changed files with 67 additions and 6 deletions
@@ -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 });