Packages

Comprehensive reporting extension for Ash Framework

Current section

Files

Jump to
ash_reports lib ash_reports.ex
Raw

lib/ash_reports.ex

defmodule AshReports do
@moduledoc """
AshReports is a comprehensive reporting extension for the Ash Framework.
It provides a declarative way to define complex reports with hierarchical band structures,
supports multiple output formats (PDF, HTML, HEEX), includes internationalization via CLDR,
and exposes reports through both an internal API server and an MCP server for LLM integration.
## Usage
To use AshReports, add it as an extension to your Ash domain:
defmodule MyApp.MyDomain do
use Ash.Domain,
extensions: [AshReports.Domain]
reports do
report :sales_report do
title "Sales Report"
description "Monthly sales summary"
driving_resource MyApp.Sales
bands do
band :title do
type :title
elements do
label :title_label do
text "Monthly Sales Report"
position x: 0, y: 0, width: 100, height: 20
end
end
end
end
end
end
end
"""
alias AshReports.Dsl
@sections [
Dsl.reports_section()
]
@transformers [
AshReports.Transformers.BuildReportModules
]
@verifiers [
AshReports.Verifiers.ValidateReports,
AshReports.Verifiers.ValidateBands,
AshReports.Verifiers.ValidateElements
]
use Spark.Dsl.Extension,
sections: @sections,
transformers: @transformers,
verifiers: @verifiers
# Note: reports/1 function is auto-generated by Spark.InfoGenerator in AshReports.Info
# Additional helper functions delegate to Info module
defdelegate report(domain_or_dsl_state, name), to: AshReports.Info
@doc """
Generates a report in the specified format.
This is a convenience wrapper around `AshReports.Runner.run_report/4` that provides
a simpler API for the most common use case.
## Parameters
- `domain` - The Ash domain containing the report definition
- `report_name` - The name of the report to generate (atom)
- `params` - Parameters to pass to the report (map)
- `format` - Output format (`:html`, `:pdf`, `:json`, or `:heex`)
## Returns
`{:ok, result}` where result is a map containing:
- `:content` - The generated report content
- `:metadata` - Metadata about report generation
- `:format` - The output format used
Or `{:error, reason}` if generation fails.
## Examples
# Generate HTML report
{:ok, result} = AshReports.generate(
MyApp.Domain,
:sales_report,
%{start_date: ~D[2024-01-01], end_date: ~D[2024-12-31]},
:html
)
html_content = result.content
# Generate PDF report
{:ok, result} = AshReports.generate(
MyApp.Domain,
:sales_report,
%{start_date: ~D[2024-01-01], end_date: ~D[2024-12-31]},
:pdf
)
pdf_content = result.content
## Options
For more control over report generation, use `AshReports.Runner.run_report/4` which
accepts additional options like `:locale`, `:timezone`, `:streaming`, etc.
"""
@spec generate(module(), atom(), map(), atom()) :: {:ok, map()} | {:error, term()}
def generate(domain, report_name, params \\ %{}, format) do
AshReports.Runner.run_report(domain, report_name, params, format: format)
end
@doc """
List all available band types.
"""
@spec band_types() :: [atom()]
def band_types do
[
:title,
:page_header,
:column_header,
:group_header,
:detail_header,
:detail,
:detail_footer,
:group_footer,
:column_footer,
:page_footer,
:summary
]
end
@doc """
List all available element types.
"""
@spec element_types() :: [atom()]
def element_types do
[:field, :label, :expression, :aggregate, :line, :box, :image]
end
@doc """
List all available variable types.
"""
@spec variable_types() :: [atom()]
def variable_types do
[:sum, :count, :average, :min, :max, :custom]
end
@doc """
List all available variable reset scopes.
"""
@spec reset_scopes() :: [atom()]
def reset_scopes do
[:detail, :group, :page, :report]
end
@doc """
List all supported output formats.
"""
@spec format_types() :: [atom()]
def format_types do
[:html, :pdf, :heex, :json]
end
end