docs: reorganize and rename documentation files for consistency
- Apply consistent prefix naming: AE__, GUIDE__, PROJECT__, MODULE__, TODO__ - Move superseded/session docs to documentation/history/ - Migrate old/ directory contents to history/ with updated naming - README.md: replace stale Modules section with accurate current routes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# Aether API CRUD V3 Beta Recommendations
|
||||
|
||||
Following the initial migration of the Journals module to the V3 CRUD endpoints, the following architectural recommendations are proposed for the FastAPI backend to improve developer experience and frontend efficiency.
|
||||
|
||||
---
|
||||
|
||||
## 1. "View" Selection (`use_alt_tbl` Replacement)
|
||||
In V2, the `use_alt_tbl` flag was frequently used to fetch "rich" objects (e.g., including joined data like `person_name`).
|
||||
- **Recommendation:** Implement a `response_view` (or `view`) query parameter for both GET list and POST search endpoints.
|
||||
- **Example:** `GET /v3/crud/journal/?view=enriched`
|
||||
- **Goal:** Allow the client to request a heavier model with joined fields only when necessary, keeping the default response lightweight.
|
||||
|
||||
## 2. Hybrid Filtering for Search
|
||||
Currently, the `/search` endpoint requires a full JSON body even for simple standard filters like `enabled` or `hidden`.
|
||||
- **Recommendation:** Update the `POST .../search` endpoint to accept standard query parameters that automatically append `AND` conditions to the logic defined in the body.
|
||||
- **Example:** `POST /v3/crud/journal/search?enabled=true`
|
||||
- **Goal:** Simplifies frontend code for common toggles while still allowing complex logic in the POST body.
|
||||
|
||||
## 3. Standardized Full-Text Search Field
|
||||
The current migration uses a field named `default_qry_str` with a `match` operator for text search.
|
||||
- **Recommendation:** Implement a reserved top-level property in the Search Pydantic model (e.g., `_search_` or `query_string`) specifically for global text search.
|
||||
- **Goal:** Decouples the frontend from knowing specific database column names used for full-text indexing. The backend can then decide which columns (name, description, tags, etc.) to include in the search.
|
||||
|
||||
## 4. Explicit "Parent" Filtering in Search
|
||||
Filtering by parent (e.g., Account or Site) is a primary use case but currently requires manual injection into the `and` array.
|
||||
- **Recommendation:** Expose `for_obj_type` and `for_obj_id` as top-level arguments in the Search API.
|
||||
- **Goal:** Standardizes how parent context is passed, allowing the backend to more easily perform ownership and permission validation before executing the search.
|
||||
|
||||
---
|
||||
**Date:** 2026-01-02
|
||||
**Status:** Beta Feedback
|
||||
51
documentation/history/GEMINI_Flowbite_upgrade_2025-12.md
Normal file
51
documentation/history/GEMINI_Flowbite_upgrade_2025-12.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Flowbite-Svelte Upgrade Notes (December 2025)
|
||||
|
||||
## Overview
|
||||
This document tracks the process of upgrading the Flowbite-Svelte UI library within the Aether SvelteKit project. The primary goal is to determine if a compatible version exists for Svelte 5 and Tailwind CSS v4, and to plan for its integration or replacement if necessary.
|
||||
|
||||
## Current Status (Pre-Upgrade)
|
||||
- **Flowbite-Svelte Version:** v1.28.1 (as per `package.json` at commit `90ee6bb1`)
|
||||
- **Target Version:** v1.30.0 (or newest compatible)
|
||||
- **Initial Issue (Pre-Rollback):** Previous attempts to update `flowbite-svelte` (and other packages) indicated peer dependency conflicts. Earlier versions of `flowbite-svelte` (compatible with Tailwind v3) required Svelte v4, which conflicted with the project's Svelte v5.
|
||||
- **Current Re-evaluation:** After rolling back to commit `90ee6bb1` and updating SkeletonLabs (which failed the build due to other reasons), `npm install` succeeded with `flowbite-svelte@1.28.1` present in `package.json`. This implies it *can install* alongside Svelte 5 and Tailwind 4. However, its runtime compatibility and rendering correctness with Svelte 5 (runes mode) and Tailwind CSS v4 remain untested.
|
||||
- **Svelte Version:** Svelte 5 (runes mode)
|
||||
- **Tailwind CSS Version:** v4.1.10
|
||||
|
||||
## Phase 1: Research and Planning (No Code Changes Yet)
|
||||
|
||||
### Goal
|
||||
Determine if Flowbite-Svelte has a version that is explicitly compatible with Svelte 5 (runes mode) and Tailwind CSS v4, and to identify any breaking changes or migration paths.
|
||||
|
||||
### Steps
|
||||
1. **Thoroughly Review Flowbite-Svelte Changelog:**
|
||||
* **Link:** `https://github.com/themesberg/flowbite-svelte/blob/main/CHANGELOG.md`
|
||||
* **Action:** Read the changelog for versions from `1.28.1` up to the latest stable release (e.g., `1.30.0` or newer).
|
||||
* **Goal:** Look for specific mentions of Svelte 5 support, "runes mode" compatibility, or compatibility with Tailwind CSS v4. Note any breaking changes or migration instructions related to Svelte version or component API changes.
|
||||
|
||||
### Expected Outcome of Phase 1
|
||||
A clear understanding of Flowbite-Svelte's compatibility with our current stack. This will inform the decision on whether to attempt an upgrade or if abandoning it (and creating custom replacements) is necessary. The expectation is that if a version is compatible, any breaking changes to component APIs (like renaming `Modal` to `Dialog`) will be identified.
|
||||
|
||||
## Phase 2: Execution (After Approval)
|
||||
|
||||
### Steps (To be detailed after Phase 1)
|
||||
1. **If a compatible version exists:**
|
||||
* Update `package.json` to the compatible version.
|
||||
* Run `npm install`.
|
||||
* Run `npm run build` and `npm run dev` and thoroughly check for errors and visual regressions.
|
||||
* Apply any necessary code changes based on identified breaking changes (e.g., component name changes like `Modal` to `Dialog`).
|
||||
2. **If no compatible version exists or issues persist:**
|
||||
* **Decision:** Abandon Flowbite-Svelte.
|
||||
* **Action:** Systematically replace its components with custom-built Svelte/Tailwind components, starting with critical ones like `Modal` (using our `element_modal_v1.svelte` if not using Skeleton's `Dialog`).
|
||||
|
||||
## Final Decision (2025-12-08)
|
||||
|
||||
**Outcome:** Hold off on upgrading Flowbite-Svelte.
|
||||
|
||||
**Reasoning:**
|
||||
The changelog indicates that experimental Svelte 5 support was added in version `0.45.0`. However, there is no mention of compatibility with Tailwind CSS v4. Since SkeletonLabs (the other major UI library) is being removed due to build failures, our immediate priority is to stabilize the project and replace Skeleton's components. Introducing another potential variable by upgrading Flowbite-Svelte at the same time is not advisable.
|
||||
|
||||
**Path Forward:**
|
||||
1. The currently installed version of `flowbite-svelte` (`1.28.1`) will be kept for now.
|
||||
2. After SkeletonLabs is removed and the project builds successfully, we will test the functionality of existing Flowbite-Svelte components.
|
||||
3. If they work, we will continue to use them.
|
||||
4. If they cause build or runtime errors after SkeletonLabs is removed, we will then evaluate either upgrading to `v0.45.0` (with careful testing against Tailwind v4) or abandoning Flowbite-Svelte and replacing its components with custom ones.
|
||||
62
documentation/history/GEMINI_SkeletonLabs_upgrade_2025-12.md
Normal file
62
documentation/history/GEMINI_SkeletonLabs_upgrade_2025-12.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# SkeletonLabs Upgrade Notes (December 2025)
|
||||
|
||||
## Overview
|
||||
This document tracks the process of upgrading the SkeletonLabs UI library (from v3 to v4.7.4) within the Aether SvelteKit project. The primary goal is to resolve build issues caused by incompatibility with Svelte 5 and Tailwind CSS v4, and to integrate the updated library correctly.
|
||||
|
||||
## Current Status (Pre-Upgrade)
|
||||
- **SkeletonLabs Version:** v3.2.2 (as per `package.json` at commit `90ee6bb1`)
|
||||
- **Target Version:** v4.7.4
|
||||
- **Issue:** Previous attempts to upgrade SkeletonLabs to v4.7.4 resulted in a persistent, blocking build error: `[@tailwindcss/vite:generate:build] Cannot use `@variant` with unknown variant: md` originating from `node_modules/@skeletonlabs/skeleton/src/index.css`. This indicates a fundamental incompatibility in how Tailwind CSS v4 processes SkeletonLabs' pre-compiled CSS.
|
||||
- **Svelte Version:** Svelte 5 (runes mode)
|
||||
- **Tailwind CSS Version:** v4.1.10
|
||||
|
||||
## Phase 1: Research and Planning (No Code Changes Yet)
|
||||
|
||||
### Goal
|
||||
Understand the required migration steps from Skeleton v3 to v4 as per official documentation, specifically to address the `@variant` build error and ensure compatibility with Svelte 5 and Tailwind CSS v4.
|
||||
|
||||
### Steps
|
||||
1. **Thoroughly Review Skeleton v3 to v4 Migration Guide:**
|
||||
* **Link:** `https://www.skeleton.dev/docs/svelte/get-started/migrate-from-v3`
|
||||
* **Action:** Read the guide carefully to identify all breaking changes related to:
|
||||
* Tailwind CSS plugin setup in `tailwind.config.ts`.
|
||||
* Required changes to `app.css` or any other global CSS files.
|
||||
* Changes in component class names, especially theme-related classes (`preset-*`, `variant-*`, etc.), which could be related to the `@variant` error.
|
||||
* The new `Dialog` component and how it replaces any previous modal-like components.
|
||||
* **Deliverable:** Summarize the required code changes based on this guide.
|
||||
|
||||
2. **Review Skeleton v4.0 Launch Discussion:**
|
||||
* **Link:** `https://github.com/skeletonlabs/skeleton/discussions/3920`
|
||||
* **Action:** Look for community insights, common issues, and suggested solutions related to upgrading.
|
||||
|
||||
3. **Review Skeleton Dialog Documentation:**
|
||||
* **Link:** `https://www.skeleton.dev/docs/svelte/framework-components/dialog`
|
||||
* **Action:** Understand the API and usage of Skeleton's native dialog component, as this will be the preferred replacement for any missing `<Modal>` components.
|
||||
|
||||
### Expected Outcome of Phase 1
|
||||
A detailed, step-by-step plan for migrating SkeletonLabs from v3 to v4, specifically targeting the resolution of the `@variant` build error and outlining the new usage of its UI components. This plan will be presented for approval before any code changes are made.
|
||||
|
||||
## Phase 2: Execution (After Approval)
|
||||
|
||||
### Steps (To be detailed after Phase 1)
|
||||
1. **Update `package.json`:** Set `@skeletonlabs/skeleton` and `@skeletonlabs/skeleton-svelte` to `4.7.4`.
|
||||
2. **Adjust `tailwind.config.ts`:** Apply changes as per migration guide (e.g., plugin configuration).
|
||||
3. **Adjust `src/app.css`:** Apply changes as per migration guide (e.g., CSS imports, custom theme definitions).
|
||||
4. **Run `npm install`**.
|
||||
5. **Run `npm run build` and `npm run dev`** to verify the build and functionality.
|
||||
6. **Replace `Modal` components:** Update existing components that used an older `<Modal>` (e.g., from `flowbite-svelte` or previous custom efforts) with Skeleton's new `Dialog` component.
|
||||
7. **Address Svelte 5 reactivity warnings:** Fix any warnings related to data handling or non-reactive updates.
|
||||
|
||||
## Final Decision (2025-12-08)
|
||||
|
||||
**Outcome:** Abandoning SkeletonLabs.
|
||||
|
||||
**Reasoning:**
|
||||
Despite following the official migration guide and attempting various configurations, the upgrade from SkeletonLabs v3 to v4.7.4 consistently fails with a blocking build error: `[@tailwindcss/vite:generate:build] Cannot use @variant with unknown variant: md`. This error points to a fundamental incompatibility between SkeletonLabs' pre-compiled CSS and the Tailwind CSS v4 build process in this Vite project.
|
||||
|
||||
Given the significant time spent debugging this issue without a clear resolution path through configuration, the most pragmatic decision is to remove SkeletonLabs entirely and proceed with custom UI component implementation.
|
||||
|
||||
**Path Forward:**
|
||||
1. All SkeletonLabs dependencies (`@skeletonlabs/skeleton`, `@skeletonlabs/skeleton-svelte`) will be removed from `package.json`.
|
||||
2. All SkeletonLabs configurations (e.g., in `tailwind.config.ts`, `app.css`) will be removed.
|
||||
3. UI components previously provided by SkeletonLabs will be replaced with custom Svelte components styled with pure Tailwind CSS.
|
||||
71
documentation/history/GEMINI_debug_notes.md
Normal file
71
documentation/history/GEMINI_debug_notes.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Skeleton/Tailwind Build Debugging Log
|
||||
|
||||
This file tracks the troubleshooting steps taken to resolve the build and dev server errors after updating packages.
|
||||
|
||||
## Initial State (Pre-Rollback to 90ee6bb1)
|
||||
|
||||
- **Packages Updated:** Attempted to update `@skeletonlabs/skeleton` to `4.7.4`, `tailwindcss` to `4.1.10`, and `flowbite-svelte` (version not explicitly stated in previous logs but was part of the update attempts).
|
||||
- **`dev` Error:** `Cannot apply unknown utility class 'preset-tonal-secondary'`
|
||||
- **`build` Error:** `Cannot use @variant with unknown variant: md`
|
||||
- **Dependency Conflicts:** Persistent `ERESOLVE` errors, primarily due to:
|
||||
- `flowbite-svelte` versions compatible with Tailwind v3 requiring `svelte@^4.0.0` (while project is Svelte v5).
|
||||
- `@skeletonlabs/skeleton` versions requiring `tailwindcss@^4.0.0` (while attempting to use Tailwind v3 for `flowbite-svelte` compatibility).
|
||||
- **Conclusion:** A fundamental incompatibility between Svelte v5, Tailwind v4, and the existing versions of UI component libraries (Skeleton, Flowbite-Svelte) when trying to achieve a stable `npm install`.
|
||||
|
||||
## Troubleshooting Steps (Pre-Rollback)
|
||||
|
||||
(Summarized from previous extensive debugging logs)
|
||||
- Multiple attempts to downgrade/upgrade Tailwind, Skeleton, and Flowbite-Svelte led to a "dependency nightmare."
|
||||
- Identified that Flowbite-Svelte was the primary blocker for maintaining Svelte v5 compatibility while also using an older Tailwind.
|
||||
- Attempted a strategy to remove *all* pre-built UI component libraries (Skeleton, Flowbite-Svelte) to achieve a clean Svelte v5 + Tailwind v4 base. This led to:
|
||||
- `ReferenceError: Modal is not defined` due to the removal of the underlying `Modal` component.
|
||||
- `</form>` syntax error due to incorrect commenting out of the `<Modal>` component's block.
|
||||
- Server-side `500 Internal Error` (diagnosis interrupted by rollback decision).
|
||||
|
||||
## Current State (Post-Rollback to 90ee6bb1)
|
||||
|
||||
- **Commit:** `90ee6bb1 - All packages have now been updated. This includes the skeletonlabs packages. Everything seems to be working. (Except for some unrelated known bugs. Why did the badge search stop working (AGAIN)?)`
|
||||
- **Status:** Application is confirmed to be "mostly working" at this commit. This provides a stable baseline.
|
||||
- **Key Observation from Commit Message:** "All packages have now been updated. This includes the skeletonlabs packages. Everything seems to be working." This implies that at this point, the `skeletonlabs` packages *were* working with some configuration of Svelte and Tailwind.
|
||||
|
||||
## Revised Path Forward: Re-evaluate UI Library Compatibility
|
||||
|
||||
**Context:** The previous issues stemmed from an inability to reconcile `skeletonlabs/skeleton` (requiring Tailwind v4), `flowbite-svelte` (preferring Svelte v4 for Tailwind v3 compatibility), and the project's Svelte v5 base. Before attempting to re-implement all UI components from scratch, we will re-evaluate if the latest versions of these libraries have resolved their internal conflicts or if a stable configuration now exists.
|
||||
|
||||
**Phase 1: Re-evaluate SkeletonLabs Compatibility (Primary Focus)**
|
||||
|
||||
**Rationale:** Skeleton UI appears to be the most deeply integrated UI library in the project. If it can be made to work, it will significantly reduce the need for custom component development.
|
||||
|
||||
1. **Update `GEMINI.md` and related notes:** (Completed in this step) Document this new strategy and the decision to re-evaluate packages.
|
||||
2. **Create a new Git branch:** Name it `feature/re_evaluate_ui_libs`. (Pending)
|
||||
3. **Identify latest compatible `@skeletonlabs/skeleton` and `skeleton-svelte` versions:**
|
||||
* Consult their official documentation, release notes, and GitHub issues for compatibility with **Svelte v5** and **Tailwind CSS v4**.
|
||||
* Determine if there's a specific version range that is known to work.
|
||||
4. **Attempt to update SkeletonLabs packages (one at a time, or as a pair if tightly coupled):**
|
||||
* Modify `package.json` to specify the identified compatible versions of `@skeletonlabs/skeleton` and `@skeletonlabs/skeleton-svelte`.
|
||||
* Run `npm install`.
|
||||
* Run `npm run build` and `npm run dev`.
|
||||
* **Crucially:** Thoroughly check for *all* types of errors:
|
||||
* Terminal errors (build, compilation, server-side).
|
||||
* Browser console errors (client-side JS, hydration).
|
||||
* Visual regressions or missing styles.
|
||||
* **Document findings:** Note down exact errors or success status.
|
||||
5. **If successful:** If SkeletonLabs works without major issues, proceed to Phase 2.
|
||||
6. **If unsuccessful:** If significant conflicts or errors persist, revert changes on the branch and document the specific incompatibilities. This would then lead to immediately pursuing custom UI component implementation.
|
||||
|
||||
**Phase 2: Address Other UI Library Needs (Conditional, based on Phase 1 outcome)**
|
||||
|
||||
1. **If SkeletonLabs is working:**
|
||||
* Re-evaluate the need for `flowbite-svelte`. Is its functionality still required, or is it covered by Skeleton UI or can be easily done with pure Tailwind?
|
||||
* If still needed, attempt to update `flowbite-svelte` to the latest version, following the same cautious approach as with SkeletonLabs (package.json update, `npm install`, full testing).
|
||||
2. **If SkeletonLabs (and/or Flowbite) cannot be made to work with Svelte v5 / Tailwind v4:**
|
||||
* **Prioritize Custom Component Implementation:** Immediately proceed with implementing custom replacements, starting with critical components. The `element_modal_v1.svelte` (which was partially developed before the rollback) is a prime candidate for immediate completion and integration.
|
||||
* **Identify other critical missing UI components:** Systematically list other essential components (e.g., dropdowns, tabs, accordions, cards, forms elements) that were previously provided by these libraries and prioritize their custom implementation using pure Tailwind CSS and native Svelte. Consider headless UI libraries (e.g., Headless UI, Radix UI) for complex components where accessibility and functionality are key without dictating styling.
|
||||
|
||||
## User Request Confirmation
|
||||
|
||||
- **Incompatibility of essential packages:** Confirmed. `flowbite-svelte` and `skeletonlabs/skeleton` were incompatible with Svelte v5 / Tailwind v4 in our previous attempts. We *will* safely double-check this as part of Phase 1 and 2.
|
||||
- **CSS and missing style issues:** Confirmed. This was the direct consequence of removing the UI libraries.
|
||||
- **`<Modal>` component replacement:** Confirmed. This was our immediate focus for custom replacement.
|
||||
|
||||
**The immediate next steps are to update my internal `GEMINI.md` for this project with this new plan and create the `feature/re_evaluate_ui_libs` branch.**
|
||||
137
documentation/history/OLD__README__Guidelines_UI_UX.md
Normal file
137
documentation/history/OLD__README__Guidelines_UI_UX.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# AE UI Components, Layout, and Style Standards (HTML/CSS)
|
||||
|
||||
## Aether Components
|
||||
|
||||
### System Components
|
||||
|
||||
- [header]
|
||||
- [main/module]s
|
||||
- [footer]
|
||||
- [app] refresh, clear IDB, clear local storage (settings), iframe toggle (also updates URL param), copy URL, generate and show QR
|
||||
- [menu][mode] edit, more (all or details)
|
||||
- [menu][access_type] passcode input, clear
|
||||
- [menu][user] sign in/out, reset password, email link, change username and email
|
||||
- [menu][theme] mode (light/dark), name (theme list)
|
||||
- [debug] toggle (also updates URL param), show core and module storages, manually set init timestamp
|
||||
- [scroll_to] top, page up, page down, bottom
|
||||
|
||||
### Core Components
|
||||
|
||||
- [copy_btn] clipboard, bind:value, btn_text, btn_html
|
||||
- [txt_editor] textarea
|
||||
- [md_editor] CodeMirror, ShadEditor TipTap (need to remove)
|
||||
- [html_editor]
|
||||
- [media_player]
|
||||
- hosted_file archive_content media_player,
|
||||
- bind:host_id,
|
||||
- bind:media_type
|
||||
- status - stopped, paused, playing
|
||||
- [hosted_file_li] manage_hosted_file_li, make available for selection
|
||||
- [hosted_file_link_to] list links per object, bind:add link, bind:remove link
|
||||
- [upload_to_host] - input_hosted_file; needs to handle multiple files
|
||||
- link_type,
|
||||
- link_id,
|
||||
- inner fragment - label html
|
||||
- bind:trigger
|
||||
- bind:show_spinner
|
||||
- bind:show_percent
|
||||
- status
|
||||
- result - started, uploading, finished
|
||||
- [upload_file_tbl] input_hosted_file_tbl, check for dup file hash, remove from list
|
||||
- [download_from_host]
|
||||
- bind:host_file_id
|
||||
- bind:filename
|
||||
- bind:file_ext
|
||||
- btn inner fragment
|
||||
- bind:trigger
|
||||
- bind:show_spinner
|
||||
- bind:show_percent
|
||||
- status
|
||||
- result - started, downloading, finished
|
||||
- [data_store]
|
||||
- [ae_crud] need to simplify! obj, prop, current_value, bind:value, bind:trigger, inner fragment
|
||||
- [ae_obj_prop_val] - essentially a wrapper for the function
|
||||
- bind:obj_type
|
||||
- bind:obj_id
|
||||
- bind:obj_prop
|
||||
- bind:obj_value
|
||||
- bind:obj_new_value
|
||||
- bind:trigger
|
||||
- bind:show_spinner
|
||||
- bind:show_percent
|
||||
- status
|
||||
- result
|
||||
- [sql_qry]
|
||||
- [obj_tbl] obj sql results tbl or similar
|
||||
- [qr_scanner]
|
||||
- [websocket]
|
||||
|
||||
### Main / Module Components
|
||||
|
||||
- [menu][options] various settings, show/hide content and options, limit, sorting options, etc
|
||||
- [menu][actions] various actions, sign in/out, email
|
||||
|
||||
### Object Menu
|
||||
|
||||
- properties: id, name, group, priority, sort, alert, hide, enable, note
|
||||
- future properties: ext_id (not ready yet), ext_sys_id (not ready yet), code (not ready yet)
|
||||
- actions: create, view, edit, update, hide, disable, delete, alert (message), archive (not ready yet)
|
||||
- future actions: copy, import
|
||||
- sort options:
|
||||
- [default] group > priority > sort (ASC/DESC) > alert > name
|
||||
- [sort_updated] group > priority > sort (ASC/DESC) > alert > updated_on > created_on
|
||||
- [priority_updated] group > priority > updated_on (ASC/DESC) > created_on
|
||||
- [priority_name] group > priority > name (ASC/DESC) > sort > alert > updated_on > created_on
|
||||
- [name] priority > name (ASC/DESC) > sort > alert > updated_on > created_on
|
||||
- [created_on] priority > created_on (ASC/DESC)
|
||||
- [updated_on] priority > updated_on (ASC/DESC) > created_on
|
||||
|
||||
### Pop-ups:
|
||||
|
||||
- modal_header
|
||||
- title
|
||||
- close
|
||||
- modal_main
|
||||
- modal_meta
|
||||
- modal_footer
|
||||
- close
|
||||
|
||||
#### Pop-up Modal (blocking)
|
||||
|
||||
- modal position
|
||||
|
||||
#### Pop-up Modal Inline
|
||||
|
||||
- inline, inline-block, block
|
||||
|
||||
#### Pop-up Dialog
|
||||
|
||||
- dialog position
|
||||
|
||||
## Containers
|
||||
|
||||
### Navigation
|
||||
|
||||
- link
|
||||
- download
|
||||
|
||||
### Forms
|
||||
|
||||
- save
|
||||
- clear value
|
||||
- set null value
|
||||
|
||||
### Other Containers
|
||||
|
||||
- help - blue
|
||||
- info - blue
|
||||
- alert - yellow
|
||||
- warning - orange
|
||||
- error - red
|
||||
- message - green
|
||||
|
||||
---
|
||||
|
||||
## Need to organize:
|
||||
|
||||
- lu: id, account_id, for_obj_id, code, name, description, group, sort, priority, enable, perm_level
|
||||
80
documentation/history/OLD__README__Guidelines_v1.md
Normal file
80
documentation/history/OLD__README__Guidelines_v1.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# One Sky IT's Aether App - UI and UX Guidelines and Rules
|
||||
|
||||
## General
|
||||
|
||||
### Events
|
||||
|
||||
#### layout header
|
||||
|
||||
#### layout footer
|
||||
|
||||
### Journals
|
||||
|
||||
#### buttons
|
||||
|
||||
##### alert
|
||||
|
||||
##### info
|
||||
|
||||
##### priority, flag
|
||||
|
||||
##### warning, hide
|
||||
|
||||
```css
|
||||
variant-soft-warning hover:variant-filled-warning
|
||||
```
|
||||
|
||||
##### error, delete, disable
|
||||
|
||||
```css
|
||||
variant-soft-error hover:variant-filled-error
|
||||
```
|
||||
|
||||
#### new root layout header
|
||||
|
||||
#### submenu
|
||||
|
||||
```css
|
||||
flex flex-row items-center justify-center gap-1
|
||||
```
|
||||
|
||||
#### new layout footer
|
||||
|
||||
## Svelte 5 and SvelteKit v2 (framework and routing)
|
||||
|
||||
## Tailwind 3.x CSS (styles)
|
||||
|
||||
Waiting to upgrade to 4.x when ShadCN is ready. ShadCN is still being worked on as of late March 2025.
|
||||
|
||||
- https://ui.shadcn.com/docs/tailwind-v4
|
||||
|
||||
## CodeMirror 6.x (text and code editor)
|
||||
|
||||
- https://codemirror.net
|
||||
|
||||
## ShadCN (Tailwind Components)
|
||||
|
||||
- https://ui.shadcn.com/docs
|
||||
- https://github.com/shadcn-ui/ui
|
||||
|
||||
## Skeleton (Design System, Tailwind Components, Functional Components)
|
||||
|
||||
Waiting to upgrade to Skeleton v3. Mostly because of the Tailwind 4.x upgrade needed for ShadCN.
|
||||
|
||||
- https://www.skeleton.dev/docs/get-started/migrate-from-v2
|
||||
|
||||
## Flowbite (Tailwind Components)
|
||||
|
||||
## Lucide Icons (SVG Icons)
|
||||
|
||||
- https://lucide.dev/icons/
|
||||
|
||||
## Markdown
|
||||
|
||||
Using marked for Markdown parsing.
|
||||
|
||||
- https://marked.js.org/
|
||||
|
||||
## Edra (TipTap based Rich Text Editor)
|
||||
|
||||
- https://edra.tsuzat.com/
|
||||
173
documentation/history/OLD__README__Guidelines_v2.md
Normal file
173
documentation/history/OLD__README__Guidelines_v2.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# AE Svelte and SvelteKit Technical Standards
|
||||
|
||||
## Official Modules
|
||||
|
||||
### Core
|
||||
|
||||
- Accounts - Minimal
|
||||
- Files
|
||||
- People - Minimal
|
||||
- Sites - Minimal
|
||||
- Users - Minimal
|
||||
|
||||
### Extended
|
||||
|
||||
Archives - Minimal, Events - Badges, Events - Presentation Management, Posts - Minimal, Journals
|
||||
|
||||
### Custom
|
||||
|
||||
IDAA - Archives, IDAA - BB, IDAA - Recovery Meetings
|
||||
|
||||
---
|
||||
|
||||
## localStorage:
|
||||
|
||||
- api
|
||||
- app - global
|
||||
- core - core modules
|
||||
- [module] - extended modules
|
||||
- [custom] - custom modules
|
||||
|
||||
---
|
||||
|
||||
## Indexed DB
|
||||
|
||||
- ae_core_db
|
||||
- [module]
|
||||
- [custom] - custom modules: none currently
|
||||
|
||||
---
|
||||
|
||||
## Data Sorting
|
||||
|
||||
- group > priority > sort > updated/created on
|
||||
- type > start date/time > code or name
|
||||
|
||||
---
|
||||
|
||||
## Objects
|
||||
|
||||
### Function - Obj Prop Update
|
||||
|
||||
- obj_type
|
||||
- obj_id
|
||||
- obj_prop
|
||||
- obj_value
|
||||
|
||||
### Core
|
||||
|
||||
### Extended
|
||||
|
||||
### Custom
|
||||
|
||||
---
|
||||
|
||||
## Object Properties or Fields
|
||||
|
||||
### Core
|
||||
|
||||
Expected standard field names: id, id_random, [obj-type]\_id_random, code, name, enable, hide, priority, sort, group, notes, created_on, updated_on
|
||||
Special use field names: for_type, for_id, archive_on, passcode, external_id
|
||||
|
||||
### Configs and Fields with JSON
|
||||
|
||||
- cfg_json
|
||||
- data_json
|
||||
- linked_li_json
|
||||
|
||||
### Special Generated Fields
|
||||
|
||||
tmp_sort_1, tmp_sort_2,
|
||||
|
||||
### Future standard fields!!!
|
||||
|
||||
obj_id?: null|string;
|
||||
obj_ext_uid?: null|string; // Probably not needed for journals
|
||||
obj_ext_id?: null|string; // Probably not needed for journals
|
||||
obj_import_id?: null|string; // Probably not needed for journals
|
||||
obj_code?: null|string;
|
||||
obj_account_id?: null|string;
|
||||
obj_passcode?: null|string;
|
||||
obj_type?: null|string; // Should always be 'journal' in this case
|
||||
obj_type_ver_id?: null|string; // The ID from the table for the object type
|
||||
obj_name?: null|string;
|
||||
obj_summary?: null|string; // LLM (AI) generated summary...???
|
||||
obj_outline?: null|string; // LLM (AI) generated outline...???
|
||||
obj_description?: null|string; // Probably not needed for journals
|
||||
obj_enable?: null|boolean;
|
||||
obj_enable_on?: null|Date;
|
||||
obj_archive_on?: null|Date;
|
||||
obj_hide?: null|boolean;
|
||||
obj_priority?: null|number;
|
||||
obj_sort?: null|number;
|
||||
obj_group?: null|string;
|
||||
obj_cfg_json?: null|string;
|
||||
obj_notes?: null|string;
|
||||
obj_created_on?: Date;
|
||||
obj_updated_on?: null|Date;
|
||||
|
||||
## Dixie IDB liveQuery with Select Objects (slct) and Lists of Objects (slct_x_li)
|
||||
|
||||
Use this method below to create a read/write snapshot of the current liveQuery results. This allows you to use it as part of a form and binding values. It might make since to call this something like "lqw**x_obj" and "lqw**x_obj_li". lqw = liveQuery writable
|
||||
|
||||
lq**xyz_obj - Use for general read only
|
||||
lqw**xyz_obj - Use for forms and binding values. What happens if the actual LQ obj is updated after the bind?
|
||||
$slct or $lqw ?
|
||||
|
||||
Sort of related.... more permission/security though: Create a new table that will be attached to every v\_ view in the DB. This new table would be a field permission list. It could work similar to the data_store table and related view. This seems like a good idea????? 2025-08-11
|
||||
|
||||
```ts
|
||||
let lq__post_obj = $derived(
|
||||
liveQuery(async () => {
|
||||
if (log_lvl) {
|
||||
console.log(`lq__post_obj: post_id = ${$idaa_slct?.post_id}`);
|
||||
}
|
||||
let results = await db_posts.post.get($idaa_slct.post_id ?? ''); // null or undefined does not reset things like '' does
|
||||
|
||||
// Check if results are different than the current $idaa_slct.post_obj
|
||||
if ($idaa_slct.post_obj && results) {
|
||||
if (JSON.stringify($idaa_slct.post_obj) !== JSON.stringify(results)) {
|
||||
$idaa_slct.post_obj = { ...results };
|
||||
if (log_lvl) {
|
||||
console.log(`$idaa_slct.post_obj = `, $idaa_slct.post_obj);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl) {
|
||||
console.log(`Post object has not changed for post_id: ${$idaa_slct.post_id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
})
|
||||
);
|
||||
|
||||
let lq__post_comment_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
let results = await db_posts.comment
|
||||
.where('post_id')
|
||||
.equals($idaa_slct.post_id ?? '') // null or undefined does not reset things like '' does
|
||||
.reverse()
|
||||
.sortBy('updated_on');
|
||||
// .sortBy('title');
|
||||
|
||||
if (
|
||||
$idaa_slct.post_comment_obj_li &&
|
||||
JSON.stringify($idaa_slct.post_comment_obj_li) !== JSON.stringify(results)
|
||||
) {
|
||||
$idaa_slct.post_comment_obj_li = [...results];
|
||||
if (log_lvl) {
|
||||
console.log(`$idaa_slct.post_comment_obj_li = `, $idaa_slct.post_comment_obj_li);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Post comment object list has not changed for post_id: ${$idaa_slct.post_id}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
})
|
||||
);
|
||||
```
|
||||
187
documentation/history/REVIEW__AE_Svelte5_performance.md
Normal file
187
documentation/history/REVIEW__AE_Svelte5_performance.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# Aether Svelte 5 App — Performance Review
|
||||
|
||||
Date: 2026-01-26
|
||||
|
||||
This document collects findings from a quick code review of the Aether Svelte 5 app (focused on `src/routes/+layout.svelte`, `src/routes/+page.svelte`, and the events launcher layout). It lists concrete performance issues observed, their likely impact, remediation recommendations (quick wins first), code examples for safe refactors, measurement steps, and a prioritized action plan.
|
||||
|
||||
**Scope**
|
||||
- Files inspected: `src/routes/+layout.svelte`, `src/routes/+page.svelte`, event launcher `+layout.svelte` and related store initialization logic.
|
||||
- Platform: SvelteKit with Vite (assumed from repo files). Builds use Tailwind CSS and manual global CSS.
|
||||
|
||||
---
|
||||
|
||||
## Summary of Key Findings
|
||||
|
||||
- Large synchronous imports at module evaluation time (notably `highlight.js` and its stylesheet) increase initial bundle size and run before first paint.
|
||||
- Many components and icon imports are static at top-level even when rendered conditionally (`Analytics`, `MyClipboard`, `E_app_debug_menu`, `E_app_sys_menu`, multiple Lucide icons). This inflates the client bundle.
|
||||
- Significant initialization and cache logic runs synchronously during module evaluation: store writes, cache expiration checks, IndexedDB operations, localStorage population, calls to `invalidateAll()` and conditional `window.location.reload()` paths — these can block initial render and cause reload loops or extra round trips.
|
||||
- Dexie `liveQuery` usages in nested layouts are eager and may execute multiple DB queries on route entry, causing CPU and I/O work up-front.
|
||||
- Multiple synchronous CSS imports (global CSS + highlight CSS) can delay first paint and increase transfer size.
|
||||
- Many localStorage/sessionStorage writes and store updates are done immediately and synchronously; iterating many keys on startup can stall the main thread.
|
||||
- Analytics, WebSocket connections, and external network resource usage may be triggered too early.
|
||||
|
||||
Impact: Slow Time to First Paint (TTFP), increased Time to Interactive (TTI), larger JS bundles, higher CPU main-thread blocking, worse Lighthouse/perceived performance.
|
||||
|
||||
---
|
||||
|
||||
## Concrete, Prioritized Recommendations
|
||||
|
||||
Priority ordering: Quick wins (low code risk) → Short-term (moderate refactor) → Long-term (architectural).
|
||||
|
||||
### Quick Wins (apply first)
|
||||
- Lazy-load `highlight.js` and its CSS in `onMount` only when highlighting is needed. This removes a heavy library and stylesheet from the initial bundle.
|
||||
- Dynamically import non-critical components (`Analytics`, debug menus, clipboard UI, large icon modules) when they will actually render.
|
||||
- Move non-UI, non-blocking initialization to `onMount` and/or `requestIdleCallback` so SSR rendering and first paint aren't blocked by client-only logic.
|
||||
- Guard `invalidateAll()` / `window.location.reload()` so they run only after a user-visible prompt or on explicit action; avoid automatic reload on subtle mismatches.
|
||||
|
||||
### Short-Term Changes (next 1–2 days)
|
||||
- Defer expensive Dexie `liveQuery` and database queries until their containing route/section mounts, or add limits/pagination to reduce initial query size.
|
||||
- Batch localStorage writes (use a single write or `requestIdleCallback`/`setTimeout(…,0)`), or store a single object rather than many keys.
|
||||
- Replace heavy icon imports with an icon-on-demand strategy (SVG sprite, `unplugin-icons`, or inlining only icons used on first paint).
|
||||
- Lazy-load large CSS (e.g., highlight theme) with dynamic import or by adding/removing link elements.
|
||||
|
||||
### Long-Term / Architectural
|
||||
- Split routes to ensure route-level code-splitting is effective — verify that `+layout` doesn't import many route-specific modules. Keep `+layout.svelte` as thin as possible.
|
||||
- Use a bundle analyzer to identify largest modules and tune dependencies.
|
||||
- Serve production build with proper HTTP caching, compression (Brotli), and HTTP/2 or HTTP/3.
|
||||
- Consider server-side rendering vs. partial hydration boundaries (islands) for heavy interactive regions.
|
||||
|
||||
---
|
||||
|
||||
## Concrete Code Examples
|
||||
|
||||
These are safe, copy-pasteable snippets for common quick fixes.
|
||||
|
||||
1) Lazy-load `highlight.js` in `src/routes/+layout.svelte` (move work to `onMount`):
|
||||
|
||||
```svelte
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
let hljs: any;
|
||||
onMount(async () => {
|
||||
const mod = await import('highlight.js/lib/core');
|
||||
hljs = mod.default || mod;
|
||||
// register languages lazily
|
||||
const xml = (await import('highlight.js/lib/languages/xml')).default;
|
||||
const css = (await import('highlight.js/lib/languages/css')).default;
|
||||
const js = (await import('highlight.js/lib/languages/javascript')).default;
|
||||
const ts = (await import('highlight.js/lib/languages/typescript')).default;
|
||||
hljs.registerLanguage('xml', xml);
|
||||
hljs.registerLanguage('css', css);
|
||||
hljs.registerLanguage('javascript', js);
|
||||
hljs.registerLanguage('typescript', ts);
|
||||
// load stylesheet dynamically if needed
|
||||
await import('highlight.js/styles/github-dark.css');
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
2) Dynamic component import for `Analytics`:
|
||||
|
||||
```svelte
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
let Analytics: any = null;
|
||||
let showAnalytics = false;
|
||||
|
||||
onMount(async () => {
|
||||
if (/* condition to show analytics, or simply true after idle */) {
|
||||
const mod = await import('$lib/app_components/analytics.svelte');
|
||||
Analytics = mod.default;
|
||||
showAnalytics = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if showAnalytics && Analytics}
|
||||
<svelte:component this={Analytics} bind:site_google_tracking_id={$ae_loc.site_google_tracking_id} />
|
||||
{/if}
|
||||
```
|
||||
|
||||
3) Batch localStorage writes using `requestIdleCallback` fallback:
|
||||
|
||||
```ts
|
||||
function batchSetLocalStorage(obj: Record<string, any>) {
|
||||
const work = () => {
|
||||
for (const [k, v] of Object.entries(obj)) {
|
||||
try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {}
|
||||
}
|
||||
};
|
||||
if ('requestIdleCallback' in window) {
|
||||
(window as any).requestIdleCallback(work);
|
||||
} else {
|
||||
setTimeout(work, 0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4) Avoid automatic reloads — example guard:
|
||||
|
||||
```ts
|
||||
// Only force reload after user consent or if critical mismatch
|
||||
if (flag_reload) {
|
||||
const reloadKey = 'aether_reload_shown_v' + ($ae_loc?.ver ?? 'unknown');
|
||||
if (!localStorage.getItem(reloadKey)) {
|
||||
if (confirm('A new version is available. Reload now?')) {
|
||||
localStorage.setItem(reloadKey, '1');
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Measurement & Tooling
|
||||
|
||||
Run these locally to find concrete hotspots and bundle contributors.
|
||||
|
||||
- Bundle analysis (Vite):
|
||||
|
||||
```bash
|
||||
# Build and open analyzer (if plugin configured)
|
||||
npm run build
|
||||
npx vite build --sourcemap
|
||||
# Use source-map-explorer or webpack-bundle-analyzer (adapt if using Rollup)
|
||||
npx source-map-explorer dist/assets/*.js
|
||||
```
|
||||
|
||||
- Vite visualizer (install `rollup-plugin-visualizer` or `vite-plugin-visualizer`):
|
||||
|
||||
```bash
|
||||
# add plugin and run build with report
|
||||
# then open .html output from the plugin
|
||||
```
|
||||
|
||||
- Lighthouse / DevTools:
|
||||
- Run Lighthouse (Performance, TTI, Largest Contentful Paint, Main thread) in Chrome.
|
||||
- In Performance panel record page load to find long main-thread tasks (JS parsing/execution) and identify blocking code paths.
|
||||
|
||||
- Runtime marks: add `performance.mark('init-start')` / `performance.mark('init-end')` to measure areas (e.g., store population, Dexie queries) then `performance.measure()`.
|
||||
|
||||
---
|
||||
|
||||
## Prioritized Action Plan (Checklist)
|
||||
|
||||
- [ ] Move `highlight.js` imports and theme stylesheet to `onMount` (quick win).
|
||||
- [ ] Convert `Analytics` and other developer tools to dynamic imports (quick win).
|
||||
- [ ] Move non-critical store population, IndexedDB maintenance, and cache-expiration logic to `onMount` or `requestIdleCallback`.
|
||||
- [ ] Add guard & confirmation around `invalidateAll()` and `location.reload()` to avoid reload loops.
|
||||
- [ ] Defer Dexie `liveQuery` initialization to the route or component that needs it (avoid running all live queries globally).
|
||||
- [ ] Batch localStorage writes and avoid iterating thousands of keys synchronously.
|
||||
- [ ] Run bundle analysis and produce a top-10 biggest modules list.
|
||||
- [ ] Replace heavy icon imports with icon-on-demand solution.
|
||||
- [ ] Re-run Lighthouse and validate improvements.
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Quick Checklist for PRs
|
||||
|
||||
- Ensure client-only code is inside `onMount` or guarded by `if (browser)`.
|
||||
- Where dynamic import used, use `<svelte:component this={Comp} />` pattern.
|
||||
- Add performance marks around expensive blocks and log durations in dev mode.
|
||||
- Avoid unconditional network or socket connections in top-level layout; open them after user interaction or when component mounts.
|
||||
|
||||
---
|
||||
|
||||
If you want, I can implement the first quick wins now: lazy-load `highlight.js` and convert `Analytics` import in `src/routes/+layout.svelte`, then run a local bundle analysis. Tell me which of the quick wins you'd like me to patch first and I'll start.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Session Report: V3 API Hardening & Stabilization (2026-01-19)
|
||||
|
||||
## 👤 User / Context
|
||||
- **Developer:** Scott Idem
|
||||
- **Date:** Monday, January 19, 2026
|
||||
- **Objective:** Stabilize V3 API helpers, resolve 403 race conditions, and fix IDAA module crashes.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 1. Completed & Committed Work
|
||||
|
||||
### **A. Core API Helpers (GET/POST/PATCH)**
|
||||
- **Structured Error Handling:** Updated helpers to extract and return rich metadata (`meta.details`) from V3 API 400/500 responses. This allows for specific debugging (e.g., "Unknown column") instead of generic HTTP codes.
|
||||
- **Immediate JWT Injection:** Refactored `+layout.ts` to read the JWT directly from `localStorage` during bootstrap. This ensures the first requests of a page load are correctly authenticated, solving race conditions.
|
||||
- **Hardened Bypass Logic:** Refined the "Bootstrap Paradox" logic to strictly check for valid values (e.g., `bypass`). Placeholder environment variables are now proactively stripped so they don't interfere with account context.
|
||||
- **Fail-Fast Protocol:** Added `400` and `422` to the Fail-Fast list to prevent unnecessary retries on invalid requests or schema violations.
|
||||
- **JWT Fallback:** Implemented a direct `localStorage` check for the `ae_loc` key as a final resort in the helpers if the Svelte stores haven't synchronized yet.
|
||||
|
||||
### **B. Module Fixes**
|
||||
- **Archives Stability:** Resolved a critical async race condition in `load_ae_obj_li__archive` that caused a `TypeError` when loading nested content before the primary promise resolved.
|
||||
- **Generic Processor Hardening:** Updated `_process_generic_props` to robustly handle non-array API responses, preventing "obj_li is not iterable" crashes.
|
||||
- **Event Search Logic:** Refactored `qry_ae_obj_li__event` to use raw `account_id_random` in the search body to attempt bypassing backend ID-mapping conflicts.
|
||||
|
||||
### **C. Testing & Diagnostics**
|
||||
- **Enhanced Dashboard:** Updated `/testing` with a "Live V3 Header Inspection" tool.
|
||||
- **Hardening Audits:** Added automated tests for **Permissive Mode** (x-ae-ignore-extra-fields) and **Structured Error** extraction.
|
||||
|
||||
---
|
||||
|
||||
## 🚧 2. The Current Blocker: Zero-Result Search
|
||||
|
||||
The `event/search` endpoint for IDAA Recovery Meetings is consistently returning `200 OK` with `data: []` or intermittent `403 Forbidden`.
|
||||
|
||||
### **Failed Attempts / Observations:**
|
||||
- **Raw ID Bypass:** Sending `account_id_random` directly in the body did not restore the listings.
|
||||
- **Hybrid Filtering:** Moving `physical`, `virtual`, and `conference` filters to the client side resolved 400 errors but resulted in empty lists.
|
||||
- **Header Diagnostics:** Confirmed that `x-account-id` and `x-aether-api-key` are present, but `Authorization` is occasionally marked as `MISSING` in the very first bootstrap trace.
|
||||
|
||||
---
|
||||
|
||||
## 🧠 3. Best Guesses for Root Cause
|
||||
|
||||
1. **The "Integer Trap":** FastAPI logs show the backend is mapping the account context to an integer (`{'account_id': 13}`). If the backend search logic compares this integer to a string column in a view, the query returns zero rows.
|
||||
2. **Mapping Conflict:** Injecting `account_id_random` in the search body while the backend automatically injects its own isolation may be creating conflicting `WHERE` clauses.
|
||||
3. **Whitelisting/Permissions:** The "Authentication required" 403 on search suggests the backend might be rejecting the combination of search fields for the `event` object specifically, or the user's JWT permissions for that object aren't being resolved correctly.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 4. Plan for Tomorrow
|
||||
|
||||
1. **CURL Trace:** Execute raw CURL requests with the payloads captured today to see the raw backend traceback (bypassing CORS masking).
|
||||
2. **Backend Audit:** Check the `v_event` view and `mdl_search` Pydantic model in the API for strict type constraints on the `account_id` field.
|
||||
3. **Filter Re-alignment:** Once backend search whitelisting is confirmed, test reverting to the standard `for_obj_type: 'account'` pattern.
|
||||
4. **JWT Verification:** Confirm if the JWT provided in `ae_loc` is correctly scoped for the `event` object search.
|
||||
|
||||
---
|
||||
**Status:** API helpers are solid; store sync is stable. Issue is narrowed to SQL/Filter logic for V3 Event Search.
|
||||
236
documentation/history/V3_FRONTEND_API_GUIDE.md
Normal file
236
documentation/history/V3_FRONTEND_API_GUIDE.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# Aether API V3 Frontend Integration Guide (Svelte/TypeScript)
|
||||
|
||||
This guide explains how to update or create frontend functions to interact with the new **Aether API V3 CRUD** endpoints. V3 introduces a nested URL structure, a powerful POST-based search, and improved performance.
|
||||
|
||||
---
|
||||
|
||||
## 1. Key Differences (V2 vs V3)
|
||||
|
||||
| Feature | CRUD V2 (Legacy) | CRUD V3 (Modern) |
|
||||
| --- | --- | --- |
|
||||
| **Base Prefix** | `/v2/crud` | `/v3/crud` |
|
||||
| **List Suffix** | Uses `/list` | **No suffix** (e.g., `/v3/crud/journal/`) |
|
||||
| **Nested Path** | Not supported in URL | **Supported** (e.g., `/v3/crud/journal/{id}/journal_entry/`) |
|
||||
| **View Selection**| `tbl_alt`, `mdl_alt` | **`view` parameter** (e.g., `?view=enriched`) |
|
||||
| **Complex Search**| Limited to GET `jp` | **POST `/search`** (Unlimited size + Hybrid params) |
|
||||
| **Full-Text Search**| Manual column names | **Reserved `q` property** in SearchQuery |
|
||||
|
||||
---
|
||||
|
||||
## 2. Authentication and Security (Mandatory in V3)
|
||||
|
||||
As of January 2026, the V3 architecture enforces strict **Multi-Tenant Isolation**. Most requests now require valid authentication to prevent data leakage between accounts.
|
||||
|
||||
### A. Authentication Requirement
|
||||
Almost all V3 CRUD endpoints require a standard Bearer token in the `Authorization` header.
|
||||
|
||||
* **Mandatory:** You must provide a valid JWT for nearly all requests.
|
||||
* **Account Isolation:** The backend automatically filters all results based on the `account_id` found in your JWT. You cannot access data belonging to another account even if you know the random ID.
|
||||
* **Status Codes:**
|
||||
* `401 Unauthorized`: Your JWT is invalid or expired.
|
||||
* `403 Forbidden`: No authentication provided, or you attempted to access an object belonging to a different account.
|
||||
|
||||
**Example Request Header:**
|
||||
```http
|
||||
Authorization: Bearer <your_jwt_token>
|
||||
```
|
||||
|
||||
### B. The "Bootstrap Paradox" Exception (`site_domain`)
|
||||
There is one critical exception to strict authentication: **`site_domain` search**.
|
||||
|
||||
Because the frontend needs to lookup the site configuration (to know which account it's on) *before* a user can log in, the following endpoint allows unauthenticated (guest) access:
|
||||
|
||||
**Endpoint:** `POST /v3/crud/site_domain/search`
|
||||
|
||||
This is the only V3 search allowed without a JWT. All other object types (journal, account, post, etc.) will return `403 Forbidden` if accessed without a token.
|
||||
|
||||
---
|
||||
|
||||
## 3. Implementing V3 CRUD Functions
|
||||
|
||||
### A. List & Single Object (GET)
|
||||
Support for view selection allows fetching richer data models when needed.
|
||||
|
||||
```ts
|
||||
// Example: Get enriched journal details
|
||||
// GET /v3/crud/journal/{id}?view=enriched
|
||||
export async function get_ae_obj_v3({ api_cfg, obj_type, obj_id, view = 'default' }) {
|
||||
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
|
||||
return await get_object({ api_cfg, endpoint, params: { view } });
|
||||
}
|
||||
```
|
||||
|
||||
### B. Advanced & Hybrid Search (POST)
|
||||
The `/search` endpoint combines the power of complex logical bodies with the simplicity of query parameters.
|
||||
|
||||
```ts
|
||||
export async function search_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type,
|
||||
search_query, // { q: "search term", and: [...] }
|
||||
enabled = 'enabled',
|
||||
view = 'default',
|
||||
for_obj_type,
|
||||
for_obj_id
|
||||
}) {
|
||||
const endpoint = `/v3/crud/${obj_type}/search`;
|
||||
|
||||
// Standard filters can be passed as query params
|
||||
const params: any = { enabled, view };
|
||||
if (for_obj_type) params.for_obj_type = for_obj_type;
|
||||
if (for_obj_id) params.for_obj_id = for_obj_id;
|
||||
|
||||
return await post_object({
|
||||
api_cfg,
|
||||
endpoint,
|
||||
params,
|
||||
data: search_query
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### C. Standardized Global Search (`q`)
|
||||
Use the `q` property in your search body for a keyword search.
|
||||
- **Wildcard Support**: Setting `q: "%"` will bypass all text filtering and return all records (respecting only logical filters like `enable`).
|
||||
- **Fallback**: If the table lacks a `default_qry_str` column, the API automatically performs a `LIKE` search across all searchable fields.
|
||||
|
||||
```json
|
||||
{
|
||||
"q": "Annual Meeting",
|
||||
"and": [{ "field": "enable", "op": "eq", "value": true }]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Create, Update, & Delete (POST, PATCH, DELETE)
|
||||
|
||||
V3 supports both top-level operations and nested parent/child operations.
|
||||
|
||||
### A. Create (POST)
|
||||
When creating objects, V3 strictly validates the incoming JSON against the `mdl_in` Pydantic model.
|
||||
|
||||
```ts
|
||||
// POST /v3/crud/{obj_type}/
|
||||
export async function create_ae_obj_v3({ api_cfg, obj_type, data }) {
|
||||
const endpoint = `/v3/crud/${obj_type}/`;
|
||||
return await post_object({ api_cfg, endpoint, data });
|
||||
}
|
||||
|
||||
// POST /v3/crud/{parent_obj_type}/{parent_obj_id}/{child_obj_type}/
|
||||
// Note: Parent ID is automatically injected into the child record.
|
||||
export async function create_nested_obj_v3({ api_cfg, parent_type, parent_id, child_type, data }) {
|
||||
const endpoint = `/v3/crud/${parent_type}/${parent_id}/${child_type}/`;
|
||||
return await post_object({ api_cfg, endpoint, data });
|
||||
}
|
||||
```
|
||||
|
||||
### B. Update (PATCH)
|
||||
V3 uses `PATCH` for partial updates. Only the fields provided in the body will be modified in the database.
|
||||
|
||||
```ts
|
||||
// PATCH /v3/crud/{obj_type}/{obj_id}
|
||||
export async function update_ae_obj_v3({ api_cfg, obj_type, obj_id, data }) {
|
||||
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
|
||||
return await patch_object({ api_cfg, endpoint, data });
|
||||
}
|
||||
```
|
||||
|
||||
### C. Delete (DELETE)
|
||||
The `DELETE` method is used for removal. The backend may implement soft-delete (hide/disable) depending on the configuration.
|
||||
|
||||
```ts
|
||||
// DELETE /v3/crud/{obj_type}/{obj_id}
|
||||
export async function delete_ae_obj_v3({ api_cfg, obj_type, obj_id }) {
|
||||
const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
|
||||
return await delete_object({ api_cfg, endpoint });
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Specialized & Context Endpoints
|
||||
|
||||
### A. Context Resolution (FQDN)
|
||||
Used during initial load to find the `account_id` associated with the domain.
|
||||
|
||||
**Legacy Method:** `GET /crud/site/domain/{fqdn}?use_alt_table=true&use_alt_base=true`
|
||||
**Modern V3 Method (Preferred):** `POST /v3/crud/site_domain/search` with `{ "q": "your-domain.com" }`
|
||||
|
||||
### B. Schema Discovery
|
||||
**Path**: `GET /v3/crud/{obj_type}/schema`
|
||||
|
||||
Used for developer tools or dynamic UI builders to understand the structure of an AE object.
|
||||
|
||||
```ts
|
||||
// GET /v3/crud/account/schema
|
||||
export async function get_obj_schema_v3({ api_cfg, obj_type }) {
|
||||
const endpoint = `/v3/crud/${obj_type}/schema`;
|
||||
return await get_object({ api_cfg, endpoint });
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Secure File Downloads (URL Parameter)
|
||||
For `hosted_file` and `event_file`, browsers often need to download files without complex header modifications. In these cases, you can pass the JWT directly in the URL.
|
||||
|
||||
```ts
|
||||
// Example: Creating a secure download link for a browser
|
||||
// GET /v3/crud/hosted_file/{id}/?jwt={token}
|
||||
const downloadUrl = `${BASE_URL}/v3/crud/hosted_file/${fileId}/?jwt=${jwtToken}`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Best Practices for V3
|
||||
|
||||
1. **Use `view` for Rich Data**: Instead of manually joining data in separate calls, use `?view=enriched` or `?view=detail`.
|
||||
2. **Singular Nouns**: Always use singular names for `obj_type` (e.g., `journal`).
|
||||
3. **Strict Typing**: Ensure your `data` objects match the backend models to avoid `400 Bad Request` validation errors.
|
||||
|
||||
---
|
||||
|
||||
## 8. Standard Patterns & Common Pitfalls (2026 Update)
|
||||
|
||||
To ensure stability across the Aether mesh, all frontend components must adhere to these established patterns.
|
||||
|
||||
### A. The "Whitelist" Standard for Saves
|
||||
**Problem:** Sending the entire object returned by a `GET` request back to a `PATCH` endpoint will cause a `400 Bad Request`. This happens because the object contains technical metadata (like `journal_id`, `created_on`, `for_type`) that the API cannot "SET".
|
||||
|
||||
**Standard:** When preparing a save payload, explicitly whitelist ONLY the user-editable fields.
|
||||
```typescript
|
||||
// ✅ CORRECT: Whitelist only editable fields
|
||||
const data_kv = {
|
||||
name: tmp_obj.name,
|
||||
content: tmp_obj.content,
|
||||
tags: tmp_obj.tags,
|
||||
category_code: tmp_obj.category_code
|
||||
};
|
||||
|
||||
// ❌ WRONG: Passing the whole object or just blacklisting a few
|
||||
const data_kv = { ...tmp_obj };
|
||||
delete data_kv.id; // Still contains other computed columns!
|
||||
```
|
||||
|
||||
### B. The Triple-ID Save Pattern
|
||||
**Standard:** When sending an ID in a POST/PATCH payload (e.g. creating a child object), use the random string version with the `_id_random` suffix.
|
||||
* **Property:** `[obj_type]_id_random`
|
||||
* **Value:** A string (e.g., `qpgvOh5nOYI`)
|
||||
|
||||
**Warning:** Sending a string value under an integer key (e.g. `journal_id: "qpgvOh5nOYI"`) will trigger a Pydantic validation error on the backend.
|
||||
|
||||
### C. Handle 'NULL' vs '0' for Booleans
|
||||
**Pitfall:** Fields like `hide` or `priority` can be `NULL` in the database.
|
||||
**Standard:** Ensure your synchronization logic in components handles `null`, `undefined`, and `0` identically for boolean checks to prevent "ghost" changes being detected by Svelte 5.
|
||||
|
||||
---
|
||||
|
||||
## 9. Planned API Improvements (2026 Roadmap)
|
||||
|
||||
The following refinements have been requested from the Backend Agent to further improve frontend productivity:
|
||||
|
||||
1. **Permissive Update Mode**: A new header (`x-ae-ignore-extra-fields: true`) is planned to allow the API to ignore non-writable columns in `PATCH` requests instead of returning a `400 Bad Request`.
|
||||
2. **Automated ID Resolution**: Backend will soon support automatic resolution of `_id_random` strings to integer IDs during `POST/PATCH`, reducing the need for manual lookups in the frontend.
|
||||
3. **Schema Evolution Tools**: New orchestration tools are being developed to automate field creation and renaming, including the automatic regeneration of the enriched SQL views.
|
||||
4. **Structured Validation Errors**: Move from string-based error details to a machine-readable format for better inline form validation.
|
||||
Reference in New Issue
Block a user