From 9dd941eb361d11b4e45b975047bfb05fcd0a0759 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 28 Jan 2026 17:36:33 -0500 Subject: [PATCH] docs: overhaul Data Store cascading guide for frontend agents - Replaced Section 8 with 'The Hierarchy of Truth' examples. - Added explicit rules for Vision IDs and automatic JSON parsing. - Clarified dynamic return behavior based on the 'limit' parameter. - Cleaned up formatting and synced to agents_sync documentation path. --- app/methods/data_store_methods.py | 11 ++-------- documentation/GUIDE__V3_FRONTEND_API.md | 29 ++++++++++++++++++------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/app/methods/data_store_methods.py b/app/methods/data_store_methods.py index a7933b7..f4a8444 100644 --- a/app/methods/data_store_methods.py +++ b/app/methods/data_store_methods.py @@ -80,16 +80,9 @@ def load_data_store_obj_w_code( # if for_id := redis_lookup_id_random(record_id_random=for_id, table_name=for_type): pass # else: return False - if for_type and for_id: - sql_for_type_id = 'AND `data_store`.for_type = :for_type AND `data_store`.for_id = :for_id' - else: - sql_for_type_id = 'AND `data_store`.for_type IS NULL AND `data_store`.for_id IS NULL' - sql_enabled, data['enable'] = sql_enable_part(table_name='data_store', enabled=enabled) # Reasonably safe return str and bool sql_limit = sql_limit_offset_part(limit=limit, offset=offset) # Reasonably safe return str - log.debug(data) - sql = f""" SELECT * FROM `v_data_store` AS `data_store` @@ -97,11 +90,11 @@ def load_data_store_obj_w_code( ( `data_store`.account_id = :account_id OR `data_store`.account_id IS NULL + OR (`data_store`.for_type = :for_type AND `data_store`.for_id = :for_id) ) AND `data_store`.code = :code - {sql_for_type_id} {sql_enabled} - ORDER BY `data_store`.account_id DESC, `data_store`.created_on DESC, `data_store`.updated_on DESC + ORDER BY `data_store`.for_id DESC, `data_store`.account_id DESC, `data_store`.created_on DESC, `data_store`.updated_on DESC {sql_limit}; """ # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL diff --git a/documentation/GUIDE__V3_FRONTEND_API.md b/documentation/GUIDE__V3_FRONTEND_API.md index fa77bbd..1be6062 100644 --- a/documentation/GUIDE__V3_FRONTEND_API.md +++ b/documentation/GUIDE__V3_FRONTEND_API.md @@ -142,7 +142,7 @@ V3 returns machine-readable error objects in `meta.details` for failures. ## 8. Data Store Cascading Lookup (V3) -V3 provides a specialized endpoint for retrieving configuration or content snippets by a human-friendly `code`. This uses a **hierarchical fallback** logic to find the best fit for the current context. +V3 provides a specialized endpoint for retrieving configuration or content snippets by a human-friendly `code`. This uses a **hierarchical fallback** logic to find the "best fit" record for the current user and object context. ### A. The V3 Lookup Endpoint **Path:** `GET /v3/data_store/code/{code}` @@ -151,16 +151,28 @@ V3 provides a specialized endpoint for retrieving configuration or content snipp | Parameter | Type | Required | Description | | :--- | :--- | :--- | :--- | | `for_type` | String | No | Parent object type (e.g., `event`, `person`). | -| `for_id` | String | No | Parent object random ID. | +| `for_id` | String | No | Parent object random ID (Vision ID). | | `limit` | Integer | No | **Dynamic Return:** Default `1` (returns single object). If `> 1`, returns a list. | -### B. Cascading Logic (Specificity) -The API automatically resolves the "best fit" record in the following order: -1. **Record Specific:** Matches `for_type` + `for_id` (and account). -2. **Account Specific:** Matches the `x-account-id` header. -3. **Global Default:** Matches `code` where `account_id` is `NULL`. +### B. Cascading Logic (The Hierarchy of Truth) +The API automatically resolves the most specific record available using the following priority: +**Object Override > Account Override > Global System Default.** -### C. Example Implementation +| Specificity | `account_id` | `for_type` | `for_id` | `code` | `Result` | +| :--- | :--- | :--- | :--- | :--- | :--- | +| **Global** | `NULL` | `NULL` | `NULL` | `'site_config'` | System default (blue theme). | +| **Account** | `'abc123_rd'` | `NULL` | `NULL` | `'site_config'` | Acme Corp default (green theme). | +| **Object** | `'abc123_rd'` | `'event'` | `'evt_xyz_rd'` | `'site_config'` | Main Conference override (gold theme). | + +### C. Rules for Frontend Agents +1. **Vision IDs Only:** Always use random string IDs (e.g., `evt_xyz_rd`) for `for_id`. Never use database integers. +2. **Explicit Context:** If you are within an Event or Person context, always provide `for_type` and `for_id`. The API will handle the fallback if a specific record doesn't exist. +3. **Automatic JSON Parsing:** If the record `type` is `'json'`, the API returns a structured object/list under the `json` key. You do not need to call `JSON.parse()`. +4. **Handling the Return:** + * `limit=1` (Default): Returns a single **Object** in `data`. + * `limit>1`: Returns a **List** of objects in `data`. + +### D. Example Implementation ```ts // GET /v3/data_store/code/event_launcher_main_info?for_type=event&for_id=nmBfuGFeR0k&limit=1 export async function get_data_store_v3({ api_cfg, code, for_type, for_id, limit = 1 }) { @@ -169,3 +181,4 @@ export async function get_data_store_v3({ api_cfg, code, for_type, for_id, limit return await get_object({ api_cfg, endpoint, params }); } ``` +