feat: Implement Event File Hosted Data Fix and API Guide Update
Address critical data visibility issues for Event Files and enhance frontend documentation.
This commit resolves the persistent problem where top-level hosted file convenience fields
(e.g., , , ) were
returning as in V3 Event File API responses, even when .
Key changes include:
- Refactored Pydantic model:
- Removed redundant definitions from top-level hosted file convenience fields,
allowing direct mapping from SQL view columns.
- Simplified to focus solely on conditionally loading the nested
object, as top-level fields are now populated directly by Pydantic
from the view.
- Added comprehensive comments to clarify data flow, Pydantic's behavior, and the
expected origin of these convenience fields from SQL views.
- Updated :
- Introduced a new section detailing how to retrieve Event File data, including the
use of to get both top-level convenience fields and a nested
object.
- Clarified all ID references as random string IDs.
- Renumbered the troubleshooting section.
- Copied updated guide to .
- Continued ID Vision compliance audit, ensuring consistent handling of random string IDs
across various core and event models (Account, Address, Contact, DataStore, Event Badge Template).
- Consolidated ID Vision E2E tests and updated related documentation.
- Minor updates to and
to support Event File data retrieval with .
This commit is contained in:
94
tests/e2e/test_e2e_v3_core_vision_parity.py
Normal file
94
tests/e2e/test_e2e_v3_core_vision_parity.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import requests
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
# --- Configuration ---
|
||||
BASE_URL = "https://dev-api.oneskyit.com/v3/crud"
|
||||
API_KEY = "PMM4n50teUCaOMMTN8qOJA" # Agent API Key
|
||||
|
||||
# Test Targets: (Object Type, Valid ID Random)
|
||||
TARGETS = [
|
||||
("account", "nqOzejLCDXM"),
|
||||
("person", "STI-PyWO6ODzLV8"),
|
||||
("contact", "dzGCDpaoYJA"),
|
||||
("address", "gUpFV3CX5UI"),
|
||||
("data_store", "tQy5v_3BIBI")
|
||||
]
|
||||
|
||||
def get_headers():
|
||||
return {
|
||||
"Content-Type": "application/json",
|
||||
"X-Aether-API-Key": API_KEY,
|
||||
"x-no-account-id": "bypass"
|
||||
}
|
||||
|
||||
def print_result(label, success, message=""):
|
||||
status = "✅ PASS" if success else "❌ FAIL"
|
||||
print(f"{status} | {label} {': ' + message if message else ''}")
|
||||
|
||||
def verify_core_parity(obj_type, record_id):
|
||||
"""
|
||||
Verifies that core objects comply with ID Vision standards.
|
||||
- All *_id fields must be strings.
|
||||
- Polymorphic for_id must resolve to parent random ID string.
|
||||
"""
|
||||
print(f"--- Testing {obj_type}: {record_id} ---")
|
||||
url = f"{BASE_URL}/{obj_type}/{record_id}"
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=get_headers())
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json().get('data', {})
|
||||
failures = []
|
||||
|
||||
# 1. Vision Standard (All *_id fields must be strings)
|
||||
for key, val in data.items():
|
||||
# Check fields that should be strings
|
||||
if key == "id" or (key.endswith("_id") and not key.endswith("external_id")):
|
||||
if val is not None and not isinstance(val, str):
|
||||
failures.append(f"Field '{key}' is {type(val).__name__} ({val})")
|
||||
elif isinstance(val, str) and len(val) < 11 and val.isdigit():
|
||||
failures.append(f"Field '{key}' looks like a stringified integer: '{val}'")
|
||||
|
||||
# 2. Polymorphic Check (for_id)
|
||||
if "for_id" in data:
|
||||
for_id = data.get("for_id")
|
||||
if for_id is None:
|
||||
# Some objects might have null for_id, but usually for these targets it should be set
|
||||
if obj_type in ["address", "contact", "data_store"]:
|
||||
failures.append("for_id is unexpectedly null")
|
||||
elif not isinstance(for_id, str) or len(for_id) < 11:
|
||||
failures.append(f"for_id failed resolution: {type(for_id).__name__} ({for_id})")
|
||||
|
||||
if not failures:
|
||||
print(f" ✅ [PASS] Vision integrity verified.")
|
||||
return True
|
||||
else:
|
||||
print(f" ❌ [FAIL] Vision integrity error:")
|
||||
for f in failures:
|
||||
print(f" - {f}")
|
||||
return False
|
||||
else:
|
||||
print(f" ❌ [ERROR] Status {response.status_code}: {response.text[:200]}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f" 💥 [EXCEPTION] {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 Starting Aether V3 Core Vision Parity Suite\n")
|
||||
|
||||
results = []
|
||||
for obj_type, record_id in TARGETS:
|
||||
results.append(verify_core_parity(obj_type, record_id))
|
||||
print("-" * 40)
|
||||
|
||||
if all(results):
|
||||
print("\n🏆 CORE SUITE SUCCESS: All core objects verified stable.")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n🚨 CORE SUITE FAILURE: Some critical checks failed.")
|
||||
sys.exit(1)
|
||||
@@ -10,6 +10,7 @@ API_KEY = "PMM4n50teUCaOMMTN8qOJA" # Agent API Key
|
||||
# Note: These IDs are extracted from real active records.
|
||||
TARGETS = [
|
||||
("event_badge", "JPUG-87-80-88"),
|
||||
("event_badge_template", "gDcA4kVb5B0"),
|
||||
("event_exhibit", "xK_9yEj1bQY"),
|
||||
("event_exhibit_tracking", "KVypw_xntSY"),
|
||||
("event_file", "a2pPIT_W28o") # Regression Target for Relational ID bug
|
||||
|
||||
Reference in New Issue
Block a user