PaperTiger.Store.Invoices (PaperTiger v1.0.2)

Copy Markdown View Source

ETS-backed storage for Invoice resources.

Uses the shared store pattern via use PaperTiger.Store which provides:

  • GenServer wraps ETS table
  • Reads go directly to ETS (concurrent, fast)
  • Writes go through GenServer (serialized, safe)

Architecture

  • ETS Table: :paper_tiger_invoices (public, read_concurrency: true)
  • GenServer: Serializes writes, handles initialization
  • Shared Implementation: All CRUD operations via PaperTiger.Store

Examples

# Direct read (no GenServer bottleneck)
{:ok, invoice} = PaperTiger.Store.Invoices.get("in_123")

# Serialized write
invoice = %{id: "in_123", customer: "cus_123", status: "paid", ...}
{:ok, invoice} = PaperTiger.Store.Invoices.insert(invoice)

# Query helpers (direct ETS access)
invoices = PaperTiger.Store.Invoices.find_by_customer("cus_123")
invoices = PaperTiger.Store.Invoices.find_by_status("paid")

Summary

Functions

Returns all invoices without pagination.

Returns a specification to start this module under a supervisor.

Clears all invoices from the store (all namespaces).

Clears all invoices for a specific namespace.

Counts total invoices in current namespace.

Deletes a invoice from the store.

Finds invoices by customer ID.

Finds invoices by status.

Finds invoices by subscription ID.

Retrieves a invoice by ID.

Inserts a invoice into the store.

Lists all invoices with optional pagination.

Returns all items in a specific namespace.

Returns the ID prefix for this resource.

Starts the invoice store GenServer.

Returns the ETS table name for this store.

Updates a invoice in the store.

Functions

all()

@spec all() :: [map()]

Returns all invoices without pagination.

Direct ETS access - does not go through GenServer.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear()

@spec clear() :: :ok

Clears all invoices from the store (all namespaces).

Serialized write - goes through GenServer.

Useful for test cleanup. Note: This clears ALL data, not just the current namespace. For namespace-specific cleanup, use clear_namespace/1.

clear_namespace(namespace)

@spec clear_namespace(pid() | :global) :: :ok

Clears all invoices for a specific namespace.

Used by PaperTiger.Test to clean up after each test.

count()

@spec count() :: non_neg_integer()

Counts total invoices in current namespace.

Direct ETS access - does not go through GenServer.

delete(id)

@spec delete(String.t()) :: :ok

Deletes a invoice from the store.

Serialized write - goes through GenServer. Data is scoped to the current test namespace.

find_by_customer(customer_id)

@spec find_by_customer(String.t()) :: [map()]

Finds invoices by customer ID.

Direct ETS access - does not go through GenServer.

find_by_status(status)

@spec find_by_status(String.t()) :: [map()]

Finds invoices by status.

Direct ETS access - does not go through GenServer.

Examples

# Find all paid invoices
paid_invoices = PaperTiger.Store.Invoices.find_by_status("paid")

# Find all open invoices
open_invoices = PaperTiger.Store.Invoices.find_by_status("open")

# Find all void invoices
void_invoices = PaperTiger.Store.Invoices.find_by_status("void")

find_by_subscription(subscription_id)

@spec find_by_subscription(String.t()) :: [map()]

Finds invoices by subscription ID.

Direct ETS access - does not go through GenServer.

get(id)

@spec get(String.t()) :: {:ok, map()} | {:error, :not_found}

Retrieves a invoice by ID.

Direct ETS access - does not go through GenServer. Data is scoped to the current test namespace.

insert(item)

@spec insert(map()) :: {:ok, map()}

Inserts a invoice into the store.

Serialized write - goes through GenServer to prevent race conditions. Data is scoped to the current test namespace.

list(opts \\ %{})

@spec list(keyword() | map()) :: PaperTiger.List.t()

Lists all invoices with optional pagination.

Direct ETS access - does not go through GenServer. Data is scoped to the current test namespace.

Options

  • :limit - Number of items (default: 10, max: 100)
  • :starting_after - Cursor for pagination
  • :ending_before - Reverse cursor

list_namespace(namespace)

@spec list_namespace(pid() | :global) :: [map()]

Returns all items in a specific namespace.

Useful for debugging test isolation.

prefix()

@spec prefix() :: String.t() | nil

Returns the ID prefix for this resource.

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the invoice store GenServer.

table_name()

@spec table_name() :: atom()

Returns the ETS table name for this store.

update(item)

@spec update(map()) :: {:ok, map()}

Updates a invoice in the store.

Serialized write - goes through GenServer. Data is scoped to the current test namespace.