Files
OSIT-AE-API-FastAPI/documentation/V3_FRONTEND_API_GUIDE.md
Scott Idem 43ac62b561 feat(auth): consolidate and secure V3 authentication flow
- Re-apply safe guest auth and passcode-to-JWT endpoint
- Consolidate AccountContext with token_payload and role flags
- Restore documentation for new guest flows and public read whitelists
- Fix 403 error in get_obj_li by allowing optional account context
2026-01-20 18:42:43 -05:00

8.0 KiB

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}/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 Manual column names Reserved q property in SearchQuery

2. Authentication and Security (Mandatory)

As of January 2026, the V3 architecture enforces strict Multi-Tenant Isolation and Machine Authorization. Most requests require two levels of validation.

A. The "Entry Ticket" (API Key)

Mandatory for all requests. Every request must provide a valid x-aether-api-key in the header. This identifies the application or script.

  • Header: x-aether-api-key: <your_app_key>
  • Status Code: 403 Forbidden if missing, invalid, or expired.

B. The "Visa" (Account Context)

Once the API Key is validated, you must specify the context of your request.

  1. Standard User Access: Provide the x-account-id (the random string ID).
    • Header: x-account-id: <account_id_random>
  2. Administrative Bypass: For authorized scripts needing global access.
    • Header: x-no-account-id: bypass
  3. Guest / Anonymous Access: Provide a Safe Guest JWT.
    • Header: x-aether-api-key: <your_app_key> (No Account Header)
    • Query Param: ?jwt=<guest_token>
    • Benefit: Allows the backend to track cryptographically signed session state (e.g., site context) without granting full account access.

C. Public Read Whitelist (Unauthenticated)

The V3 architecture allows unauthenticated (guest) access to specific objects, provided a valid API Key is present.

  • Whitelisted Objects: site_domain, event, event_session, event_presentation, event_presenter, post, post_comment, archive, archive_content, hosted_file.
  • Behavior: Requests to these objects will succeed without a user-level JWT, but are strictly limited to Read-Only operations (GET/Search).

D. Passcode Authentication (Machine/Kiosk Logins)

For guest machines or specialized kiosks, use the dedicated passcode endpoint to receive a scoped JWT.

  • Endpoint: POST /api/authenticate_passcode
  • Payload: { "site_id": "<site_id_random>", "passcode": "<secret>" }
  • Response: Returns a JWT containing the site's account_id and resolved role flags (super, manager, administrator).

E. Fail-Fast on Auth Failures (401/403)

The frontend implements a Fail-Fast policy for 401/403 errors. If the API returns these codes, the frontend must not retry automatically. It should stop and redirect the user or display an error.


3. Implementing V3 CRUD Functions

A. List & Single Object (GET)

Support for view selection allows fetching richer data models when needed.

// 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 complex logical bodies with simple query parameters.

export async function search_ae_obj_v3({
    api_cfg,
    obj_type,
    search_query, // { q: "search term", and: [...] }
    enabled = 'enabled',
    view = 'default'
}) {
    const endpoint = `/v3/crud/${obj_type}/search`;
    const params = { enabled, view };

    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: q: "%" returns all records (respecting logical filters).
  • Fallback: Performs a LIKE search across all searchable fields if no index exists.
{
  "q": "Annual Meeting",
  "and": [{ "field": "enable", "op": "eq", "value": true }]
}

4. Create, Update, & Delete

A. Create (POST)

V3 validates incoming JSON against the mdl_in Pydantic model.

// 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 });
}

B. Update (PATCH)

V3 uses PATCH for partial updates. Only provided fields are modified.

// 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)

Supports soft-delete (method=hide) or hard-delete (method=delete).

// DELETE /v3/crud/{obj_type}/{obj_id}?method=hide
export async function delete_ae_obj_v3({ api_cfg, obj_type, obj_id, method = 'delete' }) {
    const endpoint = `/v3/crud/${obj_type}/${obj_id}`;
    return await delete_object({ api_cfg, endpoint, params: { method } });
}

5. Specialized Endpoints

A. Schema Discovery

Path: GET /v3/crud/{obj_type}/schema Returns DB column definitions and Pydantic field rules for dynamic UI builders.

B. Secure File Downloads (JWT in URL)

For browsers downloading files, you can pass the JWT directly in the query string.

  • GET /v3/crud/hosted_file/{id}/?jwt={token}

6. The "ID Vision" Standard (2026)

V3 uses a String-Only ID Vision. The frontend and external agents NEVER handle or store internal database integers.

A. Automatic ID Mapping (Output)

Internal id_random fields are renamed to clean, short names in the JSON response.

  • id: Unique random identifier for the record.
  • account_id: Unique random identifier for the parent account.

B. Intelligent Mapping (Input/Search)

You can send string IDs back to the API using the same clean names.

  • Search: Filter by account_id using the random string value.
  • Save: Send account_id: "nqOzejLCDXM" in a payload; the API resolves it to an integer.

7. Standard Patterns & Pitfalls

A. Permissive Update Mode (Available)

To simplify state management, V3 supports a Permissive Update Mode which ignores unknown extra fields in the payload.

  • Header: x-ae-ignore-extra-fields: true
  • Use when: Sending back objects that contain read-only technical metadata.

B. Structured Error Handling (Rich Bubbling)

V3 returns machine-readable error objects in meta.details for failures (400/500).

Example Error Response:

{
  "meta": {
    "success": false,
    "status_code": 400,
    "details": {
      "category": "database_schema",
      "code": 1054,
      "message": "Unknown column 'notes' in 'SET'",
      "recoverable": false
    }
  }
}

Common Categories:

  • database_duplicate: Non-unique value (Code 1062).
  • database_constraint: Foreign key violation (Codes 1451, 1452).
  • database_schema: Invalid column name (Codes 1054, 1146).
  • database_connection: Temporary DB issues (recoverable: true).
  • validation: Pydantic validation failed.

C. Booleans: 'NULL' vs '0'

Pitfall: Fields like hide can be NULL in the DB. Standard: Handle null, undefined, and 0 identically for boolean checks.