defmodule AccessGrid.CardTemplate do
@moduledoc """
Represents a full card template configuration.
This struct contains all template data as returned by `AccessGrid.Console.read_template/2`.
For minimal representations, see:
- `AccessGrid.CardTemplate.Result` - returned from create/update operations
- `AccessGrid.CardTemplate.Summary` - embedded in `AccessGrid.CardTemplatePair.Summary`
"""
@type t :: %__MODULE__{
id: String.t() | nil,
name: String.t() | nil,
platform: String.t() | nil,
protocol: String.t() | nil,
use_case: String.t() | nil,
created_at: String.t() | nil,
last_published_at: String.t() | nil,
issued_keys_count: integer() | nil,
active_keys_count: integer() | nil,
allow_on_multiple_devices: boolean() | nil,
watch_count: integer() | nil,
iphone_count: integer() | nil,
android_device_limit: String.t() | nil,
support_url: String.t() | nil,
support_phone_number: String.t() | nil,
support_email: String.t() | nil,
privacy_policy_url: String.t() | nil,
terms_and_conditions_url: String.t() | nil,
background_color: String.t() | nil,
label_color: String.t() | nil,
label_secondary_color: String.t() | nil,
credential_profiles: [String.t()],
landing_pages: [String.t()],
metadata: map()
}
defstruct [
:id,
:name,
:platform,
:protocol,
:use_case,
:created_at,
:last_published_at,
:issued_keys_count,
:active_keys_count,
:allow_on_multiple_devices,
:watch_count,
:iphone_count,
:android_device_limit,
:support_url,
:support_phone_number,
:support_email,
:privacy_policy_url,
:terms_and_conditions_url,
:background_color,
:label_color,
:label_secondary_color,
credential_profiles: [],
landing_pages: [],
metadata: %{}
]
@doc """
Creates a CardTemplate struct from an API response map.
The server groups some fields under nested objects (`allowed_device_counts`,
`support_settings`, `terms_settings`, `style_settings`) and renames a few
along the way (e.g. wire `support_settings.url` → struct `:support_url`).
This function does the flatten + rename so the struct's field names match
the request param names. Symmetric: write `background_color: "..."` on
create, read `template.background_color` on get.
"""
@spec from_response(map()) :: t()
def from_response(data) when is_map(data) do
device = data["allowed_device_counts"] || %{}
support = data["support_settings"] || %{}
terms = data["terms_settings"] || %{}
style = data["style_settings"] || %{}
%__MODULE__{
id: data["id"],
name: data["name"],
platform: data["platform"],
protocol: data["protocol"],
use_case: data["use_case"],
created_at: data["created_at"],
last_published_at: data["last_published_at"],
issued_keys_count: data["issued_keys_count"],
active_keys_count: data["active_keys_count"],
allow_on_multiple_devices: device["allow_on_multiple_devices"],
watch_count: device["watch"],
iphone_count: device["iphone"],
android_device_limit: device["android_device_limit"],
support_url: support["url"],
support_phone_number: support["phone"],
support_email: support["email"],
privacy_policy_url: terms["privacy_policy_url"],
terms_and_conditions_url: terms["terms_and_conditions_url"],
background_color: style["background_color"],
label_color: style["label_color"],
label_secondary_color: style["label_secondary_color"],
credential_profiles: data["credential_profiles"] || [],
landing_pages: data["landing_pages"] || [],
metadata: data["metadata"] || %{}
}
end
end
defmodule AccessGrid.CardTemplate.Result do
@moduledoc """
Represents the response from template create/update operations.
This is a minimal acknowledgment containing only the template ID,
estimated publishing date, and metadata. For full template data,
use `AccessGrid.Console.read_template/2` which returns `AccessGrid.CardTemplate`.
"""
@type t :: %__MODULE__{
id: String.t() | nil,
estimated_publishing_date: String.t() | nil,
metadata: map()
}
defstruct [
:id,
:estimated_publishing_date,
metadata: %{}
]
@doc """
Creates a Result struct from an API response map.
"""
@spec from_response(map()) :: t()
def from_response(data) when is_map(data) do
%__MODULE__{
id: data["id"],
estimated_publishing_date: data["estimated_publishing_date"],
metadata: data["metadata"] || %{}
}
end
end
defmodule AccessGrid.CardTemplate.PublishResult do
@moduledoc """
Response from publishing a card template via
`AccessGrid.Console.publish_template/2`. Contains the template id and the
resulting publish status:
* `"publishing"` — already in flight from a prior call
* `"in-review"` — Apple-side review queued (typical for Apple templates)
* `"ready"` — published immediately (typical for Android templates)
"""
@type t :: %__MODULE__{
id: String.t() | nil,
status: String.t() | nil
}
defstruct [:id, :status]
@doc """
Creates a PublishResult struct from an API response map.
"""
@spec from_response(map()) :: t()
def from_response(data) when is_map(data) do
%__MODULE__{
id: data["id"],
status: data["status"]
}
end
end
defmodule AccessGrid.CardTemplate.Summary do
@moduledoc """
Represents a minimal template reference embedded in `AccessGrid.CardTemplatePair.Summary`.
Contains only the essential identifying information: id, name, and platform.
For full template data, use `AccessGrid.Console.read_template/2`.
"""
@type t :: %__MODULE__{
id: String.t() | nil,
name: String.t() | nil,
platform: String.t() | nil
}
defstruct [:id, :name, :platform]
@doc """
Creates a Summary struct from an API response map.
"""
@spec from_response(map()) :: t()
def from_response(nil), do: nil
def from_response(data) when is_map(data) do
%__MODULE__{
id: data["id"],
name: data["name"],
platform: data["platform"]
}
end
end