name: arex description: 'Use when working with Arex, the ArcadeDB-native Elixir client, including tenant/scope aware records, schema helpers, graph helpers, raw query/command usage, and production rollout guidance.'


Arex Skill Guide

Use this guide when an AI agent needs to work with Arex in application code.

Purpose

Arex is an ArcadeDB-native Elixir client that wraps the HTTP API with higher-level helpers for:

  • querying and raw commands
  • key/value and time-series access
  • vector search and embedding index helpers
  • tenant and scope aware records
  • schema and database operations
  • graph traversal and edge creation

Guide Map

  • ../getting_started.md for setup, configuration, and first-use examples.
  • ../records_and_queries.md for CRUD helpers, paging, batching, and upserts.
  • ../graph_and_schema.md for provisioning, schema changes, and graph usage.
  • ../runtime_behavior.md for retries, timeouts, normalized errors, and observability.

Configuration Rules

  • Connection values are resolved from call opts, then app config, then env for url, user, pwd, and db.
  • language is not env-backed. It comes from call opts or app config and otherwise defaults to "sql".
  • receive_timeout defaults to 60 seconds when omitted.
  • retry is disabled by default and is only supported on read helpers.
  • transaction_timeout is a call-local write option, not config or env state.
  • scope requires tenant.

Core Modules

Usage Conventions

  • Prefer Arex.Query.sql/3 and Arex.Command.sql/3 unless you explicitly need a non-SQL language.
  • Prefer Arex.KV over hand-built Redis command strings for common key/value flows.
  • Prefer Arex.TimeSeries for TimeSeries DDL and dedicated endpoint usage instead of hand-building /ts paths.
  • Prefer Arex.Vector for LSM_VECTOR, LSM_SPARSE_VECTOR, and vector.* SQL wrappers instead of hand-building metadata JSON.
  • Use Arex.Record for document-style reads and writes instead of building raw statements for common CRUD paths.
  • Use tenant and scope consistently on both reads and writes when the application model is boundary-aware.
  • Prefer wrapped Arex.KV helpers over run/2 when you want tenant/scope key isolation.
  • Prefer wrapped Arex.TimeSeries insert and query helpers over raw SQL or raw line protocol when you want tenant/scope tags enforced automatically.
  • Do not try to mutate tenant, scope, @rid, @type, @in, or @out through helper APIs that explicitly protect those fields.
  • Use persist_multi/2 when you need one transaction across many record changes.

Important Behaviors

  • persist_multi/2 runs inside one SQLScript transaction.
  • fetch_multi/2 returns nil entries for missing or out-of-boundary records.
  • get_one/2 returns {:ok, nil} for no rows and {:error, %{kind: :multiple_results}} for ambiguous matches.
  • upsert/3 requires a non-empty where: clause and fails when more than one row matches.
  • Query pagination uses skip and limit under the hood because ArcadeDB rejected direct offset SQL in live testing.
  • Non-unique index creation requires the explicit notunique keyword in ArcadeDB SQL.
  • Dropping bracketed index names such as Customer[field] requires backtick quoting.
  • SQLScript scalar responses come back through the HTTP API as result rows such as %{"value" => 5}.
  • Write helpers reject retry: and Arex strips retry-related keys from req_options.
  • Arex.Http.request/4 is the low-level escape hatch for authenticated non-standard ArcadeDB endpoints.
  • Wrapped Arex.KV key helpers namespace keys by active tenant and scope, but run/2 and batch/2 are still raw.
  • Wrapped Arex.TimeSeries writes stamp tenant and scope tags, and wrapped SQL/latest reads apply those boundaries when present.

Operational Rules

  • Arex does not emit its own Telemetry events or logs; instrument call sites at the application boundary.
  • Log normalized error maps instead of raw payload guesses, but redact credentials and auth headers.
  • For local verification or CI, start arcadedata/arcadedb with an empty test_db database provisioned as test_db[test_user:test_password]; integration tests must run without relying on sample imports or root-only database creation.

Example

{:ok, customer} =
  Arex.Record.persist(
    %{name: "Ada"},
    db: "crm",
    type: "Customer",
    tenant: "ankara",
    scope: "sales"
  )

{:ok, page} =
  Arex.Query.page(
    "select from Customer order by @rid",
    %{},
    db: "crm",
    tenant: "ankara",
    scope: "sales",
    limit: 50
  )

When To Drop Lower

  • Use Arex.Http only when you need raw request/response control.
  • Use Arex.Sql and Arex.Options only for internal extensions or library work, not typical application code.