refactor(core): consolidate logic and modernize imports

- Unified Person and User logic into ae_core__* counterparts and marked legacy files.
- Renamed Activity Log to ae_core__activity_log.ts for naming consistency.
- Updated all core function imports across the identity, logs, and video conference modules.
- Fixed missing 'prefix' field in Person form payload and corrected return types in Activity Log.
- Updated project TODO to reflect completed core module refinements.
This commit is contained in:
Scott Idem
2026-01-15 14:29:14 -05:00
parent 7ce9c5e093
commit 74d107f157
14 changed files with 361 additions and 23 deletions

16
TODO.md
View File

@@ -60,12 +60,16 @@ This is a list of tasks to be completed before the next event/show/conference.
## Core Module Improvements
- [ ] **Person Management:**
- [ ] Create dedicated page/form for creating/editing person records.
- [ ] Finalize Person-User linking.
- [ ] **Address & Contact Management:**
- [ ] Implement full V3 CRUD UI (currently placeholders).
- [ ] Create dynamic detail routes.
- [x] **Person Management:**
- [x] Create dedicated page/form for creating/editing person records. (Standardized 2026-01-15)
- [x] Finalize Person-User linking. (UI implemented in [person_id]/+page.svelte)
- [x] **Address & Contact Management:**
- [x] Implement full V3 CRUD UI (Standardized 2026-01-15).
- [x] Create dynamic detail routes.
- [x] **Logic Consolidation:**
- [x] Merged legacy logic files into modern `ae_core__*` counterparts.
- [x] Renamed Activity Log to `ae_core__activity_log.ts` for consistency.
- [x] Unified Person-User logic and ensured correct Triple-ID / V3 helper usage.
---

View File

