Ingot.AnvilClient behaviour (Ingot v0.1.0)
View SourceBehaviour for labeling operations via Anvil.
Handles queue subscriptions, assignment fetching, label submission, and stats. Supports pluggable adapters for different deployment scenarios:
- MockAdapter: For testing without running Anvil
- ElixirAdapter: Direct in-process calls when deployed together
- HTTPAdapter: REST API calls for separate deployments (future)
Summary
Callbacks
Check if user has access to a queue.
Create an invite code for a queue.
Export all labels as CSV.
Get invite by code.
Get next assignment from a queue for a user.
Get queue-level statistics.
Get user roles.
Health check for Anvil service.
Redeem an invite code.
Get labeling statistics.
Store a completed label.
Submit a completed label.
Get total count of all labels.
Upsert a user (create or update).
Functions
Check if user has access to a queue.
Create an invite code for a queue.
Export all labels as CSV.
Get invite by code.
Get next assignment from a queue for a user.
Get queue-level statistics.
Get user roles.
Health check for Anvil service.
Redeem an invite code.
Get all labels for a specific session.
Get labeling statistics.
Store a completed label.
Submit a completed label.
Get total count of all labels.
Upsert a user (create or update).
Types
Callbacks
Check if user has access to a queue.
Returns true if the user has permission to access the queue.
Create an invite code for a queue.
Generates an invite code that can be redeemed by external labelers.
Export all labels as CSV.
Legacy API - maintained for backward compatibility.
@callback get_invite(code :: String.t()) :: {:ok, map()} | {:error, :not_found | :expired | :exhausted}
Get invite by code.
Returns invite details if the code is valid and not expired/exhausted.
@callback get_next_assignment(queue_id(), user_id()) :: {:ok, Ingot.DTO.Assignment.t()} | {:error, error()}
Get next assignment from a queue for a user.
Returns an assignment with the sample pre-fetched and any existing labels for review/adjudication scenarios.
@callback get_queue_stats(queue_id()) :: {:ok, Ingot.DTO.QueueStats.t()} | {:error, error()}
Get queue-level statistics.
Returns aggregate progress and agreement metrics.
Get user roles.
Returns a list of roles assigned to the user.
@callback health_check() :: {:ok, :healthy} | {:error, error()}
Health check for Anvil service.
Returns :ok if Anvil is reachable and healthy, otherwise returns an error.
@callback redeem_invite(code :: String.t(), user_attrs :: map()) :: {:ok, map()} | {:error, :not_found | :expired | :exhausted | error()}
Redeem an invite code.
Creates a user and grants access to the queue associated with the invite.
@callback statistics() :: map()
Get labeling statistics.
Legacy API - maintained for backward compatibility.
Store a completed label.
Legacy API - maintained for backward compatibility.
@callback submit_label(assignment_id(), values :: map()) :: :ok | {:error, error()}
Submit a completed label.
Values should conform to the schema defined in the assignment.
@callback total_labels() :: integer()
Get total count of all labels.
Legacy API - maintained for backward compatibility.
Upsert a user (create or update).
Creates a new user or updates an existing one based on external_id. Used for OIDC just-in-time provisioning.
Functions
Check if user has access to a queue.
Examples
iex> AnvilClient.check_queue_access("user_123", "queue_abc")
{:ok, true}
Create an invite code for a queue.
Examples
iex> AnvilClient.create_invite(%{queue_id: "queue_abc", role: :labeler, max_uses: 10})
{:ok, %{code: "ABCD1234WXYZ", queue_id: "queue_abc", ...}}
Export all labels as CSV.
Examples
iex> AnvilClient.export_csv()
{:ok, "sample_id,coherence\n..."}
Get invite by code.
Examples
iex> AnvilClient.get_invite("ABCD1234WXYZ")
{:ok, %{code: "ABCD1234WXYZ", queue_id: "queue_abc", ...}}
Get next assignment from a queue for a user.
Examples
iex> AnvilClient.get_next_assignment("queue-1", "user-123")
{:ok, %Ingot.DTO.Assignment{...}}
iex> AnvilClient.get_next_assignment("empty-queue", "user-123")
{:error, :no_assignments}
Get queue-level statistics.
Examples
iex> AnvilClient.get_queue_stats("queue-1")
{:ok, %Ingot.DTO.QueueStats{total_samples: 100, labeled: 47, ...}}
Get user roles.
Examples
iex> AnvilClient.get_user_roles("user_123")
{:ok, [%{role: :labeler, scope: "queue:abc"}, ...]}
Health check for Anvil service.
Examples
iex> AnvilClient.health_check()
{:ok, :healthy}
iex> AnvilClient.health_check()
{:error, :not_available}
Redeem an invite code.
Examples
iex> AnvilClient.redeem_invite("ABCD1234WXYZ", %{email: "labeler@example.com", name: "Labeler"})
{:ok, %{user: %{id: "user_123", ...}, queue_id: "queue_abc", role: :labeler}}
Get all labels for a specific session.
Legacy API - maintained for backward compatibility.
Get labeling statistics.
Examples
iex> AnvilClient.statistics()
%{total_labels: 47, avg_coherence: 3.8, ...}
Store a completed label.
Examples
iex> label = %{sample_id: "s1", ratings: %{coherence: 4}}
iex> AnvilClient.store_label(label)
{:ok, label}
Submit a completed label.
Examples
iex> AnvilClient.submit_label("assignment-1", %{coherence: 4})
:ok
iex> AnvilClient.submit_label("assignment-1", %{invalid: "data"})
{:error, {:validation, %{coherence: "is required"}}}
Get total count of all labels.
Examples
iex> AnvilClient.total_labels()
47
Upsert a user (create or update).
Examples
iex> AnvilClient.upsert_user(%{external_id: "oidc_123", email: "user@example.com", name: "User"})
{:ok, %{id: "user_123", external_id: "oidc_123", ...}}