From a4ae1db4973af1e6a80e9ed7a91cae24d5265e43 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 8 Dec 2025 15:37:00 -0500 Subject: [PATCH] WIP: Prepared for SkeletonLabs v3 to v4 migration with temporary v3 dependencies. Proceed to rollback to 90ee6bb1 on main branch for re-verification. --- GEMINI.md | 151 ++++-- GEMINI_Flowbite_upgrade_2025-12.md | 38 ++ GEMINI_SkeletonLabs_upgrade_2025-12.md | 48 ++ GEMINI_debug_notes.md | 71 +++ package-lock.json | 703 ++++++++++--------------- package.json | 5 +- vite.config.ts | 4 +- 7 files changed, 534 insertions(+), 486 deletions(-) create mode 100644 GEMINI_Flowbite_upgrade_2025-12.md create mode 100644 GEMINI_SkeletonLabs_upgrade_2025-12.md create mode 100644 GEMINI_debug_notes.md diff --git a/GEMINI.md b/GEMINI.md index f005f78f..bb654682 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -82,19 +82,19 @@ The refactoring strategy involved creating a local, non-exported `_process_gener **Key aspects of the refactoring:** -- **In-file Generic Helper (`_process_generic_props`):** This function handles common data transformations: - - **`*_random` ID Aliasing:** It automatically iterates over object keys and creates a non-suffixed alias for any key ending in `_random` (e.g., `person_id_random` becomes `person_id`). This is crucial for client-side logic that expects standard ID fields. - - **`tmp_sort` Field Generation:** It creates a set of basic `tmp_sort` fields for client-side sorting. +- **In-file Generic Helper (`_process_generic_props`):** This function handles common data transformations: + - **`*_random` ID Aliasing:** It automatically iterates over object keys and creates a non-suffixed alias for any key ending in `_random` (e.g., `person_id_random` becomes `person_id`). This is crucial for client-side logic that expects standard ID fields. + - **`tmp_sort` Field Generation:** It creates a set of basic `tmp_sort` fields for client-side sorting. -- **`specific_processor` Callback:** Module-specific logic is handled by a `specific_processor` callback function passed to the `_process_generic_props` helper. This allows for: - - **Unique `tmp_sort` Logic:** Modules can override the default `tmp_sort` fields with their own specific sorting requirements. - - **Content Processing:** Asynchronous operations like Markdown parsing (using `marked.parse`) are handled within the `specific_processor` for the relevant modules (e.g., `ae_journals__journal_entry.ts`). - - **Other Special Cases:** Any other module-specific data transformations are handled in this callback. +- **`specific_processor` Callback:** Module-specific logic is handled by a `specific_processor` callback function passed to the `_process_generic_props` helper. This allows for: + - **Unique `tmp_sort` Logic:** Modules can override the default `tmp_sort` fields with their own specific sorting requirements. + - **Content Processing:** Asynchronous operations like Markdown parsing (using `marked.parse`) are handled within the `specific_processor` for the relevant modules (e.g., `ae_journals__journal_entry.ts`). + - **Other Special Cases:** Any other module-specific data transformations are handled in this callback. -- **`core__crud_generic.ts` Cleanup:** The generic CRUD functions in `src/lib/ae_core/core__crud_generic.ts` were simplified: - - The `process_ae_obj__props` function in this file was deprecated. - - All calls to `process_ae_obj__props` and `db_save_ae_obj_li__ae_obj` were removed from the generic CRUD functions (`load_ae_obj_id`, `load_ae_obj_li`, etc.). - - These functions are now responsible only for API interaction, delegating all data processing and caching to the module-specific functions that call them. This enforces a cleaner separation of concerns. +- **`core__crud_generic.ts` Cleanup:** The generic CRUD functions in `src/lib/ae_core/core__crud_generic.ts` were simplified: + - The `process_ae_obj__props` function in this file was deprecated. + - All calls to `process_ae_obj__props` and `db_save_ae_obj_li__ae_obj` were removed from the generic CRUD functions (`load_ae_obj_id`, `load_ae_obj_li`, etc.). + - These functions are now responsible only for API interaction, delegating all data processing and caching to the module-specific functions that call them. This enforces a cleaner separation of concerns. ### Tiptap to CodeMirror Migration (2025-11-17) @@ -102,38 +102,38 @@ The rich text editor component, previously based on Tiptap (`shad-editor`), has **Key aspects of the migration:** -- **Removal of Tiptap:** All `@tiptap/*` and `svelte-tiptap` dependencies were removed from `package.json`, and the `src/lib/components/shad-editor/` directory was deleted. -- **CodeMirror Integration:** A new CodeMirror component (`src/lib/elements/element_codemirror_editor.svelte`) was created, providing basic markdown formatting capabilities. -- **Wrapper Component Update:** The existing editor wrapper (`src/lib/elements/element_tiptap_editor.svelte`) was renamed to `src/lib/elements/element_codemirror_wrapper.svelte` and refactored to utilize the new CodeMirror component. Tiptap-specific logic and props were removed. -- **Component Usage Updates:** All Svelte components that previously imported and used the Tiptap wrapper were updated to import `element_codemirror_wrapper.svelte`. Unsupported props such as `default_minimal`, `show_button_kv`, `bind:new_html`, and `bind:changed` were removed from their usage. -- **Dependency Cleanup:** `npm install` was run to remove unneeded packages, and `npm run format` was executed to ensure consistent code style. +- **Removal of Tiptap:** All `@tiptap/*` and `svelte-tiptap` dependencies were removed from `package.json`, and the `src/lib/components/shad-editor/` directory was deleted. +- **CodeMirror Integration:** A new CodeMirror component (`src/lib/elements/element_codemirror_editor.svelte`) was created, providing basic markdown formatting capabilities. +- **Wrapper Component Update:** The existing editor wrapper (`src/lib/elements/element_tiptap_editor.svelte`) was renamed to `src/lib/elements/element_codemirror_wrapper.svelte` and refactored to utilize the new CodeMirror component. Tiptap-specific logic and props were removed. +- **Component Usage Updates:** All Svelte components that previously imported and used the Tiptap wrapper were updated to import `element_codemirror_wrapper.svelte`. Unsupported props such as `default_minimal`, `show_button_kv`, `bind:new_html`, and `bind:changed` were removed from their usage. +- **Dependency Cleanup:** `npm install` was run to remove unneeded packages, and `npm run format` was executed to ensure consistent code style. ### CodeMirror Bug Fixes (2025-11-18) Following the initial migration to CodeMirror, several issues were identified and resolved: -- **Initialization Errors:** An "Unrecognized extension value" error was fixed by refactoring `codemirror_modules.ts` to explicitly import individual CodeMirror extensions instead of relying on the `basicSetup` bundle. This ensures proper singleton usage and prevents module duplication. -- **Text Wrapping:** The `EditorView.lineWrapping` extension was added to `element_codemirror_editor.svelte` and `e_app_codemirror_v5.svelte` to enable text wrapping. -- **Content Saving:** Content binding issues were resolved in various IDAA components by correctly binding the `html_text` prop of the CodeMirror wrapper to the corresponding state variables. -- **Save Button Enablement:** The logic for enabling the "Save" button was fixed in `ae_idaa_comp__post_obj_id_edit.svelte` to correctly detect changes in the CodeMirror editor. -- **Editor Buttons:** A `TypeError` in the editor's formatting buttons was fixed by using `EditorSelection.range()` to correctly create selection ranges. -- **Component Renaming:** The `Tiptap_editor` component alias was renamed to `CodeMirror_wrapper` across the project for clarity, and the wrapper file was renamed to `element_codemirror_editor_wrapper.svelte`. +- **Initialization Errors:** An "Unrecognized extension value" error was fixed by refactoring `codemirror_modules.ts` to explicitly import individual CodeMirror extensions instead of relying on the `basicSetup` bundle. This ensures proper singleton usage and prevents module duplication. +- **Text Wrapping:** The `EditorView.lineWrapping` extension was added to `element_codemirror_editor.svelte` and `e_app_codemirror_v5.svelte` to enable text wrapping. +- **Content Saving:** Content binding issues were resolved in various IDAA components by correctly binding the `html_text` prop of the CodeMirror wrapper to the corresponding state variables. +- **Save Button Enablement:** The logic for enabling the "Save" button was fixed in `ae_idaa_comp__post_obj_id_edit.svelte` to correctly detect changes in the CodeMirror editor. +- **Editor Buttons:** A `TypeError` in the editor's formatting buttons was fixed by using `EditorSelection.range()` to correctly create selection ranges. +- **Component Renaming:** The `Tiptap_editor` component alias was renamed to `CodeMirror_wrapper` across the project for clarity, and the wrapper file was renamed to `element_codemirror_editor_wrapper.svelte`. ### Badge Search Refactoring (2025-11-18) The new Badge Search functionality was refactored to resolve several issues related to Svelte 5 reactivity and IndexedDB schema design. -- **Svelte 5 Reactivity Fixes:** - - A `store_invalid_shape` error was fixed by removing the `$` prefix from Svelte 5 state variables in templates. - - A Svelte 5 compilation error (`illegal variable name`) was resolved by using `$derived` to create a local reactive variable from a store. - - A 500 Internal Error was resolved by moving Dexie `liveQuery` calls into an `onMount` block to ensure they only run on the client-side. -- **IndexedDB Schema Refactoring:** - - The primary key for the `badge` table was changed from a numeric `id` to the string-based `event_badge_id_random`. - - All related components were updated to use the new primary key for data retrieval, allowing for more efficient lookups using `get()` and `bulkGet()`. -- **Data Flow Simplification:** - - The badge search data flow was refactored to pass full badge objects from the search component to the list component, simplifying the logic and resolving reactivity issues. -- **Link Generation:** - - Badge links were updated to use the string-based random IDs for both the event and the badge, ensuring consistency and avoiding the exposure of internal numeric IDs. +- **Svelte 5 Reactivity Fixes:** + - A `store_invalid_shape` error was fixed by removing the `$` prefix from Svelte 5 state variables in templates. + - A Svelte 5 compilation error (`illegal variable name`) was resolved by using `$derived` to create a local reactive variable from a store. + - A 500 Internal Error was resolved by moving Dexie `liveQuery` calls into an `onMount` block to ensure they only run on the client-side. +- **IndexedDB Schema Refactoring:** + - The primary key for the `badge` table was changed from a numeric `id` to the string-based `event_badge_id_random`. + - All related components were updated to use the new primary key for data retrieval, allowing for more efficient lookups using `get()` and `bulkGet()`. +- **Data Flow Simplification:** + - The badge search data flow was refactored to pass full badge objects from the search component to the list component, simplifying the logic and resolving reactivity issues. +- **Link Generation:** + - Badge links were updated to use the string-based random IDs for both the event and the badge, ensuring consistency and avoiding the exposure of internal numeric IDs. ### Event Settings Page (2025-11-18) @@ -141,35 +141,76 @@ A new event settings page was created at `/events/[event_id]/settings` to provid **Key features:** -- **Form-Based UI:** Instead of raw JSON editing, the page uses form-based components for editing event properties. This includes basic event fields (name, code, dates, etc.) and the JSON configuration fields (`cfg_json`, `mod_pres_mgmt_json`, `mod_badges_json`, `mod_abstracts_json`). -- **Collapsible Sections:** Each configuration section is wrapped in a `
` element, allowing them to be collapsed and expanded for better organization. -- **View Toggling:** For the JSON configuration fields, a toggle switch allows the user to switch between the form-based UI and a raw JSON editor (using CodeMirror), providing flexibility for both simple and advanced editing. -- **Svelte 5 Reactivity:** The components were built using Svelte 5's `bindable` props to ensure proper two-way data binding between the parent page and the child form components. This corrected an issue where changes in the child components were not being reflected in the parent's state. +- **Form-Based UI:** Instead of raw JSON editing, the page uses form-based components for editing event properties. This includes basic event fields (name, code, dates, etc.) and the JSON configuration fields (`cfg_json`, `mod_pres_mgmt_json`, `mod_badges_json`, `mod_abstracts_json`). +- **Collapsible Sections:** Each configuration section is wrapped in a `
` element, allowing them to be collapsed and expanded for better organization. +- **View Toggling:** For the JSON configuration fields, a toggle switch allows the user to switch between the form-based UI and a raw JSON editor (using CodeMirror), providing flexibility for both simple and advanced editing. +- **Svelte 5 Reactivity:** The components were built using Svelte 5's `bindable` props to ensure proper two-way data binding between the parent page and the child form components. This corrected an issue where changes in the child components were not being reflected in the parent's state. ### API Payload Cleaning (2025-11-19) To address issues with the Aether API's strict handling of `POST` and `PATCH` request payloads, a more robust solution for cleaning data on the frontend has been implemented. -- **Svelte 5 Event Handlers:** Corrected the use of `on:click` to `onclick` in the event settings components to align with Svelte 5 conventions. -- **Payload Cleaning:** - - The `update_ae_obj__event` function in `src/lib/ae_events/ae_events__event.ts` was modified to remove read-only fields (`id`, `event_id`, `created_on`, `updated_on`, etc.) from the payload before sending it to the API. - - The function now also correctly renames `account_id` to `account_id_random` to match the API's expectations. -- **Editable Fields Whitelist:** - - A new file, `src/lib/ae_events/ae_events__event.editable_fields.ts`, was created to define a whitelist of fields that are allowed to be sent in `POST` and `PATCH` requests for an event. - - The `create_ae_obj__event` and `update_ae_obj__event` functions now use this whitelist to filter the `data_kv` object, ensuring only allowed fields are sent to the API. This provides a more maintainable and less error-prone way to manage which fields are sent to the API. -- **Component Cleanup:** The temporary pre-cleaning logic from the `handle_save` function in `src/routes/events/[event_id]/settings/+page.svelte` has been removed, as the filtering is now handled centrally in `ae_events__event.ts`. -- **Future Work:** This pattern of using a whitelist for editable fields will be applied to all other Aether object types to ensure consistent and correct API interactions across the application. +- **Svelte 5 Event Handlers:** Corrected the use of `on:click` to `onclick` in the event settings components to align with Svelte 5 conventions. +- **Payload Cleaning:** + - The `update_ae_obj__event` function in `src/lib/ae_events/ae_events__event.ts` was modified to remove read-only fields (`id`, `event_id`, `created_on`, `updated_on`, etc.) from the payload before sending it to the API. + - The function now also correctly renames `account_id` to `account_id_random` to match the API's expectations. +- **Editable Fields Whitelist:** + - A new file, `src/lib/ae_events/ae_events__event.editable_fields.ts`, was created to define a whitelist of fields that are allowed to be sent in `POST` and `PATCH` requests for an event. + - The `create_ae_obj__event` and `update_ae_obj__event` functions now use this whitelist to filter the `data_kv` object, ensuring only allowed fields are sent to the API. This provides a more maintainable and less error-prone way to manage which fields are sent to the API. +- **Component Cleanup:** The temporary pre-cleaning logic from the `handle_save` function in `src/routes/events/[event_id]/settings/+page.svelte` has been removed, as the filtering is now handled centrally in `ae_events__event.ts`. +- **Future Work:** This pattern of using a whitelist for editable fields will be applied to all other Aether object types to ensure consistent and correct API interactions across the application. ### Badge Search v3 Bug-Fixing Session (2025-11-19) This session focused on resolving a series of cascading build and runtime errors that prevented the new "Badges v3" feature from loading and functioning correctly. -- **Initial State:** The page was failing with a `Cannot use @variant with unknown variant: md` error, caused by a conflict between Skeleton UI's CSS and the project's Tailwind CSS v4 configuration. -- **Misguided Fix & Reversal:** An initial attempt to fix this by removing all global Skeleton UI CSS imports from `app.css` resolved the `@variant` error but broke site-wide styling, causing errors like `Cannot apply unknown utility class 'preset-tonal-secondary'`. The Skeleton imports were subsequently restored to stabilize the application. -- **Svelte v5 Event Syntax:** A significant amount of time was spent incorrectly attempting to "fix" Svelte v5 event handlers. The correct understanding was eventually established: - - **DOM Events:** Use the `onevent` prefix (e.g., `onclick`). - - **Component Events:** Continue to use the `on:event` directive (e.g., `on:success`). -- **Invalid Attribute Name Error:** An error (`'onsubmit|preventDefault' is not a valid attribute name`) was discovered in the new badge forms. This was resolved by removing the `|preventDefault` modifier from the `onsubmit` attribute and instead calling `event.preventDefault()` inside the handler function. This appears to be a nuance or bug in how the Svelte v5 compiler handles modifiers with the new `on` prefix. -- **Svelte 5 Binding Error:** A runtime error, `props_invalid_value: Cannot do bind:prop={undefined}`, was fixed. It was caused by binding a parent component's `undefined` store value to a child component's prop that had a fallback. The fix involved adding a defensive initialization check directly in the parent component's `