Packages
phoenix_kit
1.7.43
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/migrations/postgres/v43.ex
defmodule PhoenixKit.Migrations.Postgres.V43 do
@moduledoc """
PhoenixKit V43 Migration: Legal Module
This migration introduces the Legal module infrastructure for GDPR/CCPA compliance,
including consent tracking and legal page management.
## Changes
### Phase 1: Settings Seeds
- legal_enabled: Module enable/disable toggle
- legal_frameworks: Selected compliance frameworks (JSON array)
- legal_company_info: Company information for legal pages (JSON)
- legal_dpo_contact: Data Protection Officer contact (JSON)
### Phase 2 Prep: Consent Logs Table
- phoenix_kit_consent_logs: User consent tracking for cookie banners
- Supports both logged-in users and anonymous visitors
- Tracks consent type, version, and user fingerprint
### Consent Widget Settings (Phase 2)
- legal_consent_widget_enabled: Cookie consent banner toggle
- legal_cookie_banner_position: Banner position (bottom, top, etc.)
## PostgreSQL Support
- JSONB storage for flexible metadata
- Optimized indexes for consent queries
- Supports prefix for schema isolation
## Usage
# Migrate up
PhoenixKit.Migrations.Postgres.up(prefix: "public", version: 43)
# Rollback
PhoenixKit.Migrations.Postgres.down(prefix: "public", version: 42)
"""
use Ecto.Migration
@doc """
Run the V43 migration to add the Legal module infrastructure.
"""
def up(%{prefix: prefix} = _opts) do
# ===================================
# 1. CONSENT LOGS TABLE (Phase 2 prep)
# ===================================
create_if_not_exists table(:phoenix_kit_consent_logs, prefix: prefix) do
# User identification
add :user_id, :bigint, null: true
add :session_id, :string, size: 64, null: true
# Consent details
add :consent_type, :string, size: 30, null: false
add :consent_given, :boolean, null: false, default: false
add :consent_version, :string, size: 20, null: true
# Fingerprinting for anonymous tracking
add :ip_address, :string, size: 45, null: true
add :user_agent_hash, :string, size: 64, null: true
# Additional data
add :metadata, :map, null: true, default: %{}
timestamps(type: :utc_datetime_usec)
end
# Indexes for consent logs
create_if_not_exists index(:phoenix_kit_consent_logs, [:user_id],
name: :phoenix_kit_consent_logs_user_id_idx,
prefix: prefix
)
create_if_not_exists index(:phoenix_kit_consent_logs, [:session_id],
name: :phoenix_kit_consent_logs_session_id_idx,
prefix: prefix
)
create_if_not_exists index(:phoenix_kit_consent_logs, [:consent_type],
name: :phoenix_kit_consent_logs_type_idx,
prefix: prefix
)
create_if_not_exists index(:phoenix_kit_consent_logs, [:inserted_at],
name: :phoenix_kit_consent_logs_inserted_at_idx,
prefix: prefix
)
# Composite index for user consent lookup
create_if_not_exists index(:phoenix_kit_consent_logs, [:user_id, :consent_type],
name: :phoenix_kit_consent_logs_user_type_idx,
prefix: prefix
)
# Composite index for session consent lookup
create_if_not_exists index(:phoenix_kit_consent_logs, [:session_id, :consent_type],
name: :phoenix_kit_consent_logs_session_type_idx,
prefix: prefix
)
# ===================================
# 2. SETTINGS SEEDS
# ===================================
# Boolean settings use 'value' column (string)
execute """
INSERT INTO #{prefix_table_name("phoenix_kit_settings", prefix)} (key, value, module, date_added, date_updated)
VALUES
('legal_enabled', 'false', 'legal', NOW(), NOW()),
('legal_consent_widget_enabled', 'false', 'legal', NOW(), NOW()),
('legal_cookie_banner_position', 'bottom', 'legal', NOW(), NOW())
ON CONFLICT (key) DO NOTHING
"""
# JSON settings use 'value_json' column (jsonb)
execute """
INSERT INTO #{prefix_table_name("phoenix_kit_settings", prefix)} (key, value_json, module, date_added, date_updated)
VALUES
('legal_frameworks', '{"items": []}'::jsonb, 'legal', NOW(), NOW()),
('legal_company_info', '{}'::jsonb, 'legal', NOW(), NOW()),
('legal_dpo_contact', '{}'::jsonb, 'legal', NOW(), NOW())
ON CONFLICT (key) DO NOTHING
"""
# ===================================
# 3. TABLE COMMENTS
# ===================================
execute """
COMMENT ON TABLE #{prefix_table_name("phoenix_kit_consent_logs", prefix)} IS
'User consent tracking for GDPR/CCPA compliance cookie banners'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_consent_logs", prefix)}.consent_type IS
'Type of consent: necessary, analytics, marketing, preferences'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_consent_logs", prefix)}.consent_version IS
'Version of privacy/cookie policy when consent was given'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_consent_logs", prefix)}.user_agent_hash IS
'SHA256 hash of user agent for anonymous tracking without storing full UA string'
"""
# Update version
execute "COMMENT ON TABLE #{prefix_table_name("phoenix_kit", prefix)} IS '43'"
end
@doc """
Rollback the V43 migration.
"""
def down(%{prefix: prefix} = _opts) do
# Drop indexes first
drop_if_exists index(:phoenix_kit_consent_logs, [:session_id, :consent_type],
name: :phoenix_kit_consent_logs_session_type_idx,
prefix: prefix
)
drop_if_exists index(:phoenix_kit_consent_logs, [:user_id, :consent_type],
name: :phoenix_kit_consent_logs_user_type_idx,
prefix: prefix
)
drop_if_exists index(:phoenix_kit_consent_logs, [:inserted_at],
name: :phoenix_kit_consent_logs_inserted_at_idx,
prefix: prefix
)
drop_if_exists index(:phoenix_kit_consent_logs, [:consent_type],
name: :phoenix_kit_consent_logs_type_idx,
prefix: prefix
)
drop_if_exists index(:phoenix_kit_consent_logs, [:session_id],
name: :phoenix_kit_consent_logs_session_id_idx,
prefix: prefix
)
drop_if_exists index(:phoenix_kit_consent_logs, [:user_id],
name: :phoenix_kit_consent_logs_user_id_idx,
prefix: prefix
)
# Drop table
drop_if_exists table(:phoenix_kit_consent_logs, prefix: prefix)
# Remove settings
execute """
DELETE FROM #{prefix_table_name("phoenix_kit_settings", prefix)}
WHERE key IN (
'legal_enabled',
'legal_frameworks',
'legal_company_info',
'legal_dpo_contact',
'legal_consent_widget_enabled',
'legal_cookie_banner_position'
)
"""
# Update version
execute "COMMENT ON TABLE #{prefix_table_name("phoenix_kit", prefix)} IS '42'"
end
defp prefix_table_name(table_name, nil), do: table_name
defp prefix_table_name(table_name, "public"), do: "public.#{table_name}"
defp prefix_table_name(table_name, prefix), do: "#{prefix}.#{table_name}"
end