Added a new 'Development Guidelines' section to GEMINI.md to provide clear instructions on Svelte v5 conventions and the project's 'id' vs 'id_random' usage. This will serve as a reminder to avoid common pitfalls and ensure code consistency.
9.6 KiB
Aether (AE) SvelteKit Application
This project is a Svelte and SvelteKit based application, part of the Aether (AE) system. It uses Tailwind CSS and Skeleton for styling and some elements. This is the frontend UI/UX. The backend API uses Python FastAPI.
Core Aether modules
- accounts - client account, not user account
- hosted_files
- people
- users
- sites and site_domains
Additional Aether modules
- events
- presentation management - import the program data (events, session, presentations, presenters, event files, locations/rooms, devices)
- launcher - Technically this is used with presentation management. It is part of the native app that uses Electron. One of the libraries is for functions that only work when the site is opened in an Electron app. For example the regular browser can not move files around on the local computer or run local commands.
- badge printing
- lead retrieval - attendee tracking; QR codes
- journals - journal, documentation, notes, diary, blog, etc
- idaa - One of my clients
Documentation
- TODO.md
- Svelte - Introducing runes - https://svelte.dev/blog/runes
- Svelte - Breaking changes in runes mode - https://svelte.dev/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode
- Dexie.js - Getting Started - https://dexie.org/docs/Tutorial/Getting-started
- Dexie.js - API Quick Reference - https://dexie.org/docs/API-Reference#quick-reference
Ignored Directories
The following directories are ignored for various operations (e.g., search, file listing) to focus on relevant source code:
buildnode_modulestests
Development Guidelines
Svelte v5 and SvelteKit
This project uses Svelte v5 with runes enabled. This introduces significant differences from Svelte v4. It is critical to adhere to v5 conventions to avoid bugs.
- Reactivity: State is managed with
$stateand$derived. Props can be made two-way bindable with$bindable. Avoid direct mutation of props. - Event Handling:
- DOM events still use the
on:eventnamedirective (e.g.,on:click,on:input). - Component events are dispatched with
createEventDispatcherand listened to withon:eventname. - For two-way binding on component props, use
bind:propName.
- DOM events still use the
- Stores and
liveQuery:- To access the value of a store in Svelte v5, you must use the
$store_namesyntax (e.g.,$ae_api). - Dexie
liveQueryreturns an observable. To use it in a component, you must subscribe to it withinonMountto avoid SSR errors. The value from the subscription should then be assigned to a$statevariable.
- To access the value of a store in Svelte v5, you must use the
- Migration Guide: For a comprehensive overview of the changes, refer to the official Svelte 5 Migration Guide.
ID Convention: id vs. id_random
- Always use
id_random: The API returns both a numericidand a string-based[obj_type]_id_random. For all frontend operations (routing, data fetching, local storage), you must use the_id_randomstring. - Local Storage: When saving an object to the local IndexedDB (Dexie), the
id_randomvalue should be aliased to bothid(as the primary key) and[obj_type]_id. This ensures consistency with Dexie's expectations and the rest of the application's data access patterns.
Refactoring Notes
process_ae_obj__*_props() Refactoring (2025-11-13)
The process_ae_obj__*_props() family of functions, which are responsible for transforming API data for frontend use, have been refactored to standardize their structure and improve maintainability.
The refactoring strategy involved creating a local, non-exported _process_generic_props helper function within each module (ae_journals, ae_events, ae_archives, ae_posts, ae_core). This approach was chosen to avoid altering the module import graph, which had previously caused a critical InternalError: module record has unexpected status: New in the SvelteKit development server when a shared utility file was introduced.
Key aspects of the refactoring:
-
In-file Generic Helper (
_process_generic_props): This function handles common data transformations:*_randomID Aliasing: It automatically iterates over object keys and creates a non-suffixed alias for any key ending in_random(e.g.,person_id_randombecomesperson_id). This is crucial for client-side logic that expects standard ID fields.tmp_sortField Generation: It creates a set of basictmp_sortfields for client-side sorting.
-
specific_processorCallback: Module-specific logic is handled by aspecific_processorcallback function passed to the_process_generic_propshelper. This allows for:- Unique
tmp_sortLogic: Modules can override the defaulttmp_sortfields with their own specific sorting requirements. - Content Processing: Asynchronous operations like Markdown parsing (using
marked.parse) are handled within thespecific_processorfor the relevant modules (e.g.,ae_journals__journal_entry.ts). - Other Special Cases: Any other module-specific data transformations are handled in this callback.
- Unique
-
core__crud_generic.tsCleanup: The generic CRUD functions insrc/lib/ae_core/core__crud_generic.tswere simplified:- The
process_ae_obj__propsfunction in this file was deprecated. - All calls to
process_ae_obj__propsanddb_save_ae_obj_li__ae_objwere 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.
- The
Tiptap to CodeMirror Migration (2025-11-17)
The rich text editor component, previously based on Tiptap (shad-editor), has been replaced with a CodeMirror-based solution. This change was driven by the complexity of Tiptap and its compatibility issues with Tailwind CSS, aiming for a simpler, markdown-focused editing experience.
Key aspects of the migration:
- Removal of Tiptap: All
@tiptap/*andsvelte-tiptapdependencies were removed frompackage.json, and thesrc/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 tosrc/lib/elements/element_codemirror_wrapper.svelteand 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 asdefault_minimal,show_button_kv,bind:new_html, andbind:changedwere removed from their usage. - Dependency Cleanup:
npm installwas run to remove unneeded packages, andnpm run formatwas 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.tsto explicitly import individual CodeMirror extensions instead of relying on thebasicSetupbundle. This ensures proper singleton usage and prevents module duplication. - Text Wrapping: The
EditorView.lineWrappingextension was added toelement_codemirror_editor.svelteande_app_codemirror_v5.svelteto enable text wrapping. - Content Saving: Content binding issues were resolved in various IDAA components by correctly binding the
html_textprop 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.svelteto correctly detect changes in the CodeMirror editor. - Editor Buttons: A
TypeErrorin the editor's formatting buttons was fixed by usingEditorSelection.range()to correctly create selection ranges. - Component Renaming: The
Tiptap_editorcomponent alias was renamed toCodeMirror_wrapperacross the project for clarity, and the wrapper file was renamed toelement_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_shapeerror 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$derivedto create a local reactive variable from a store. - A 500 Internal Error was resolved by moving Dexie
liveQuerycalls into anonMountblock to ensure they only run on the client-side.
- A
- IndexedDB Schema Refactoring:
- The primary key for the
badgetable was changed from a numericidto the string-basedevent_badge_id_random. - All related components were updated to use the new primary key for data retrieval, allowing for more efficient lookups using
get()andbulkGet().
- The primary key for the
- 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.