From 1381b81bf058f59d142d18bbb3613431af424f01 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Sun, 19 Apr 2026 18:06:04 -0400 Subject: [PATCH] fix(idaa): move BB post loading from +page.ts to $effect in +page.svelte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +page.ts runs before layout effects and fires on SvelteKit link prefetch, causing private IDAA posts to be written to IDB before Novi auth runs. Moving to $effect gated on novi_verified eliminates the race entirely — $effect only runs post-mount, after the layout has verified the user. Co-Authored-By: Claude Sonnet 4.6 --- src/routes/idaa/(idaa)/bb/+page.svelte | 24 +++++++++++- src/routes/idaa/(idaa)/bb/+page.ts | 54 ++------------------------ 2 files changed, 27 insertions(+), 51 deletions(-) diff --git a/src/routes/idaa/(idaa)/bb/+page.svelte b/src/routes/idaa/(idaa)/bb/+page.svelte index 004065b4..a5224ef9 100644 --- a/src/routes/idaa/(idaa)/bb/+page.svelte +++ b/src/routes/idaa/(idaa)/bb/+page.svelte @@ -10,7 +10,7 @@ let log_lvl: number = $state(0); // *** Import Svelte specific import { page } from '$app/state'; import { browser } from '$app/environment'; -// import { untrack } from 'svelte'; +import { untrack } from 'svelte'; // import { goto, invalidate, pushState, replaceState } from '$app/navigation'; // *** Import other supporting libraries @@ -114,6 +114,28 @@ let lq__post_obj_li = $derived.by(() => { // }); // }); +// Initial post load — gated on novi_verified. +// WHY $effect and not +page.ts: +page.ts runs before layout effects and fires on SvelteKit +// link prefetch (hover), causing private IDAA data to be written to IDB before auth runs. +// $effect only runs post-mount, after the layout has completed Novi verification. +$effect(() => { + if (!$idaa_loc.novi_verified) return; + untrack(() => { + posts_func.load_ae_obj_li__post({ + api_cfg: $ae_api, + for_obj_type: 'account', + for_obj_id: data.account_id, + inc_comment_li: false, + enabled: 'enabled', + hidden: 'not_hidden', + limit: 19, + order_by_li: { updated_on: 'DESC', created_on: 'DESC' }, + try_cache: true, + log_lvl + }); + }); +}); + // Handle Single Post Load Trigger $effect(() => { if ($idaa_trig.post_id) { diff --git a/src/routes/idaa/(idaa)/bb/+page.ts b/src/routes/idaa/(idaa)/bb/+page.ts index c3a2fcab..fee8ebbd 100644 --- a/src/routes/idaa/(idaa)/bb/+page.ts +++ b/src/routes/idaa/(idaa)/bb/+page.ts @@ -1,15 +1,10 @@ import type { PageLoad } from './$types'; -console.log(`ae_idaa_bulletin_board [root] +page.ts start`); - -import { error } from '@sveltejs/kit'; -import { browser } from '$app/environment'; -import { get } from 'svelte/store'; -import { idaa_loc } from '$lib/stores/ae_idaa_stores'; -import { posts_func } from '$lib/ae_posts/ae_posts_functions'; +// Data loading for IDAA BB has been moved to +page.svelte $effect (gated on novi_verified). +// +page.ts runs before layout effects and fires during SvelteKit link prefetch, +// making it unsafe for private IDAA content — see BOOTSTRAP__AI_Agent_Quickstart.md. export const load = (async ({ params, parent }) => { - // route const log_lvl: number = 1; const data = await parent(); @@ -24,51 +19,10 @@ export const load = (async ({ params, parent }) => { ); ae_acct = { api: data.ae_api || {}, - slct: { - account_id: account_id - } + slct: { account_id: account_id } }; } - if (browser) { - // Auth gate: do not fetch or cache IDAA posts for unauthenticated users. - // +page.ts runs before +layout.svelte effects — without this check, the API call - // fires and writes to IDB before the layout's purge can run. - if (!get(idaa_loc).novi_verified) { - console.log('IDAA BB +page.ts: novi_verified=false — skipping post fetch.'); - return data; - } - - const load_post_obj_li = posts_func - .load_ae_obj_li__post({ - api_cfg: ae_acct.api, - for_obj_type: 'account', - for_obj_id: account_id, - inc_comment_li: false, - enabled: 'enabled', - hidden: 'not_hidden', - limit: 19, - order_by_li: { updated_on: 'DESC', created_on: 'DESC' }, - try_cache: true, - log_lvl: log_lvl - }) - .then((posts) => { - // REVIEW AGAIN: The backend now supports filtering out archived posts based on the 'archive_on' field. - // Workaround: V3 Search does not permit 'archive_on' field yet. - // Filter locally for posts that are not archived yet. - const now = new Date(); - return (posts || []).filter( - (p: any) => !p.archive_on || new Date(p.archive_on) > now - ); - }); - if (log_lvl) { - console.log(`load_post_obj_li = `, load_post_obj_li); - } - ae_acct.slct.post_obj_li = load_post_obj_li; - } - - // WARNING: Precaution against shared data between sites and sessions. data[account_id] = ae_acct; - return data; }) satisfies PageLoad;