Generic middleware pipeline for query execution and schema discovery hooks.
Each middleware module implements init/1 and call/2, following
the standard Plug pattern:
defmodule MyApp.AuditPlug do
def init(opts), do: opts
def call(payload, opts) do
{:cont, payload} # continue to next middleware
# or
{:halt, "reason"} # stop pipeline, Lotus returns {:error, reason}
end
endPipeline Events
| Event | Triggered |
|---|---|
:before_query | After preflight visibility check, before SQL execution |
:after_query | After execution, before result returned to caller |
:after_list_schemas | After schema discovery and visibility filtering |
:after_list_tables | After table discovery and visibility filtering |
:after_get_table_schema | After table schema introspection and column visibility |
:after_list_relations | After relation discovery and visibility filtering |
Configuration
config :lotus,
middleware: %{
before_query: [
{MyApp.AccessControlPlug, []},
{MyApp.QueryAuditPlug, [repo: MyApp.AuditRepo]}
],
after_query: [
{MyApp.QueryAuditPlug, [repo: MyApp.AuditRepo]}
],
after_list_tables: [
{MyApp.TableFilterPlug, []}
]
}Context
A :context key carries opaque user data (e.g. the current user) through
to middleware. Lotus never inspects this value.
Summary
Functions
Compiles all middleware by calling init/1 on each module and stores
the result in :persistent_term for fast runtime access.
Runs the middleware pipeline for the given event.
Types
@type event() ::
:before_query
| :after_query
| :after_list_schemas
| :after_list_tables
| :after_get_table_schema
| :after_list_relations
Functions
@spec compile(map()) :: :ok
Compiles all middleware by calling init/1 on each module and stores
the result in :persistent_term for fast runtime access.
Runs the middleware pipeline for the given event.
Returns {:cont, payload} if all middleware passed, or
{:halt, reason} if any middleware halted the pipeline.
When no middleware is configured for the event, returns {:cont, payload}
with zero overhead beyond the map lookup.