# `PhoenixKit.Modules.Legal`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L1)

Legal module for PhoenixKit - GDPR/CCPA compliant legal pages and consent management.

## Phase 1: Legal Pages Generation
- Compliance framework selection (GDPR, CCPA, etc.)
- Company information management
- Legal page generation (Privacy Policy, Terms, Cookie Policy)
- Integration with Publishing module for page storage

## Phase 2: Cookie Consent Widget (prepared infrastructure)
- Cookie consent banner
- Consent logging to phoenix_kit_consent_logs table
- Google Consent Mode v2 integration

## Dependencies
- Publishing module must be enabled before Legal module

## Usage

    # Enable the module (requires Publishing to be enabled)
    PhoenixKit.Modules.Legal.enable_system()

    # Check if enabled
    PhoenixKit.Modules.Legal.enabled?()

    # Get configuration
    PhoenixKit.Modules.Legal.get_config()

    # Generate legal pages
    PhoenixKit.Modules.Legal.generate_all_pages()

# `all_required_pages_published?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L598)

```elixir
@spec all_required_pages_published?() :: boolean()
```

Check if all required legal pages are published.

# `available_frameworks`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L244)

```elixir
@spec available_frameworks() :: %{
  required(String.t()) =&gt; PhoenixKit.Modules.Legal.LegalFramework.t()
}
```

Get available compliance frameworks.

# `available_page_types`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L252)

```elixir
@spec available_page_types() :: %{
  required(String.t()) =&gt; PhoenixKit.Modules.Legal.PageType.t()
}
```

Get available page types.

# `consent_widget_enabled?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L365)

```elixir
@spec consent_widget_enabled?() :: boolean()
```

Check if consent widget is enabled (Phase 2 feature).

# `disable_consent_widget`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L385)

```elixir
@spec disable_consent_widget() :: {:ok, term()} | {:error, term()}
```

Disable consent widget.

# `disable_google_consent_mode`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L482)

```elixir
@spec disable_google_consent_mode() :: {:ok, term()} | {:error, term()}
```

Disable Google Consent Mode v2.

# `disable_system`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L206)

```elixir
@spec disable_system() :: {:ok, term()} | {:error, term()}
```

Disable the Legal module.

# `enable_consent_widget`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L373)

```elixir
@spec enable_consent_widget() :: {:ok, term()} | {:error, term()}
```

Enable consent widget.

# `enable_google_consent_mode`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L474)

```elixir
@spec enable_google_consent_mode() :: {:ok, term()} | {:error, term()}
```

Enable Google Consent Mode v2.

# `enable_system`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L184)

```elixir
@spec enable_system() :: {:ok, :enabled} | {:error, :publishing_required | term()}
```

Enable the Legal module.

Requires Publishing module to be enabled first.
Creates the "legal" publishing group if it doesn't exist.

## Returns
- `{:ok, :enabled}` - Successfully enabled
- `{:error, :publishing_required}` - Publishing module must be enabled first

# `enabled?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L168)

```elixir
@spec enabled?() :: boolean()
```

Check if Legal module is enabled.

# `generate_all_pages`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L753)

```elixir
@spec generate_all_pages(keyword()) :: {:ok, map()}
```

Generate all required pages for selected frameworks.

## Parameters
- opts: Keyword options
  - :language - Language code (default: "en")
  - :scope - User scope for audit trail
  - :include_optional - Include optional pages (default: false)

## Returns
- `{:ok, results}` - Map of page_type => result

# `generate_page`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L697)

