refactor(events): enforce hierarchy consistency and id standardization

This commit is contained in:
Scott Idem
2026-02-25 17:53:20 -05:00
parent 197adff33b
commit 17620b6fbc
3 changed files with 112 additions and 24 deletions

View File

@@ -23,6 +23,8 @@ export async function load_ae_obj_id__event({
inc_file_li = false,
inc_location_li = false,
inc_session_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_template_li = false,
enabled = 'enabled',
hidden = 'not_hidden',
@@ -36,6 +38,8 @@ export async function load_ae_obj_id__event({
inc_file_li?: boolean;
inc_location_li?: boolean;
inc_session_li?: boolean;
inc_presentation_li?: boolean;
inc_presenter_li?: boolean;
inc_template_li?: boolean;
enabled?: 'enabled' | 'all' | 'not_enabled';
hidden?: 'hidden' | 'all' | 'not_hidden';
@@ -46,6 +50,9 @@ export async function load_ae_obj_id__event({
console.log(`*** load_ae_obj_id__event() *** event_id=${event_id} (SWR Optimization)`);
}
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
if (inc_presenter_li || inc_presentation_li) inc_session_li = true;
// 1. FAST PATH: Return cached data immediately
if (try_cache) {
try {
@@ -56,15 +63,15 @@ export async function load_ae_obj_id__event({
// Trigger background refresh
_refresh_event_v3_background({
api_cfg, event_id, view, try_cache,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
enabled, hidden,
log_lvl: 0
});
// Still handle nested loads for the cached version to ensure UI richness
return await _handle_nested_loads(cached_event, {
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li,
enabled, hidden, log_lvl
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
enabled, hidden, try_cache, log_lvl
});
}
} catch (e) {
@@ -75,7 +82,7 @@ export async function load_ae_obj_id__event({
// 2. SLOW PATH: Wait for API if cache is empty or try_cache is false
return await _refresh_event_v3_background({
api_cfg, event_id, view, try_cache,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
enabled, hidden,
log_lvl
});
@@ -86,7 +93,7 @@ export async function load_ae_obj_id__event({
*/
async function _refresh_event_v3_background({
api_cfg, event_id, view, try_cache,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li,
inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
enabled, hidden,
log_lvl
}: any) {
@@ -123,8 +130,8 @@ async function _refresh_event_v3_background({
}
return await _handle_nested_loads(processed_obj, {
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li,
enabled, hidden, log_lvl
api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li,
enabled, hidden, try_cache: false, log_lvl
});
}
} catch (error: any) {
@@ -136,8 +143,8 @@ async function _refresh_event_v3_background({
/**
* Shared logic for loading nested child collections
*/
async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_template_li, enabled, hidden, log_lvl }: any) {
if (log_lvl) console.log(`Loading nested collections for event: ${event_obj.event_id} (Devices: ${inc_device_li}, Files: ${inc_file_li}, Locations: ${inc_location_li}, Sessions: ${inc_session_li}, Templates: ${inc_template_li})`);
async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, inc_file_li, inc_location_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_template_li, enabled, hidden, try_cache, log_lvl }: any) {
if (log_lvl) console.log(`Loading nested collections for event: ${event_obj.event_id} (Devices: ${inc_device_li}, Files: ${inc_file_li}, Locations: ${inc_location_li}, Sessions: ${inc_session_li}, Presentations: ${inc_presentation_li}, Presenters: ${inc_presenter_li}, Templates: ${inc_template_li})`);
// String-Only ID Vision: the '_id' field IS the string ID
const current_event_id = event_obj.id || event_obj.event_id;
@@ -149,6 +156,7 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
api_cfg,
for_obj_type: 'event',
for_obj_id: current_event_id,
try_cache,
log_lvl
}).then(res => event_obj.event_device_obj_li = res));
}
@@ -159,6 +167,7 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
for_obj_id: current_event_id,
enabled: 'all',
limit: 100,
try_cache,
log_lvl
}).then(res => event_obj.event_file_li = res));
}
@@ -169,6 +178,7 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
for_obj_id: current_event_id,
enabled,
hidden,
try_cache,
log_lvl
}).then(res => event_obj.event_location_obj_li = res));
}
@@ -177,6 +187,11 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
api_cfg,
for_obj_type: 'event',
for_obj_id: current_event_id,
inc_presentation_li,
inc_presenter_li,
enabled,
hidden,
try_cache,
log_lvl
}).then(res => event_obj.event_session_obj_li = res));
}
@@ -184,6 +199,7 @@ async function _handle_nested_loads(event_obj: any, { api_cfg, inc_device_li, in
tasks.push(load_ae_obj_li__event_badge_template({
api_cfg,
event_id: current_event_id,
try_cache,
log_lvl
}).then(res => event_obj.event_badge_template_obj_li = res));
}
@@ -203,6 +219,8 @@ export async function load_ae_obj_li__event({
hidden = 'not_hidden',
view = 'default',
inc_session_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
limit = 9,
offset = 0,
order_by_li = { start_datetime: 'DESC' } as const,
@@ -217,6 +235,8 @@ export async function load_ae_obj_li__event({
hidden?: 'hidden' | 'all' | 'not_hidden';
view?: string;
inc_session_li?: boolean;
inc_presentation_li?: boolean;
inc_presenter_li?: boolean;
limit?: number;
offset?: number;
order_by_li?: Record<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[];
@@ -225,6 +245,9 @@ export async function load_ae_obj_li__event({
log_lvl?: number;
}): Promise<ae_Event[]> {
// Hierarchy Enforcement: Pulling presentations/presenters requires pulling sessions first
if (inc_presenter_li || inc_presentation_li) inc_session_li = true;
// Check if offline
if (typeof navigator !== 'undefined' && !navigator.onLine) {
if (log_lvl) console.log('Browser is offline. Skipping API and attempting cache load.');
@@ -324,6 +347,9 @@ export async function load_ae_obj_li__event({
api_cfg,
for_obj_type: 'event',
for_obj_id: current_event_id,
inc_presentation_li,
inc_presenter_li,
try_cache,
log_lvl
}).then((res) => (event_obj.event_session_obj_li = res));
});
@@ -860,8 +886,12 @@ async function _process_generic_props<T extends Record<string, any>>({
}
}
const randomIdKey = `${obj_type}_id_random`;
const baseIdKey = `${obj_type}_id`;
if (processed_obj[randomIdKey]) {
(processed_obj as any).id = processed_obj[randomIdKey];
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
} else if (processed_obj[baseIdKey]) {
(processed_obj as any).id = processed_obj[baseIdKey];
}
const group = processed_obj.group ?? '0';
@@ -900,7 +930,9 @@ export async function process_ae_obj__event_props({
obj.code = obj.event_code;
}
// Ensure ID consistency for components relying on specific ID fields
if (obj.id && !obj.event_id) {
if (obj.event_id_random) {
obj.event_id = obj.event_id_random;
} else if (obj.id && !obj.event_id) {
obj.event_id = obj.id;
}
return obj;

View File

@@ -6,6 +6,7 @@ import { db_events } from '$lib/ae_events/db_events';
import type { ae_EventLocation } from '$lib/types/ae_types';
import { load_ae_obj_li__event_file } from '$lib/ae_events/ae_events__event_file';
import { load_ae_obj_li__event_session } from '$lib/ae_events/ae_events__event_session';
import { load_ae_obj_li__event_device } from '$lib/ae_events/ae_events__event_device';
const ae_promises: key_val = {};
@@ -16,6 +17,9 @@ export async function load_ae_obj_id__event_location({
view = 'default',
inc_file_li = false,
inc_session_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_device_li = false,
inc_all_file_li = false,
try_cache = true,
log_lvl = 0
@@ -25,6 +29,9 @@ export async function load_ae_obj_id__event_location({
view?: string;
inc_file_li?: boolean;
inc_session_li?: boolean;
inc_presentation_li?: boolean;
inc_presenter_li?: boolean;
inc_device_li?: boolean;
inc_all_file_li?: boolean;
try_cache?: boolean;
log_lvl?: number;
@@ -38,17 +45,28 @@ export async function load_ae_obj_id__event_location({
try {
const cached = await db_events.location.get(event_location_id);
if (cached) {
_refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 });
return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl });
_refresh_location_id_background({
api_cfg, event_location_id, view, try_cache,
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl: 0
});
return await _handle_nested_loads(cached, {
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl
});
}
} catch (e) {}
}
// 2. SLOW PATH: Wait for API
return await _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl });
return await _refresh_location_id_background({
api_cfg, event_location_id, view, try_cache,
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl
});
}
async function _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }: any) {
async function _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, log_lvl }: any) {
if (typeof navigator !== 'undefined' && !navigator.onLine) return null;
try {
const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_location', obj_id: event_location_id, view, log_lvl });
@@ -58,7 +76,10 @@ async function _refresh_location_id_background({ api_cfg, event_location_id, vie
if (try_cache) {
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: [processed_obj], properties_to_save, log_lvl });
}
return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl });
return await _handle_nested_loads(processed_obj, {
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl
});
}
} catch (e) {}
return null;
@@ -71,6 +92,9 @@ export async function load_ae_obj_li__event_location({
for_obj_id,
inc_file_li = false,
inc_session_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_device_li = false,
inc_all_file_li = false,
enabled = 'enabled',
hidden = 'not_hidden',
@@ -91,6 +115,9 @@ export async function load_ae_obj_li__event_location({
for_obj_id: string;
inc_file_li?: boolean;
inc_session_li?: boolean;
inc_presentation_li?: boolean;
inc_presenter_li?: boolean;
inc_device_li?: boolean;
inc_all_file_li?: boolean;
enabled?: 'enabled' | 'all' | 'not_enabled';
hidden?: 'hidden' | 'all' | 'not_hidden';
@@ -110,9 +137,17 @@ export async function load_ae_obj_li__event_location({
try {
const cached_li = await db_events.location.where('event_id').equals(for_obj_id).toArray();
if (cached_li && cached_li.length > 0) {
_refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 });
_refresh_location_li_background({
api_cfg, for_obj_type, for_obj_id,
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
enabled, hidden, view, limit, offset, order_by_li, try_cache,
log_lvl: 0
});
for (const loc of cached_li) {
_handle_nested_loads(loc, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 });
_handle_nested_loads(loc, {
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl: 0
});
}
return cached_li;
}
@@ -120,10 +155,15 @@ export async function load_ae_obj_li__event_location({
}
// 2. SLOW PATH: API
return await _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl });
return await _refresh_location_li_background({
api_cfg, for_obj_type, for_obj_id,
inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
enabled, hidden, view, limit, offset, order_by_li, try_cache,
log_lvl
});
}
async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) {
if (typeof navigator !== 'undefined' && !navigator.onLine) return [];
try {
const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_location', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl });
@@ -139,7 +179,10 @@ async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_
await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: processed, properties_to_save, log_lvl });
}
for (const loc of processed) {
_handle_nested_loads(loc, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 });
_handle_nested_loads(loc, {
api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li,
log_lvl: 0
});
}
return processed;
}
@@ -150,7 +193,7 @@ async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_
/**
* Handle nested data loads for a single location object.
*/
async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }: any) {
async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, inc_session_li, inc_presentation_li, inc_presenter_li, inc_device_li, inc_all_file_li, log_lvl }: any) {
const current_location_id = location_obj.id || location_obj.event_location_id;
if (!current_location_id) return location_obj;
@@ -165,12 +208,21 @@ async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, i
if (inc_session_li) {
tasks.push(load_ae_obj_li__event_session({
api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id,
inc_file_li: inc_all_file_li, inc_all_file_li: inc_all_file_li,
inc_presentation_li: true, inc_presenter_li: true,
inc_file_li: inc_all_file_li,
inc_all_file_li: inc_all_file_li,
inc_presentation_li: inc_presentation_li,
inc_presenter_li: inc_presenter_li,
enabled: 'enabled', hidden: 'not_hidden', limit: 150, log_lvl
}).then(res => location_obj.event_session_obj_li = res));
}
if (inc_device_li) {
tasks.push(load_ae_obj_li__event_device({
api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id,
enabled: 'all', limit: 50, log_lvl
}).then(res => location_obj.event_device_li = res));
}
if (tasks.length > 0) await Promise.all(tasks);
return location_obj;
}

View File

@@ -414,7 +414,10 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
}
const randomIdKey = `${obj_type}_id_random`;
const baseIdKey = `${obj_type}_id`;
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
if (processed_obj[randomIdKey]) {
(processed_obj as any).id = processed_obj[randomIdKey];
(processed_obj as any)[baseIdKey] = processed_obj[randomIdKey];
}
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
const group = processed_obj.group ?? '0';
const priority = processed_obj.priority ? 1 : 0;
@@ -432,6 +435,7 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
export async function process_ae_obj__event_presenter_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) {
return _process_generic_props({ obj_li, obj_type: 'event_presenter', log_lvl, specific_processor: (obj) => {
// String-Only ID Vision: Ensure linking IDs are the string versions for indexing
if (obj.event_presenter_id_random) obj.event_presenter_id = obj.event_presenter_id_random;
if (obj.event_presentation_id_random) obj.event_presentation_id = obj.event_presentation_id_random;
if (obj.event_session_id_random) obj.event_session_id = obj.event_session_id_random;
if (obj.event_id_random) obj.event_id = obj.event_id_random;