defmodule Mv.Constants do @moduledoc """ Module for defining constants and atoms. """ @member_fields [ :first_name, :last_name, :email, :join_date, :exit_date, :notes, :country, :city, :street, :house_number, :postal_code, :membership_fee_start_date ] @custom_field_prefix "custom_field_" @boolean_filter_prefix "bf_" @group_filter_prefix "group_" @fee_type_filter_prefix "fee_type_" @join_date_from_param "jd_from" @join_date_to_param "jd_to" @exit_date_mode_param "ed_mode" @exit_date_from_param "ed_from" @exit_date_to_param "ed_to" @custom_date_filter_prefix "cdf_" @max_boolean_filters 50 @max_mailto_bulk_recipients 50 @max_uuid_length 36 @email_validator_checks [:html_input, :pow] # No member fields are required solely for Vereinfacht; API accepts minimal payload # (contactType + isExternal) when creating external contacts and supports filter by email for lookup. @vereinfacht_required_member_fields [] def member_fields, do: @member_fields @doc """ Returns member fields that are always required when Vereinfacht integration is configured. Currently empty: the Vereinfacht API only requires contactType (e.g. "person") when creating external contacts; lookup uses filter[email] so no extra required fields in the app. """ def vereinfacht_required_member_fields, do: @vereinfacht_required_member_fields @doc """ Returns whether the given member field is required by Vereinfacht when integration is active. """ def vereinfacht_required_field?(field) when is_atom(field), do: field in @vereinfacht_required_member_fields def vereinfacht_required_field?(_), do: false @doc """ Returns the prefix used for custom field keys in field visibility maps. ## Examples iex> Mv.Constants.custom_field_prefix() "custom_field_" """ def custom_field_prefix, do: @custom_field_prefix @doc """ Returns the prefix used for boolean custom field filter URL parameters. ## Examples iex> Mv.Constants.boolean_filter_prefix() "bf_" """ def boolean_filter_prefix, do: @boolean_filter_prefix @doc """ Returns the prefix for group filter URL parameters (e.g. group_=in|not_in). """ def group_filter_prefix, do: @group_filter_prefix @doc """ Returns the prefix for fee type filter URL parameters (e.g. fee_type_=in|not_in). """ def fee_type_filter_prefix, do: @fee_type_filter_prefix @doc """ Returns the URL parameter name for the join_date lower bound filter. ## Examples iex> Mv.Constants.join_date_from_param() "jd_from" """ def join_date_from_param, do: @join_date_from_param @doc """ Returns the URL parameter name for the join_date upper bound filter. ## Examples iex> Mv.Constants.join_date_to_param() "jd_to" """ def join_date_to_param, do: @join_date_to_param @doc """ Returns the URL parameter name for the exit_date filter mode (`active_only` | `inactive_only` | `all` | `custom`). ## Examples iex> Mv.Constants.exit_date_mode_param() "ed_mode" """ def exit_date_mode_param, do: @exit_date_mode_param @doc """ Returns the URL parameter name for the exit_date lower bound filter (only relevant when ed_mode=custom). ## Examples iex> Mv.Constants.exit_date_from_param() "ed_from" """ def exit_date_from_param, do: @exit_date_from_param @doc """ Returns the URL parameter name for the exit_date upper bound filter (only relevant when ed_mode=custom). ## Examples iex> Mv.Constants.exit_date_to_param() "ed_to" """ def exit_date_to_param, do: @exit_date_to_param @doc """ Returns the prefix for custom date field filter URL parameters (e.g. cdf__from / cdf__to). ## Examples iex> Mv.Constants.custom_date_filter_prefix() "cdf_" """ def custom_date_filter_prefix, do: @custom_date_filter_prefix @doc """ Returns the maximum number of boolean custom field filters allowed per request. This limit prevents DoS attacks by restricting the number of filter parameters that can be processed in a single request. ## Examples iex> Mv.Constants.max_boolean_filters() 50 """ def max_boolean_filters, do: @max_boolean_filters @doc """ Returns the maximum number of mailto recipients before the bulk "open in email program" action is disabled. The mailto link carries every recipient in its BCC; browsers cannot reliably hand a too-long mailto URI to the mail program. At or above this count the action is disabled in the UI (Copy and Export have no such limit). ## Examples iex> Mv.Constants.max_mailto_bulk_recipients() 50 """ def max_mailto_bulk_recipients, do: @max_mailto_bulk_recipients @doc """ Returns the maximum length of a UUID string (36 characters including hyphens). UUIDs in standard format (e.g., "550e8400-e29b-41d4-a716-446655440000") are exactly 36 characters long. This constant is used for input validation. ## Examples iex> Mv.Constants.max_uuid_length() 36 """ def max_uuid_length, do: @max_uuid_length @doc """ Returns the email validator checks used for EctoCommons.EmailValidator. We use both `:html_input` and `:pow` checks: - `:html_input` - Pragmatic validation matching browser `` behavior - `:pow` - Stricter validation following email spec, supports internationalization (Unicode) Using both ensures: - Compatibility with common email providers (html_input) - Compliance with email standards (pow) - Support for international email addresses (pow) ## Examples iex> Mv.Constants.email_validator_checks() [:html_input, :pow] """ def email_validator_checks, do: @email_validator_checks end