@@ -101,7 +101,7 @@ export async function create_ae_obj__activity_log({
if (!account_id) {
console.log(`ERROR: Core - Activity Log - account_id required to create`);
return false;
return null;
}
ae_promises.create__activity_log = await api.create_ae_obj_v3({

View File

@@ -65,6 +65,7 @@ export async function load_ae_obj_li__person({
api_cfg,
for_obj_type = 'account',
for_obj_id,
qry_email = null,
qry_user_id = null,
enabled = 'enabled',
hidden = 'not_hidden',
@@ -84,6 +85,7 @@ export async function load_ae_obj_li__person({
api_cfg: any;
for_obj_type?: string;
for_obj_id?: string;
qry_email?: string | null;
qry_user_id?: string | null;
enabled?: 'enabled' | 'all' | 'not_enabled';
hidden?: 'hidden' | 'all' | 'not_hidden';
@@ -101,11 +103,19 @@ export async function load_ae_obj_li__person({
let promise;
if (qry_user_id) {
if (qry_user_id || qry_email) {
const search_query: any = {
and: [{ field: 'user_id_random', op: 'eq', value: qry_user_id }]
and: []
};
if (qry_user_id) {
search_query.and.push({ field: 'user_id_random', op: 'eq', value: qry_user_id });
}
if (qry_email) {
search_query.and.push({ field: 'primary_email', op: 'eq', value: qry_email });
}
if (for_obj_id) {
search_query.and.push({
field: `${for_obj_type}_id_random`,
@@ -352,7 +362,18 @@ const properties_to_save = [
'contact_id',
'contact_id_random',
'contact_name',
'contact_email'
'contact_email',
'contact_cc_email',
'contact_phone_mobile',
'contact_phone_home',
'contact_phone_office',
'contact_phone_land',
'contact_phone_fax',
'contact_phone_other',
'address_id',
'address_id_random',
'address_city',
'address_country_alpha_2_code'
];
async function _process_generic_props<T extends Record<string, any>>({

View File

@@ -253,6 +253,322 @@ export async function delete_ae_obj_id__user({
return result;
}
/*
* *** LEGACY AUTHENTICATION HEADER LOGIC ***
*
* The functions in this section interact with legacy Aether API authentication endpoints
* (e.g., /user/authenticate, /user/lookup_email).
*
* Unlike V3 endpoints which handle context automatically or via standard headers,
* these legacy endpoints have specific requirements:
*
* 1. They often require the `x-account-id` header to be explicitly set to the target
* account ID to find the user within that specific account context.
* 2. The standard API wrapper logic might strip `x-account-id` if `x-no-account-id`
* is present (Bootstrap Paradox logic). We must explicitly remove `x-no-account-id`
* and set `x-account-id` to ensure the request is routed correctly.
* 3. Some endpoints accept `account_id` as a query parameter, while others (like email sending)
* may crash (500 Error) if unexpected parameters are passed.
*/
// Updated 2025-04-04
// This function handles username/password authentication.
// It explicitly sets the x-account-id header to ensure the user is looked up in the correct account.
export async function auth_ae_obj__username_password({
api_cfg,
account_id,
null_account_id = false,
username,
password,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
account_id: string;
null_account_id?: boolean;
username: string;
password: string;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(
`*** auth_ae_obj__username_password() *** account_id=${account_id} username=${username} password=${password}`
);
}
const endpoint = '/user/authenticate';
// Prepare API config with correct headers to override global guest settings
const use_api_cfg = { ...api_cfg, headers: { ...api_cfg.headers } };
if (account_id) {
use_api_cfg.headers['x-account-id'] = account_id;
delete use_api_cfg.headers['x-no-account-id'];
params['account_id'] = account_id;
}
if (null_account_id) {
params['null_account_id'] = true;
}
params['username'] = username; // Required
params['password'] = password; // Required
params['inc_jwt'] = true; // Request a JWT in the response
if (log_lvl > 1) {
console.log(`auth_ae_obj__username_password() - params:`, params);
}
ae_promises.auth__username_password = await api
.get_object({
api_cfg: use_api_cfg,
endpoint: endpoint,
params: params,
// data: {},
log_lvl: log_lvl
})
.then(async function (user_obj_get_result) {
if (user_obj_get_result) {
return user_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.auth__username_password:', ae_promises.auth__username_password);
}
return ae_promises.auth__username_password;
}
// Updated 2025-04-04
// This function handles authentication using a User ID and a one-time auth key.
export async function auth_ae_obj__user_id_user_auth_key({
api_cfg,
account_id,
user_id,
user_auth_key,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
account_id: string;
user_id: string;
user_auth_key: string;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(
`*** auth_ae_obj__user_id_user_auth_key() *** account_id=${account_id} user_id=${user_id}`
);
}
const endpoint = '/user/authenticate';
// Prepare API config with correct headers to override global guest settings
const use_api_cfg = { ...api_cfg, headers: { ...api_cfg.headers } };
if (account_id) {
use_api_cfg.headers['x-account-id'] = account_id;
delete use_api_cfg.headers['x-no-account-id'];
params['account_id'] = account_id;
}
params['user_id'] = user_id; // Required
params['auth_key'] = user_auth_key; // Required
params['inc_jwt'] = true; // Request a JWT in the response
if (log_lvl > 1) {
console.log(`auth_ae_obj__user_id_user_auth_key() - params:`, params);
}
ae_promises.auth__user_id_user_key = await api
.get_object({
api_cfg: use_api_cfg,
endpoint: endpoint,
params: params,
log_lvl: log_lvl
})
.then(async function (user_obj_get_result) {
if (user_obj_get_result) {
return user_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.auth__user_id_user_key:', ae_promises.auth__user_id_user_key);
}
return ae_promises.auth__user_id_user_key;
}
// Send an email to the user with a new one time use authentication key.
// Updated 2025-04-08
// NOTE: This legacy endpoint is sensitive to extra query parameters and will 500 if account_id is passed in the URL.
export async function send_email_auth_ae_obj__user_id({
api_cfg,
account_id,
user_id,
base_url,
key_param_name = 'user_key', // API defaults to 'auth_key'
params = {},
log_lvl = 0
}: {
api_cfg: any;
account_id: string;
user_id: string;
base_url?: string;
key_param_name?: string;
params?: key_val;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(
`*** send_email_auth_ae_obj__user_id() *** account_id=${account_id} user_id=${user_id}`
);
}
const email_auth_key_endpoint = `/user/${user_id}/email_auth_key_url`;
params = {
root_url: base_url,
key_param_name: key_param_name
};
// Prepare API config with correct headers
const use_api_cfg = { ...api_cfg, headers: { ...api_cfg.headers } };
if (account_id) {
use_api_cfg.headers['x-account-id'] = account_id;
delete use_api_cfg.headers['x-no-account-id'];
// WARNING: Do NOT add account_id to params here, as it causes a 500 error on the legacy backend.
}
ae_promises.auth_key__send_email = await api.get_object({
api_cfg: use_api_cfg,
endpoint: email_auth_key_endpoint,
params: params,
log_lvl: log_lvl
});
return ae_promises.auth_key__send_email;
}
// Look up user based on email address provided
// Updated 2025-04-08
export async function qry_ae_obj_li__user_email({
api_cfg,
account_id,
null_account_id = false,
email,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any;
account_id: string;
null_account_id?: boolean;
email: string;
params?: key_val;
try_cache?: boolean;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(`*** qry_ae_obj_li__user_email() *** account_id=${account_id} email=${email}`);
}
const endpoint = '/user/lookup_email';
// Prepare API config with correct headers
const use_api_cfg = { ...api_cfg, headers: { ...api_cfg.headers } };
if (account_id) {
use_api_cfg.headers['x-account-id'] = account_id;
delete use_api_cfg.headers['x-no-account-id'];
params['account_id'] = account_id;
}
params['email'] = email; // Required
params['null_account_id'] = null_account_id || false;
ae_promises.qry__user_email = await api
.get_object({
api_cfg: use_api_cfg,
endpoint: endpoint,
params: params,
log_lvl: log_lvl
})
.then(async function (user_obj_get_result) {
if (user_obj_get_result) {
return user_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
});
return ae_promises.qry__user_email;
}
// Change user password
// Updated 2025-04-11
export async function auth_ae_obj__user_id_change_password({
api_cfg,
account_id,
user_id,
password,
params = {},
log_lvl = 0
}: {
api_cfg: any;
account_id: string;
user_id: string;
password: string;
params?: key_val;
log_lvl?: number;
}) {
if (log_lvl) {
console.log(
`*** auth_ae_obj__user_id_change_password() *** account_id=${account_id} user_id=${user_id}`
);
}
const endpoint = `/user/${user_id}/change_password`;
params['user_id'] = user_id; // Required
ae_promises.change_password__user_id = await api
.patch_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
data: { password: password },
log_lvl: log_lvl
})
.then(async function (change_password_result) {
if (change_password_result) {
return change_password_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error: any) {
console.log('No results returned or failed.', error);
});
return ae_promises.change_password__user_id;
}
const properties_to_save = [
'id',
'user_id',

View File

@@ -7,8 +7,7 @@ import {
load_ae_obj_li__activity_log,
create_ae_obj__activity_log,
update_ae_obj__activity_log
// db_save_ae_obj_li__activity_log
} from '$lib/ae_core/core__activity_log';
} from '$lib/ae_core/ae_core__activity_log';
import {
load_ae_obj_id__person,
@@ -16,7 +15,6 @@ import {
create_ae_obj__person,
delete_ae_obj_id__person,
update_ae_obj__person
// db_save_ae_obj_li__person
} from '$lib/ae_core/ae_core__person';
import {
@@ -25,12 +23,7 @@ import {
send_email_auth_ae_obj__user_id,
qry_ae_obj_li__user_email,
auth_ae_obj__user_id_change_password
// handle_load_ae_obj_id__user,
// handle_load_ae_obj_li__user,
// handle_create_ae_obj__user,
// handle_update_ae_obj__user,
// handle_db_save_ae_obj_li__user
} from '$lib/ae_core/core__user';
} from '$lib/ae_core/ae_core__user';
import { generate_qr_code, js_generate_qr_code } from '$lib/ae_core/core__qr_code';

View File

@@ -189,7 +189,7 @@ import { load_ae_obj_id__journal } from '$lib/ae_journals/ae_journals__journal';
import { load_ae_obj_id__journal_entry } from '$lib/ae_journals/ae_journals__journal_entry';
import { load_ae_obj_id__post } from '$lib/ae_posts/ae_posts__post';
import { load_ae_obj_id__post_comment } from '$lib/ae_posts/ae_posts__post_comment';
import { load_ae_obj_id__person } from '$lib/ae_core/core__person';
import { load_ae_obj_id__person } from '$lib/ae_core/ae_core__person';
export async function update_ae_obj_id_crud_v2({
api_cfg,

View File

@@ -1,7 +1,7 @@
<script lang="ts">
/** @type {import('./$types').PageData} */
import { onMount } from 'svelte';
import { qry__activity_log } from '$lib/ae_core/core__activity_log';
import { qry__activity_log } from '$lib/ae_core/ae_core__activity_log';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { Search, History, Calendar, User, Tag, Activity } from 'lucide-svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';

View File

@@ -33,7 +33,7 @@
import { update_ae_obj__person } from '$lib/ae_core/ae_core__person';
import { qry_ae_obj_li__event } from '$lib/ae_events/ae_events__event';
import { qry__post } from '$lib/ae_posts/ae_posts__post';
import { qry__activity_log } from '$lib/ae_core/core__activity_log';
import { qry__activity_log } from '$lib/ae_core/ae_core__activity_log';
import { Users, Link, Unlink, UserPlus, ShieldCheck, User, Calendar, MessageSquare, History, Activity, Edit, Eye } from 'lucide-svelte';
interface Props {

View File

@@ -46,6 +46,7 @@
// Clean payload: Map fields and handle optional values
const payload: any = {
prefix: formData.prefix.trim() || null,
given_name: formData.given_name.trim(),
family_name: formData.family_name.trim() || null,
middle_name: formData.middle_name.trim() || null,

View File

@@ -3,7 +3,10 @@
import { page } from '$app/stores';
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
import { create_ae_obj__activity_log, update_ae_obj__activity_log } from '$lib/ae_core/core__activity_log';
import {
create_ae_obj__activity_log,
update_ae_obj__activity_log
} from "$lib/ae_core/ae_core__activity_log";
let log_lvl: number = $state(0);