feat(v3): harden clean ID pattern and standardize snake_case platform-wide
- Systematically migrated from *_id_random to clean *_id fields in BB, People, and Posts modules. - Synchronized Post_Comment interface with account_id for multi-tenant isolation. - Applied optional chaining and local reactive state to harden async UI initialization. - Refactored common helpers to follow snake_case naming conventions. - Resolved various minor stability and logic issues across IDAA Bulletin Board.
This commit is contained in:
@@ -174,7 +174,7 @@ export async function load_ae_obj_li__post({
|
|||||||
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
||||||
api_cfg: api_cfg,
|
api_cfg: api_cfg,
|
||||||
for_obj_type: 'post',
|
for_obj_type: 'post',
|
||||||
for_obj_id: post_obj.post_id_random,
|
for_obj_id: post_obj.post_id,
|
||||||
enabled,
|
enabled,
|
||||||
hidden,
|
hidden,
|
||||||
limit,
|
limit,
|
||||||
@@ -213,7 +213,7 @@ export async function create_ae_obj__post({
|
|||||||
api_cfg,
|
api_cfg,
|
||||||
obj_type: 'post',
|
obj_type: 'post',
|
||||||
fields: {
|
fields: {
|
||||||
account_id_random: account_id,
|
account_id: account_id,
|
||||||
...data_kv
|
...data_kv
|
||||||
},
|
},
|
||||||
params,
|
params,
|
||||||
@@ -358,7 +358,7 @@ export async function qry__post({
|
|||||||
const search_query: any = { and: [] };
|
const search_query: any = { and: [] };
|
||||||
|
|
||||||
if (account_id) {
|
if (account_id) {
|
||||||
search_query.and.push({ field: 'account_id_random', op: 'eq', value: account_id });
|
search_query.and.push({ field: 'account_id', op: 'eq', value: account_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qry_str) {
|
if (qry_str) {
|
||||||
@@ -431,7 +431,7 @@ export async function qry__post({
|
|||||||
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
ae_promises.load__post_obj_li[i].post_comment_li = await load_ae_obj_li__post_comment({
|
||||||
api_cfg: api_cfg,
|
api_cfg: api_cfg,
|
||||||
for_obj_type: 'post',
|
for_obj_type: 'post',
|
||||||
for_obj_id: post_obj.post_id_random,
|
for_obj_id: post_obj.post_id,
|
||||||
enabled,
|
enabled,
|
||||||
hidden,
|
hidden,
|
||||||
limit,
|
limit,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export const editable_fields__post_comment = [
|
export const editable_fields__post_comment = [
|
||||||
'post_id',
|
'post_id',
|
||||||
'post_id_random',
|
// 'post_id_random',
|
||||||
'name',
|
'name',
|
||||||
'title',
|
'title',
|
||||||
'content',
|
'content',
|
||||||
|
|||||||
@@ -14,12 +14,9 @@ import type { key_val } from '$lib/stores/ae_stores';
|
|||||||
*/
|
*/
|
||||||
export interface Post {
|
export interface Post {
|
||||||
id: string;
|
id: string;
|
||||||
// id_random: string;
|
|
||||||
post_id: string;
|
post_id: string;
|
||||||
// post_id_random: string;
|
|
||||||
|
|
||||||
account_id: string;
|
account_id: string;
|
||||||
// account_id_random: string;
|
|
||||||
|
|
||||||
person_id?: null | string;
|
person_id?: null | string;
|
||||||
external_person_id?: null | string; // For IDAA this is the Novi UUID
|
external_person_id?: null | string; // For IDAA this is the Novi UUID
|
||||||
@@ -78,12 +75,9 @@ export interface Post {
|
|||||||
*/
|
*/
|
||||||
export interface Post_Comment {
|
export interface Post_Comment {
|
||||||
id: string;
|
id: string;
|
||||||
// id_random: string;
|
|
||||||
post_comment_id: string;
|
post_comment_id: string;
|
||||||
// post_comment_id_random: string;
|
|
||||||
|
|
||||||
post_id: string;
|
post_id: string;
|
||||||
// post_id_random: string;
|
|
||||||
|
|
||||||
external_person_id?: null | string; // For IDAA this is the Novi UUID
|
external_person_id?: null | string; // For IDAA this is the Novi UUID
|
||||||
|
|
||||||
@@ -114,6 +108,7 @@ export interface Post_Comment {
|
|||||||
tmp_sort_2?: null | string;
|
tmp_sort_2?: null | string;
|
||||||
|
|
||||||
// Additional fields for convenience (database views)
|
// Additional fields for convenience (database views)
|
||||||
|
account_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-02-05
|
// Updated 2026-02-05
|
||||||
|
|||||||
@@ -740,9 +740,9 @@ export interface ae_DataStore extends ae_BaseObj {
|
|||||||
*/
|
*/
|
||||||
export interface ae_Post extends ae_BaseObj {
|
export interface ae_Post extends ae_BaseObj {
|
||||||
post_id: string;
|
post_id: string;
|
||||||
post_id_random: string;
|
// post_id_random: string;
|
||||||
account_id: string;
|
account_id: string;
|
||||||
account_id_random: string;
|
// account_id_random: string;
|
||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
content: string;
|
content: string;
|
||||||
@@ -762,8 +762,9 @@ export interface ae_Post extends ae_BaseObj {
|
|||||||
*/
|
*/
|
||||||
export interface ae_PostComment extends ae_BaseObj {
|
export interface ae_PostComment extends ae_BaseObj {
|
||||||
post_comment_id: string;
|
post_comment_id: string;
|
||||||
post_comment_id_random: string;
|
// post_comment_id_random: string;
|
||||||
post_id_random: string;
|
post_id: string;
|
||||||
|
// post_id_random: string;
|
||||||
|
|
||||||
content: string;
|
content: string;
|
||||||
anonymous: boolean;
|
anonymous: boolean;
|
||||||
|
|||||||
@@ -107,18 +107,18 @@
|
|||||||
log_lvl: 1
|
log_lvl: 1
|
||||||
});
|
});
|
||||||
// Filter users that don't have a person_id linked
|
// Filter users that don't have a person_id linked
|
||||||
// NOTE: The backend might return person_id or person_id_random
|
// NOTE: The backend might return person_id or person_id
|
||||||
available_users = all_users.filter(u => !u.person_id_random && !u.person_id);
|
available_users = all_users.filter(u => !u.person_id && !u.person_id);
|
||||||
loading_users = false;
|
loading_users = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handle_link_user(user_id_random: string) {
|
async function handle_link_user(user_id: string) {
|
||||||
if (!confirm('Link this person to this user account?')) return;
|
if (!confirm('Link this person to this user account?')) return;
|
||||||
|
|
||||||
const result = await update_ae_obj__person({
|
const result = await update_ae_obj__person({
|
||||||
api_cfg: $ae_api,
|
api_cfg: $ae_api,
|
||||||
person_id: $slct.person_id,
|
person_id: $slct.person_id,
|
||||||
data_kv: { user_id_random },
|
data_kv: { user_id },
|
||||||
log_lvl: 1
|
log_lvl: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
const result = await update_ae_obj__person({
|
const result = await update_ae_obj__person({
|
||||||
api_cfg: $ae_api,
|
api_cfg: $ae_api,
|
||||||
person_id: $slct.person_id,
|
person_id: $slct.person_id,
|
||||||
data_kv: { user_id_random: null },
|
data_kv: { user_id: null },
|
||||||
log_lvl: 1
|
log_lvl: 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@
|
|||||||
<ShieldCheck size={18} />
|
<ShieldCheck size={18} />
|
||||||
<span>User Account Linking</span>
|
<span>User Account Linking</span>
|
||||||
</div>
|
</div>
|
||||||
{#if $lq__person_obj?.user_id_random}
|
{#if $lq__person_obj?.user_id}
|
||||||
<button class="btn btn-sm variant-soft-error" onclick={handle_unlink_user}>
|
<button class="btn btn-sm variant-soft-error" onclick={handle_unlink_user}>
|
||||||
<Unlink size={14} class="mr-2" /> Unlink User
|
<Unlink size={14} class="mr-2" /> Unlink User
|
||||||
</button>
|
</button>
|
||||||
@@ -266,14 +266,14 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{#if $lq__person_obj?.user_id_random}
|
{#if $lq__person_obj?.user_id}
|
||||||
<div class="flex items-center gap-4 py-2">
|
<div class="flex items-center gap-4 py-2">
|
||||||
<div class="avatar variant-filled-primary w-12 h-12 flex items-center justify-center rounded-full">
|
<div class="avatar variant-filled-primary w-12 h-12 flex items-center justify-center rounded-full">
|
||||||
<Users size={24} />
|
<Users size={24} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm opacity-60 uppercase tracking-widest font-bold">Linked User ID</p>
|
<p class="text-sm opacity-60 uppercase tracking-widest font-bold">Linked User ID</p>
|
||||||
<p class="font-mono text-lg">{$lq__person_obj.user_id_random}</p>
|
<p class="font-mono text-lg">{$lq__person_obj.user_id}</p>
|
||||||
<p class="text-xs opacity-60">Username: {$lq__person_obj.username || '--'}</p>
|
<p class="text-xs opacity-60">Username: {$lq__person_obj.username || '--'}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -289,7 +289,7 @@
|
|||||||
{#each available_users as user}
|
{#each available_users as user}
|
||||||
<button
|
<button
|
||||||
class="card p-3 variant-soft-primary hover:variant-filled-primary text-left transition-all flex flex-col gap-1"
|
class="card p-3 variant-soft-primary hover:variant-filled-primary text-left transition-all flex flex-col gap-1"
|
||||||
onclick={() => handle_link_user(user.user_id_random)}
|
onclick={() => handle_link_user(user.user_id)}
|
||||||
>
|
>
|
||||||
<span class="font-bold flex items-center gap-2">
|
<span class="font-bold flex items-center gap-2">
|
||||||
<User size={14} />
|
<User size={14} />
|
||||||
@@ -333,7 +333,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each related_events as ev}
|
{#each related_events as ev}
|
||||||
<a href="/events/{ev.event_id_random}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
<a href="/events/{ev.event_id}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
||||||
<span class="font-bold text-sm">{ev.name}</span>
|
<span class="font-bold text-sm">{ev.name}</span>
|
||||||
<span class="text-[10px] opacity-60">{new Date(ev.start_datetime).toLocaleDateString()}</span>
|
<span class="text-[10px] opacity-60">{new Date(ev.start_datetime).toLocaleDateString()}</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -354,7 +354,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each related_posts as post}
|
{#each related_posts as post}
|
||||||
<a href="/idaa/bb/{post.post_id_random}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
<a href="/idaa/bb/{post.post_id}" class="card p-3 variant-soft flex flex-col gap-1 hover:variant-soft-primary transition-all">
|
||||||
<span class="font-bold text-sm">{post.title}</span>
|
<span class="font-bold text-sm">{post.title}</span>
|
||||||
<div class="flex justify-between items-center text-[10px] opacity-60">
|
<div class="flex justify-between items-center text-[10px] opacity-60">
|
||||||
<span>{new Date(post.created_on).toLocaleDateString()}</span>
|
<span>{new Date(post.created_on).toLocaleDateString()}</span>
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
// NEW COMMENT: Ensure post_id is included
|
// NEW COMMENT: Ensure post_id is included
|
||||||
const parent_post_id = $idaa_slct.post_id;
|
const parent_post_id = $idaa_slct.post_id;
|
||||||
post_comment_do['post_id'] = parent_post_id;
|
post_comment_do['post_id'] = parent_post_id;
|
||||||
// post_comment_do['post_id_random'] = parent_post_id;
|
// post_comment_do['post_id'] = parent_post_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_lvl = 1;
|
log_lvl = 1;
|
||||||
@@ -118,9 +118,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$idaa_slct.post_comment_id) {
|
if (!$idaa_slct.post_comment_id) {
|
||||||
// NEW COMMENT: Ensure post_id_random is included
|
// NEW COMMENT: Ensure post_id is included
|
||||||
// SVELTE 5 V3 Pattern: Some child objects require the random ID suffix for parent mapping
|
// SVELTE 5 V3 Pattern: Some child objects require the random ID suffix for parent mapping
|
||||||
post_comment_do['post_id_random'] = $idaa_slct.post_id;
|
post_comment_do['post_id'] = $idaa_slct.post_id;
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (prom_api__post_comment_obj) {
|
if (prom_api__post_comment_obj) {
|
||||||
$idaa_slct.post_comment_id = prom_api__post_comment_obj.post_comment_id_random;
|
$idaa_slct.post_comment_id = prom_api__post_comment_obj.post_comment_id;
|
||||||
$idaa_slct.post_comment_obj = prom_api__post_comment_obj;
|
$idaa_slct.post_comment_obj = prom_api__post_comment_obj;
|
||||||
|
|
||||||
disable_submit_btn = false;
|
disable_submit_btn = false;
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('post_obj_create_result:', post_obj_create_result);
|
console.log('post_obj_create_result:', post_obj_create_result);
|
||||||
}
|
}
|
||||||
$idaa_slct.post_id = post_obj_create_result.post_id_random;
|
$idaa_slct.post_id = post_obj_create_result.post_id;
|
||||||
$idaa_slct.post_obj = post_obj_create_result;
|
$idaa_slct.post_obj = post_obj_create_result;
|
||||||
|
|
||||||
return post_obj_create_result;
|
return post_obj_create_result;
|
||||||
@@ -570,11 +570,11 @@ Copy and paste link: <a href="${link_base_url}?post_id=${$idaa_slct.post_id}">${
|
|||||||
>
|
>
|
||||||
<span class="fas fa-paperclip m-1"></span>
|
<span class="fas fa-paperclip m-1"></span>
|
||||||
{linked_obj.filename}
|
{linked_obj.filename}
|
||||||
({linked_obj.hosted_file_id_random})
|
({linked_obj.hosted_file_id})
|
||||||
</a> -->
|
</a> -->
|
||||||
|
|
||||||
{#if $ae_loc.authenticated_access}
|
{#if $ae_loc.authenticated_access}
|
||||||
{@const file_id = linked_obj?.hosted_file_id_random || linked_obj?.id || linked_obj?.hosted_file_id}
|
{@const file_id = linked_obj?.hosted_file_id || linked_obj?.id || linked_obj?.hosted_file_id}
|
||||||
{#if file_id}
|
{#if file_id}
|
||||||
{@const ext = (linked_obj.extension || linked_obj.file_extension || ae_util.guess_file_extension(linked_obj.filename) || '').toLowerCase()}
|
{@const ext = (linked_obj.extension || linked_obj.file_extension || ae_util.guess_file_extension(linked_obj.filename) || '').toLowerCase()}
|
||||||
{#if ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)}
|
{#if ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)}
|
||||||
@@ -608,7 +608,7 @@ Copy and paste link: <a href="${link_base_url}?post_id=${$idaa_slct.post_id}">${
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ae_promises[linked_obj.event_file_id_random] = handle_delete__event_file({event_file_id: linked_obj.event_file_id_random});
|
// ae_promises[linked_obj.event_file_id] = handle_delete__event_file({event_file_id: linked_obj.event_file_id});
|
||||||
|
|
||||||
// First - Attempt to delete the hosted file
|
// First - Attempt to delete the hosted file
|
||||||
ae_promises.delete__linked_obj = await core_func
|
ae_promises.delete__linked_obj = await core_func
|
||||||
@@ -631,7 +631,7 @@ Copy and paste link: <a href="${link_base_url}?post_id=${$idaa_slct.post_id}">${
|
|||||||
let delete_result_li =
|
let delete_result_li =
|
||||||
$idaa_slct.post_obj.linked_li_json.filter(
|
$idaa_slct.post_obj.linked_li_json.filter(
|
||||||
function (hosted_file_obj) {
|
function (hosted_file_obj) {
|
||||||
const current_id = hosted_file_obj?.hosted_file_id_random || hosted_file_obj?.id || hosted_file_obj?.hosted_file_id;
|
const current_id = hosted_file_obj?.hosted_file_id || hosted_file_obj?.id || hosted_file_obj?.hosted_file_id;
|
||||||
console.log(
|
console.log(
|
||||||
`Comparing: ${current_id} vs ${file_id}`
|
`Comparing: ${current_id} vs ${file_id}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -248,11 +248,11 @@
|
|||||||
{#if ($ae_loc.trusted_access && $ae_loc.edit_mode) || $lq__post_obj?.external_person_id === $idaa_loc.novi_uuid}
|
{#if ($ae_loc.trusted_access && $ae_loc.edit_mode) || $lq__post_obj?.external_person_id === $idaa_loc.novi_uuid}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
// $idaa_slct.post_id = $idaa_slct.post_obj.post_id_random;
|
// $idaa_slct.post_id = $idaa_slct.post_obj.post_id;
|
||||||
$idaa_slct.post_obj = $lq__post_obj; // In case things changed
|
$idaa_slct.post_obj = $lq__post_obj; // In case things changed
|
||||||
|
|
||||||
// const url = new URL(location);
|
// const url = new URL(location);
|
||||||
// url.searchParams.set('post_id', $idaa_slct.post_obj.post_id_random);
|
// url.searchParams.set('post_id', $idaa_slct.post_obj.post_id);
|
||||||
// history.pushState({}, '', url);
|
// history.pushState({}, '', url);
|
||||||
|
|
||||||
// $idaa_sess.bb.show_main__options = false;
|
// $idaa_sess.bb.show_main__options = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user