Files
OSIT-AE-App-Svelte/documentation/PROJECT__AE_Events_PressMgmt_Config_Cleanup.md
Scott Idem 8eb9444edf fix(pres_mgmt): sync remote config on all deep-link entry pages
Root cause of the presenter QR not propagating to other browsers/incognito:
sync_config__event_pres_mgmt() was only called from pres_mgmt/+page.svelte
and session/[session_id]/+page.svelte. A browser landing directly on the
presenter page (e.g. via a presenter's sign-in link) never synced remote
config into pres_mgmt_loc.current at all — every always-synced and
lock-synced field (QR enables, POC visibility, code visibility, labels,
etc.) silently stayed at hardcoded local defaults regardless of what was
set on the Config page, since that page was never visited in that browser.

Added the same sync $effect (mirroring the existing pattern/comment already
in session/[session_id]/+page.svelte) to:
- presenter/[presenter_id]/+page.svelte
- locations/+page.svelte
- location/[event_location_id]/+page.svelte
- reports/+page.svelte

Logged in PROJECT__AE_Events_PressMgmt_Config_Cleanup.md with a note that
any future pres_mgmt entry page needs the same block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 12:29:43 -04:00

14 KiB

Project: Pres Mgmt Config Cleanup & Config UI

Status: 🟡 ~70% Complete — Core Working, Cleanup Pass Needed Priority: Medium (core features functional; remaining work is deprecation + consistency) Created: 2026-04-02 Last Updated: 2026-06-12 (regression audit) Related: TODO__Agents.md, PROJECT__Stores_Svelte5_Migration.md


Background

The event.mod_pres_mgmt_json config grew organically across several conferences (LCI, BGH, etc.) and has accumulated serious inconsistencies:

  • Mixed show__ and hide__ prefixes for the same concepts
  • Some features have BOTH show__foo and hide__foo keys active simultaneously
  • Duplicate keys with different names (file_purpose_option_kv = file_purpose_option_li)
  • Dead config (HOLD__* prefix)
  • Type inconsistency (label__person_external_id: false vs "LCI member ID" string)
  • Keys in the DB not consumed by sync_config__event_pres_mgmt()
  • Bug: label__session_poc_name_short is read then immediately overwritten (line 970-972 in ae_events__event.ts)
  • hide_launcher_link / hide_launcher_link_legacy missing the __ separator (inconsistent)
  • show_content__presentation_description uses a third naming convention
  • Admin must edit DB records directly to change config — error-prone

The local config (events_loc.pres_mgmt) is also tangled into the main events_loc persisted store which is part of the paused Svelte 5 migration.


Goals

  1. Canonical config schema — define a TypeScript interface for mod_pres_mgmt_json
  2. Consistent naming convention — one rule for all show__/hide__ keys
  3. New Svelte 5 store — break out local pres_mgmt config from events_loc
  4. Config UI — admin page within pres_mgmt to manage the remote config
  5. No more direct DB edits for routine pres_mgmt configuration

Convention Decision

Rule: the prefix reflects the default state.

Prefix Default Use for
hide__ false = visible Features ON by default that can be turned off
show__ false = hidden Features OFF by default that can be turned on

Never have both show__foo and hide__foo for the same concept.

  • Visibility controls (codes, descriptions, POC, biography) → default visible → hide__
  • Opt-in features (access links, launcher, QR links) → default hidden → show__

Canonical Remote Config Schema

PressMgmtRemoteCfg — the authoritative TypeScript interface for event.mod_pres_mgmt_json:

interface PressMgmtRemoteCfg {
    // System
    lock_config: boolean;               // true = force remote→local sync (prevent user overrides)

    // Labels (event-specific terminology overrides)
    label__person_external_id: string | null;      // default: 'External ID'
    label__presenter_external_id: string | null;   // default: 'External ID'
    label__session_poc_type: string | null;        // e.g. 'champion', 'poc'
    label__session_poc_name: string | null;        // e.g. 'Champion', 'Point of Contact'

    // Codes (visible by default — hide to suppress)
    hide__location_code: boolean;
    hide__presentation_code: boolean;
    hide__presenter_code: boolean;
    hide__session_code: boolean;

    // Session fields (visible by default)
    hide__session_description: boolean;
    hide__session_location: boolean;
    hide__session_msg: boolean;
    hide__session_poc: boolean;
    hide__session_poc_biography: boolean;
    hide__session_poc_profile_pic: boolean;

    // Presenter fields
    hide__presenter_biography: boolean;

    // Presentation fields
    hide__presentation_datetime: boolean;
    hide__presentation_description: boolean;    // replaces show_content__presentation_description

    // Opt-in features (hidden by default — show to enable)
    show__copy_access_link: boolean;
    show__email_access_link: boolean;
    show__launcher_link: boolean;
    show__launcher_link_legacy: boolean;
    show__session_li_poc_field: boolean;   // POC column in session list/table; hide__session_poc still wins

    // Requirements
    require__presenter_agree: boolean;
    require__session_agree: boolean;

    // Navigation/UI constraints
    limit__navigation: boolean;
    limit__options: boolean;

    // File upload config
    file_purpose_option_kv: Record<string, {
        name: string;
        disabled?: boolean;
        hidden?: boolean;
    }> | null;

    // Report visibility (key = report slug, value = true to hide)
    hide__report_kv: Record<string, boolean>;
}

Keys Removed vs. Current DB Records

Removed Key Reason
file_purpose_option_li Duplicate of file_purpose_option_kv
HOLD__file_os_selection_option Dead/held feature
hide__copy_access_link Conflicts with show__copy_access_link — use show__
hide__email_access_link Conflicts with show__email_access_link — use show__
hide__launcher_link Conflicts with show__launcher_link — use show__
hide__launcher_link_legacy Conflicts with show__launcher_link_legacy — use show__
hide__report_li Superseded by hide__report_kv
show__navigation Ambiguous — covered by limit__navigation
label__session_poc_name_short Was a bug — never applied (overwritten immediately)
show_content__presentation_description Renamed to hide__presentation_description

New Svelte 5 Local Store

Do NOT touch events_loc or the paused Svelte 5 migration. Instead, create a standalone store for pres_mgmt local config.

File: src/lib/stores/ae_events_stores__pres_mgmt.svelte.ts

import { PersistedState } from 'runed';
import { pres_mgmt_loc_defaults } from './ae_events_stores__pres_mgmt_defaults';

export const pres_mgmt_loc = new PersistedState('ae_pres_mgmt_loc', pres_mgmt_loc_defaults);
// Usage: pres_mgmt_loc.current.hide__session_code
  • New localStorage key: ae_pres_mgmt_loc (separate from ae_events_loc)
  • Version gate: add AE_PRES_MGMT_LOC_VERSION to store_versions.ts
  • sync_config__event_pres_mgmt() writes to pres_mgmt_loc.current directly

Consumer syntax change:

BEFORE: $events_loc.pres_mgmt.hide__session_code
AFTER:  pres_mgmt_loc.current.hide__session_code

Config UI Page

Route: /events/[event_id]/(pres_mgmt)/pres_mgmt/config/ Access: $ae_loc.manager_access only Button visibility: Edit mode only ($ae_loc.edit_mode)

Page behavior

  • Loads event.mod_pres_mgmt_json fresh from API on page open
  • Displays grouped form sections (see below)
  • Save = load → merge → PATCH /v3/crud/event/{event_id} with { mod_pres_mgmt_json: updated }
  • The existing settings form at /events/[id]/settings has its pres_mgmt section removed or replaced with a link

Form sections (grouped)

  1. Systemlock_config
  2. Labelslabel__* fields (text inputs, nullable)
  3. Session Visibilityhide__session_* toggles
  4. Presenter Visibilityhide__presenter_* toggles
  5. Presentation Visibilityhide__presentation_* toggles
  6. Code Visibilityhide__*_code toggles
  7. Opt-in Featuresshow__* toggles
  8. Requirementsrequire__presenter_agree, require__session_agree
  9. Navigation Limitslimit__navigation, limit__options
  10. File Purpose Configfile_purpose_option_kv (JSON editor or structured form)
  11. Report Visibilityhide__report_kv (key-value toggles)

Migration Path

Safe and backward compatible — old DB records fall through to ?? false defaults.

  1. No DB migration script needed — old keys are simply ignored by the updated sync function
  2. Active events (BGH) get updated via the new UI after it's built
  3. The sync_config__event_pres_mgmt() rewrite is the critical step — it must handle the canonical keys and clean defaults before the UI ships

Implementation Steps

  • Step 1 — Define PressMgmtRemoteCfg TypeScript interface (new file or in ae_events__event.ts)
  • Step 2 — New ae_events_stores__pres_mgmt.svelte.ts with PersistedState ⚠️ Missing: version gate in store_versions.ts
  • Step 3 — Rewrite sync_config__event_pres_mgmt() in ae_events__event.ts to use canonical keys ⚠️ Issue: show__launcher_link_legacy hard-coded instead of synced from remote
  • Step 4 — Build config UI page at (pres_mgmt)/pres_mgmt/config/+page.svelte (manager_access + edit_mode gated)
  • Step 5 — Strip ae_comp__event_settings_pres_mgmt_form.svelte from settings page (or replace with a link to new page) BLOCKING
  • Step 6 — Migrate all $events_loc.pres_mgmt.* references in pres_mgmt templates to pres_mgmt_loc.current.*
  • Step 7 — Update BGH (and any other active events) via new UI (blocked on Step 5)
  • Step 8npx svelte-check clean; commit

Regression Fixes Needed (2026-06-12 Audit)

  • Add show__launcher_link_legacy to PressMgmtRemoteCfg or remove entirely if deprecated
    • Currently hard-coded to true in sync function (line 1054 ae_events__event.ts)
    • Can't be controlled via config UI
  • Resolve hide__launcher_link* local/remote conflict
    • Menu toggles (ae_comp__events_menu_opts.svelte lines 462-494) use hide__launcher_link for LOCAL UI state
    • Remote schema uses show__launcher_link (inverted)
    • Decision: Keep separate? Document clearly? Unify?
  • Add AE_PRES_MGMT_LOC_VERSION to store_versions.ts (Step 2 requirement)
  • Clean hide__launcher_link* from defaults if truly deprecated (lines 154-155, 333-334 in pres_mgmt_defaults.ts)
  • POC column local/remote conflict fixed (2026-06-16)show__session_li_poc_field was local-only (never synced) and the session-list-table prop computation ignored the admin's hide__session_poc master switch entirely. Fixed: added show__session_li_poc_field to PressMgmtRemoteCfg + Config UI (Session Field Visibility) + sync_config__event_pres_mgmt() lock-synced block; list/table column visibility is now hide__session_poc || !show__session_li_poc_field in pres_mgmt/+page.svelte and locations/ae_comp__event_location_obj_li.svelte. The local per-browser "Show/Hide POC Column" toggle buttons in ae_comp__events_menu_opts.svelte and event_page_menu.svelte were removed — the field is lock-synced from the per-event Config page now, same as the other session field visibility toggles.
  • Presenter QR matched to session QR pattern (2026-06-16)show__session_qr / show__presenter_qr are the admin-set global default for everyone, signed in or not. show_content__*_qr is a trusted-staff-only local override, used when the admin has NOT enabled QR globally. The session QR side already worked this way (fixed earlier today); presenter QR was still on the old buggy logic requiring show_content__presenter_qr to be true even when the admin had enabled it for everyone, which non-trusted users (presenters) have no way to set. Fixed presenter_view.svelte (generation effect + display block) to show__presenter_qr || (trusted_access && show_content__presenter_qr). Also corrected two toggle-button visibility bugs found along the way: ae_comp__events_menu_opts.svelte was showing the QR toggle to all authenticated_access users (not just trusted) whenever the admin had enabled QR globally, even though the toggle had no effect for them; and presenter_page_menu.svelte's QR toggle was gated to administrator_access, hiding it from plain Trusted onsite staff entirely. Both now use the canonical pattern from session_page_menu.svelte: trusted_access && !show__*_qr.
  • Missing sync_config__event_pres_mgmt() calls on deep-link entry pages (2026-06-16) — root cause of the presenter QR bug above: a browser landing directly on the presenter page (e.g. via a presenter sign-in link) never synced remote config into pres_mgmt_loc.current at all, since only pres_mgmt/+page.svelte and session/[session_id]/+page.svelte called the sync function. Every "always synced" and "lock-synced" field (QR enables, POC visibility, code visibility, labels, etc.) silently stayed at hardcoded local defaults on that browser regardless of admin Config page settings. Added the same sync $effect (mirroring the existing comment/pattern in session/[session_id]/+page.svelte) to presenter/[presenter_id]/+page.svelte, locations/+page.svelte, location/[event_location_id]/+page.svelte, and reports/+page.svelte. Any new pres_mgmt page that can be a first-load entry point (i.e. not always reached via /pres_mgmt or /session/[id] first) needs this same block.

Step 6 scope (mechanical find-replace)

The $events_loc.pres_mgmt pattern appears across:

  • ae_comp__event_session_obj_li.svelte
  • ae_comp__events_menu_opts.svelte
  • session/[session_id]/+page.svelte
  • session/[session_id]/session_view.svelte
  • session/[session_id]/session_page_menu.svelte
  • locations/locations_page_menu.svelte
  • reports/+page.svelte
  • pres_mgmt/+page.svelte
  • (and likely others — run grep -r 'events_loc.pres_mgmt' src/ to get full list)

Notes

  • The lock_config: true default means most events will always sync from remote. This is intentional — it prevents presenter laptops from drifting into different configs.
  • file_purpose_option_kv may need a structured editor (not raw JSON) to be usable. Consider a simple key-value form row per purpose type for Phase 2.
  • QR link keys (hide__presenter_qr_link, hide__session_qr_link) appeared in LCI config but are not in the canonical schema above. Evaluate whether they're actively used before adding them back.
  • limit__navigation and limit__options are in the DB but not currently read by sync_config__event_pres_mgmt(). Confirm where they're consumed before adding to sync.