From 821bfc5bcfaafcb3ada49b42098a3d7038a45a65 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Tue, 14 Apr 2026 16:43:31 +0200 Subject: [PATCH] chore: standardize dev-only debug logging across all three SPAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Router guards: - apps/app: added DEV-gated logging matching admin pattern (route info, auth decisions, org selection, access granted/denied) - apps/portal: added DEV-gated logging matching admin pattern (route info, auth decisions, backward-compat redirects) - apps/admin: already had full logging (unchanged) Ungated console statements fixed: - admin/main.ts: error handler, plugin registration, mount errors - admin/pages/login.vue, register.vue: catch block errors - admin/pages/events/index.vue: fetch error logging - admin/pages/wizard-examples: demo form submit logging - admin/pages/faq.vue: catch block error All console statements in Crewli-authored code are now gated behind import.meta.env.DEV — zero console output in production builds. Vuexy template demo files (views/demos/*) left as-is. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/admin/src/main.ts | 10 ++++++---- apps/admin/src/pages/events/index.vue | 4 ++-- apps/admin/src/pages/login.vue | 2 +- apps/admin/src/pages/pages/faq.vue | 2 +- apps/admin/src/pages/register.vue | 2 +- .../src/pages/wizard-examples/create-deal.vue | 2 +- .../wizard-examples/property-listing.vue | 2 +- apps/app/src/plugins/1.router/guards.ts | 19 +++++++++++++++++-- apps/portal/src/plugins/1.router/guards.ts | 16 +++++++++++++++- 9 files changed, 45 insertions(+), 14 deletions(-) diff --git a/apps/admin/src/main.ts b/apps/admin/src/main.ts index 48117734..84b414cb 100644 --- a/apps/admin/src/main.ts +++ b/apps/admin/src/main.ts @@ -14,8 +14,10 @@ const app = createApp(App) // Error handler for unhandled errors app.config.errorHandler = (err, instance, info) => { - console.error('Vue Error:', err, info) - console.error('Component:', instance) + if (import.meta.env.DEV) { + console.error('Vue Error:', err, info) + console.error('Component:', instance) + } } // Register plugins @@ -24,7 +26,7 @@ app.use(VueQueryPlugin, queryClientConfig) try { registerPlugins(app) } catch (error) { - console.error('Failed to register plugins:', error) + if (import.meta.env.DEV) console.error('Failed to register plugins:', error) throw error } @@ -32,7 +34,7 @@ try { try { app.mount('#app') } catch (error) { - console.error('Failed to mount app:', error) + if (import.meta.env.DEV) console.error('Failed to mount app:', error) // Show error message to user (safe DOM construction — no innerHTML with variables) const el = document.getElementById('app')! el.innerHTML = '' diff --git a/apps/admin/src/pages/events/index.vue b/apps/admin/src/pages/events/index.vue index 574735a1..a73fe431 100644 --- a/apps/admin/src/pages/events/index.vue +++ b/apps/admin/src/pages/events/index.vue @@ -31,7 +31,7 @@ watch([page, itemsPerPage], async () => { }) } catch (err) { - console.error('Failed to fetch events:', err) + if (import.meta.env.DEV) console.error('Failed to fetch events:', err) } }, { immediate: true }) @@ -44,7 +44,7 @@ watch(organisationId, async (id) => { }) } catch (err) { - console.error('Failed to fetch events:', err) + if (import.meta.env.DEV) console.error('Failed to fetch events:', err) } } }) diff --git a/apps/admin/src/pages/login.vue b/apps/admin/src/pages/login.vue index f60288fe..e1400117 100644 --- a/apps/admin/src/pages/login.vue +++ b/apps/admin/src/pages/login.vue @@ -96,7 +96,7 @@ const login = async () => { router.replace(rawTo.startsWith('/') ? rawTo : '/') } catch (err) { - console.error(err) + if (import.meta.env.DEV) console.error(err) } } diff --git a/apps/admin/src/pages/pages/faq.vue b/apps/admin/src/pages/pages/faq.vue index e9698117..4cba695f 100644 --- a/apps/admin/src/pages/pages/faq.vue +++ b/apps/admin/src/pages/pages/faq.vue @@ -12,7 +12,7 @@ const fetchFaqs = async () => { query: { q: faqSearchQuery.value, }, - }).catch(err => console.log(err)) + }).catch(err => { if (import.meta.env.DEV) console.log(err) }) faqs.value = data } diff --git a/apps/admin/src/pages/register.vue b/apps/admin/src/pages/register.vue index a663a8ad..f77efc0b 100644 --- a/apps/admin/src/pages/register.vue +++ b/apps/admin/src/pages/register.vue @@ -99,7 +99,7 @@ const register = async () => { }) } catch (err) { - console.error(err) + if (import.meta.env.DEV) console.error(err) } finally { isLoading.value = false diff --git a/apps/admin/src/pages/wizard-examples/create-deal.vue b/apps/admin/src/pages/wizard-examples/create-deal.vue index 39011ed2..267dbcd1 100644 --- a/apps/admin/src/pages/wizard-examples/create-deal.vue +++ b/apps/admin/src/pages/wizard-examples/create-deal.vue @@ -65,7 +65,7 @@ const createDealData = ref({ }) const onSubmit = () => { - console.log('createDealData :>> ', createDealData.value) + if (import.meta.env.DEV) console.log('createDealData :>> ', createDealData.value) } diff --git a/apps/admin/src/pages/wizard-examples/property-listing.vue b/apps/admin/src/pages/wizard-examples/property-listing.vue index 59973ecf..90a4af3b 100644 --- a/apps/admin/src/pages/wizard-examples/property-listing.vue +++ b/apps/admin/src/pages/wizard-examples/property-listing.vue @@ -90,7 +90,7 @@ const propertyListingData = ref({ const currentStep = ref(0) const onSubmit = () => { - console.log('propertyListingData :>> ', propertyListingData.value) + if (import.meta.env.DEV) console.log('propertyListingData :>> ', propertyListingData.value) } diff --git a/apps/app/src/plugins/1.router/guards.ts b/apps/app/src/plugins/1.router/guards.ts index a05f23ce..33cb04f8 100644 --- a/apps/app/src/plugins/1.router/guards.ts +++ b/apps/app/src/plugins/1.router/guards.ts @@ -3,7 +3,7 @@ import { useAuthStore } from '@/stores/useAuthStore' import { useOrganisationStore } from '@/stores/useOrganisationStore' export function setupGuards(router: Router) { - router.beforeEach(async (to) => { + router.beforeEach(async (to, from) => { const authStore = useAuthStore() // Wait for initialization to complete (only blocks on first navigation) @@ -11,24 +11,36 @@ export function setupGuards(router: Router) { await authStore.initialize() } + if (import.meta.env.DEV) { + console.log('🔒 Router Guard:', { + to: to.path, + from: from.path, + isAuthenticated: authStore.isAuthenticated, + }) + } + const isPublic = to.meta.public === true // Allow public routes (login, auth pages, 404) — but redirect authenticated users away from login if (isPublic) { const guestOnlyPaths = ['/login', '/forgot-password', '/reset-password', '/verify-email-change'] if (authStore.isAuthenticated && guestOnlyPaths.some(p => to.path === p)) { + if (import.meta.env.DEV) console.log('🔄 Redirecting logged-in user away from login page') return { name: 'dashboard' } } + if (import.meta.env.DEV) console.log('✅ Public route, allowing access') return } // Routes that opt out of auth (e.g. invitations) if (to.meta.requiresAuth === false) { + if (import.meta.env.DEV) console.log('✅ Route does not require auth') return } // Not authenticated → redirect to login with return URL if (!authStore.isAuthenticated) { + if (import.meta.env.DEV) console.log('🚫 Not authenticated, redirecting to login') return { path: '/login', query: { to: to.fullPath } } } @@ -37,13 +49,16 @@ export function setupGuards(router: Router) { const isSelectOrgPage = to.path === '/select-organisation' if (isSelectOrgPage) { - // Already on the org selection page — allow + if (import.meta.env.DEV) console.log('✅ Organisation selection page') return } // If user has organisations but none selected → redirect to selection if (authStore.organisations.length > 0 && !orgStore.hasOrganisation) { + if (import.meta.env.DEV) console.log('🔄 No organisation selected, redirecting') return { path: '/select-organisation' } } + + if (import.meta.env.DEV) console.log('✅ Access granted') }) } diff --git a/apps/portal/src/plugins/1.router/guards.ts b/apps/portal/src/plugins/1.router/guards.ts index 084b5ca6..4a51d0b6 100644 --- a/apps/portal/src/plugins/1.router/guards.ts +++ b/apps/portal/src/plugins/1.router/guards.ts @@ -12,13 +12,21 @@ const dashboardRedirects: Record = { } export function setupGuards(router: Router) { - router.beforeEach(async (to) => { + router.beforeEach(async (to, from) => { const authStore = useAuthStore() if (!authStore.isInitialized) { await authStore.initialize() } + if (import.meta.env.DEV) { + console.log('🔒 Router Guard:', { + to: to.path, + from: from.path, + isAuthenticated: authStore.isAuthenticated, + }) + } + // Hydrate portal data once after auth is confirmed if (authStore.isAuthenticated) { const portalStore = usePortalStore() @@ -28,6 +36,7 @@ export function setupGuards(router: Router) { // Backward-compat redirects for old dashboard routes const redirect = dashboardRedirects[to.path] if (redirect && authStore.isAuthenticated) { + if (import.meta.env.DEV) console.log('🔄 Backward-compat redirect:', to.path, '→', redirect) return { path: redirect } } @@ -36,15 +45,20 @@ export function setupGuards(router: Router) { // Public routes — no auth check needed if (!requiresAuth) { if (authStore.isAuthenticated && guestOnlyPaths.some(p => to.path === p || to.path.startsWith(`${p}/`))) { + if (import.meta.env.DEV) console.log('🔄 Redirecting logged-in user away from login page') return { path: '/evenementen' } } + if (import.meta.env.DEV) console.log('✅ Public route, allowing access') return } // Auth required — redirect to login if not authenticated if (!authStore.isAuthenticated) { + if (import.meta.env.DEV) console.log('🚫 Not authenticated, redirecting to login') return { path: '/login', query: { to: to.fullPath } } } + + if (import.meta.env.DEV) console.log('✅ Access granted') }) }