fix(idaa): move BB post loading from +page.ts to $effect in +page.svelte

+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 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-04-19 18:06:04 -04:00
parent 686b289bdb
commit 1381b81bf0
2 changed files with 27 additions and 51 deletions

View File

@@ -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) {

View File

@@ -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;