```elixir
@spec generate_page(
  String.t(),
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Generate a legal page from template.

## Parameters
- page_type: Page type slug (e.g., "privacy-policy")
- opts: Keyword options
  - :language - Language code (default: "en")
  - :scope - User scope for audit trail

## Returns
- `{:ok, post}` on success
- `{:error, reason}` on failure

# `get_all_pages_for_frameworks`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L817)

```elixir
@spec get_all_pages_for_frameworks([String.t()]) :: [String.t()]
```

Get all pages (required + optional) for given frameworks.

# `get_auto_policy_version`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L609)

```elixir
@spec get_auto_policy_version() :: String.t()
```

Get auto-calculated policy version based on legal page updates.

Uses the latest updated_at from cookie-policy or privacy-policy pages.
Falls back to manual version if no pages exist.

# `get_company_info`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L306)

```elixir
@spec get_company_info() :: map()
```

Get company information.

Reads from consolidated `company_info` key with fallback to legacy `legal_company_info`.

# `get_config`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L227)

```elixir
@spec get_config() :: map()
```

Get the full configuration of the Legal module.

Returns a map with:
- enabled: boolean
- frameworks: list of selected framework IDs
- company_info: map with company details
- dpo_contact: map with DPO contact info
- generated_pages: list of generated page slugs
- consent_widget_enabled: boolean (Phase 2)

# `get_consent_mode`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L502)

```elixir
@spec get_consent_mode() :: String.t()
```

Get consent mode.

Modes:
- "strict" - Full compliance: icon, script blocking, re-consent on policy change
- "notice" - Simple notice: banner once, no blocking, no icon

Default: "strict" for opt-in frameworks, "notice" otherwise.

# `get_consent_widget_config`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L558)

```elixir
@spec get_consent_widget_config() :: map()
```

Get full consent widget configuration for the component.

Returns a map with all settings needed by the cookie_consent component:
- enabled: boolean
- consent_mode: "strict" | "notice"
- show_icon: boolean
- icon_position: string
- policy_version: string
- google_consent_mode: boolean
- hide_for_authenticated: boolean
- frameworks: list of framework IDs
- cookie_policy_url: string
- privacy_policy_url: string

# `get_cookie_banner_position`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L424)

```elixir
@spec get_cookie_banner_position() :: String.t()
```

Get cookie banner/icon position.
Options: "bottom-left", "bottom-right", "top-left", "top-right"

# `get_dpo_contact`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L334)

```elixir
@spec get_dpo_contact() :: map()
```

Get Data Protection Officer contact.

# `get_icon_position`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L432)

```elixir
@spec get_icon_position() :: String.t()
```

Alias for get_cookie_banner_position/0.

# `get_policy_version`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L450)

```elixir
@spec get_policy_version() :: String.t()
```

Get policy version for consent tracking.
Changing this version will prompt users to re-consent.

# `get_required_pages_for_frameworks`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L802)

```elixir
@spec get_required_pages_for_frameworks([String.t()]) :: [String.t()]
```

Get pages required for given frameworks.

# `get_selected_frameworks`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L260)

```elixir
@spec get_selected_frameworks() :: [String.t()]
```

Get selected compliance frameworks.

# `get_unpublished_required_pages`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L581)

```elixir
@spec get_unpublished_required_pages() :: [String.t()]
```

Check if there are unpublished legal pages that are required.

Returns a list of unpublished page slugs (e.g., ["cookie-policy", "privacy-policy"]).

# `google_consent_mode_enabled?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L466)

```elixir
@spec google_consent_mode_enabled?() :: boolean()
```

Check if Google Consent Mode v2 is enabled.

# `has_opt_in_framework?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L414)

```elixir
@spec has_opt_in_framework?() :: boolean()
```

Check if any opt-in framework is selected.

# `hide_for_authenticated?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L526)

```elixir
@spec hide_for_authenticated?() :: boolean()
```

Check if consent widget should be hidden for authenticated users.
Only applies in "notice" mode.

# `list_generated_pages`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L778)

```elixir
@spec list_generated_pages() :: [map()]
```

List generated legal pages.

# `publish_page`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L720)

```elixir
@spec publish_page(
  String.t(),
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Publish a legal page by slug.

## Parameters
- page_slug: The slug of the page to publish (e.g., "cookie-policy")
- opts: Keyword options
  - :scope - User scope for audit trail

## Returns
- `{:ok, post}` on success
- `{:error, reason}` on failure

# `set_frameworks`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L278)

```elixir
@spec set_frameworks([String.t()]) :: {:ok, term()} | {:error, term()}
```

Set compliance frameworks.

## Parameters
- framework_ids: List of framework IDs to enable

## Returns
- `{:ok, setting}` on success
- `{:error, reason}` on failure

# `should_show_consent_icon?`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L403)

```elixir
@spec should_show_consent_icon?() :: boolean()
```

Check if consent icon should be shown.

Returns true only if:
- Legal module is enabled
- Consent widget is enabled
- Consent mode is "strict"
- At least one opt-in framework is selected (GDPR, UK GDPR, LGPD, PIPEDA)

# `update_company_info`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L324)

```elixir
@spec update_company_info(map()) :: {:ok, term()} | {:error, term()}
```

Update company information.

# `update_consent_mode`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L515)

```elixir
@spec update_consent_mode(String.t()) :: {:ok, term()} | {:error, term()}
```

Update consent mode.

# `update_dpo_contact`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L349)

```elixir
@spec update_dpo_contact(map()) :: {:ok, term()} | {:error, term()}
```

Update DPO contact information.

# `update_hide_for_authenticated`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L534)

```elixir
@spec update_hide_for_authenticated(boolean()) :: {:ok, term()} | {:error, term()}
```

Update hide for authenticated setting.

# `update_icon_position`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L438)

```elixir
@spec update_icon_position(String.t()) :: {:ok, term()} | {:error, term()}
```

Update cookie banner/icon position.

# `update_policy_version`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/modules/legal/legal.ex#L458)

```elixir
@spec update_policy_version(String.t()) :: {:ok, term()} | {:error, term()}
```

Update policy version.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
