From 98546abe2160f41d9ddfc32f536fb3aaaaff8fb8 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Thu, 30 Apr 2026 21:17:19 -0400 Subject: [PATCH] docs: update ARCH__AE_INTEGRATION with verified API behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - query_string required for and/or filters to apply; use "%" as wildcard - Total count is in meta.data_list_count, not top-level - id_random is None in responses; Vision ID convention uses {obj_type}_id - tags comes back as string on read, not list — normalize before joining - Replace stale "Planned: Search Improvements" with current signature + notes - Clarify date_to boundary (lte midnight, use next day to include full day) Co-Authored-By: Claude Sonnet 4.6 --- documentation/ARCH__AE_INTEGRATION.md | 61 +++++++++++++-------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/documentation/ARCH__AE_INTEGRATION.md b/documentation/ARCH__AE_INTEGRATION.md index d11feb4..f8d1f0d 100644 --- a/documentation/ARCH__AE_INTEGRATION.md +++ b/documentation/ARCH__AE_INTEGRATION.md @@ -1,7 +1,7 @@ # Aether Platform Integration — Cortex Tool Layer > Last updated: 2026-04-30 -> Status: Active development — Journal toolset being expanded +> Status: Journal toolset complete — broader AE integration planned This doc covers how Cortex/Inara integrates with the Aether Platform API, what's implemented, what the data model looks like, and what's planned next. @@ -54,11 +54,14 @@ POST /v3/crud/journal_entry/search } ``` -**`query_string` vs `and_filters` on `default_qry_str`:** +**`query_string` vs `and` filters on `default_qry_str`:** - `query_string` → triggers `MATCH(default_qry_str) AGAINST(... IN BOOLEAN MODE)` — uses the FULLTEXT index. Faster and supports boolean operators (`+word`, `-word`, `"phrase"`). -- `and_filters` with `icontains` on `default_qry_str` → plain `LIKE '%term%'`. Slower, - no index. The current implementation uses this; should be migrated to `query_string`. +- `and` with `icontains` on `default_qry_str` → plain `LIKE '%term%'`. Slower, no index. + +**Important:** `query_string` must be present for `and`/`or` filters to apply. When using +filters without a keyword query, pass `query_string: "%"` as a wildcard to activate the +filter path without restricting by keyword. ### Supported operators | Operator | SQL | Notes | @@ -83,7 +86,7 @@ POST /v3/crud/journal_entry/search ### Pagination `page_size` (default 10, max ~100) + `page` (1-based). -Response includes `total` count for pagination UI. +Total count is in `response["meta"]["data_list_count"]` — not a top-level key. --- @@ -93,7 +96,7 @@ Full table schema from `ae_describe journal_entry --detailed`: | Field | Type | Indexed | Notes | |---|---|---|---| -| `id_random` | varchar(22) | UNI | Public ID — use for all API calls | +| `id_random` | varchar(22) | UNI | DB public ID field — but API responses return this as `journal_entry_id` (the Vision ID convention: `{obj_type}_id`). `id_random` key is `None` in responses. | | `journal_id` | int | MUL | FK — use `for_obj_id` param in search | | `name` | varchar(250) | MUL | Entry title | | `short_name` | varchar(25) | | | @@ -128,7 +131,7 @@ Full table schema from `ae_describe journal_entry --detailed`: | Field | Type | Notes | |---|---|---| -| `id_random` | varchar(22) | Public ID | +| `id_random` | varchar(22) | DB field — returned in API as `journal_id` | | `name` | varchar(250) | Journal name | | `summary` / `description` | text | | | `type_code` | varchar(25) | Journal type | @@ -142,7 +145,7 @@ Full table schema from `ae_describe journal_entry --detailed`: | Tool | Status | Notes | |---|---|---| | `ae_journal_list` | ✅ | Lists journals with id + name | -| `ae_journal_search` | ✅ improved | Keyword search; switched to fulltext in next pass | +| `ae_journal_search` | ✅ | Fulltext + tag/date/type/status/priority filters; paginated | | `ae_journal_entry_read` | ✅ | Full content by entry_id; configurable truncation | | `ae_journal_entries_list` | ✅ | Browse a journal newest-first; paginated | | `ae_journal_entry_create` | ✅ | Create with title, content, tags, summary | @@ -154,37 +157,31 @@ Full table schema from `ae_describe journal_entry --detailed`: --- -## Planned: Search Improvements +## ae_journal_search — Current Signature -Current search uses plain `LIKE` on `default_qry_str`. Migration plan: +All filters are optional and combine with AND. At least one should be provided. -1. **Switch to `query_string`** — fulltext MATCH/AGAINST; supports boolean operators -2. **Tag filter** — `icontains` on `tags` field -3. **Date range** — `gte`/`lte` on `created_on` or `updated_on` -4. **Classification filters** — `type_code`, `topic_code`, `category_code` (exact match) -5. **Sort control** — expose `order_by` (updated, created, name, priority) -6. **Status / priority filters** — `eq` on `status`, `priority` -7. **Combined search** — keyword + any filter combination in one call - -Target signature: ```python ae_journal_search( - query: str = "", # fulltext (query_string path) — optional - journal_id: str = "", # scope to journal - tags: str = "", # icontains on tags field - type_code: str = "", # eq - topic_code: str = "", # eq - date_from: str = "", # created_on gte (YYYY-MM-DD) - date_to: str = "", # created_on lte + query: str = "", # fulltext via query_string (MATCH/AGAINST) + journal_id: str = "", # scope to a specific journal + tags: str = "", # icontains on tags field + type_code: str = "", # eq on type_code + topic_code: str = "", # eq on topic_code + date_from: str = "", # created_on gte (YYYY-MM-DD) + date_to: str = "", # created_on lte (YYYY-MM-DD, exclusive of time — use next day to include full day) sort_by: str = "updated", # updated | created | name | priority sort_order: str = "desc", - status: int | None, - priority: int | None, + status: int | None = None, + priority: int | None = None, max_results: int = 10, page: int = 1, ) ``` +**date_to boundary note:** `date_to='2026-01-17'` means `<= 2026-01-17 00:00:00`, which +excludes entries created later that day. Use `date_to='2026-01-18'` to include all of Jan 17. + --- ## Planned: Broader AE Platform Integration @@ -215,9 +212,11 @@ Complete read/write/search for Journals and Journal Entries. `tags` is stored as a raw comma-separated varchar(255), not a JSON array. The API accepts a Python list on write (the `tags` PATCH key takes a list and the backend joins it). -On read, it comes back as a list in the API response. -For filtering: use `icontains` on `tags` — e.g. `{"field": "tags", "op": "icontains", "value": "networking"}`. -This means a tag search for "net" would match "networking" AND "subnet" — acceptable for now. +On read, it comes back as a **string** (e.g. `"shelterluv, api"`), not a list — normalize before +displaying: `[t.strip() for t in tags_str.split(",") if t.strip()]`. +For filtering: use `icontains` on `tags` inside the `"and"` list, e.g.: +`{"field": "tags", "op": "icontains", "value": "networking"}`. +A tag search for "net" matches "networking" AND "subnet" — acceptable for now. True per-tag filtering would require a tags junction table. ## Notes on `default_qry_str`