defmodule Plausible.DataMigration.BackfillTrackerScriptConfiguration do @moduledoc """ Backfill Plausible.Site.TrackerScriptConfiguration for all sites. """ import Ecto.Query alias Plausible.Repo defmodule TrackerScriptConfigurationSnapshot do @moduledoc """ A snapshot of the Plausible.Site.TrackerScriptConfiguration schema from May 2025. """ use Ecto.Schema @primary_key false schema "tracker_script_configuration" do field :id, :string field :installation_type, Ecto.Enum, values: [:manual, :wordpress, :gtm, nil] field :track_404_pages, :boolean, default: false field :hash_based_routing, :boolean, default: false field :outbound_links, :boolean, default: false field :file_downloads, :boolean, default: false field :revenue_tracking, :boolean, default: false field :tagged_events, :boolean, default: false field :form_submissions, :boolean, default: false field :pageview_props, :boolean, default: false field :site_id, :integer timestamps() end end def run() do now = NaiveDateTime.utc_now(:second) process_batch(0, now) end @batch_size 1000 def process_batch(offset, now) do sites = Repo.all( from(s in "sites", order_by: [asc: :id], limit: @batch_size, offset: ^offset, select: %{id: s.id, installation_meta: s.installation_meta} ) ) if length(sites) > 0 do create_tracker_script_configurations(sites, now) process_batch(offset + @batch_size, now) end end defp create_tracker_script_configurations(sites, now) do configurations = Enum.map(sites, &tracker_script_configuration(&1, now)) Repo.insert_all( TrackerScriptConfigurationSnapshot, configurations, # Conflicts mean that the site has already been updated and is in sync on_conflict: :nothing, conflict_target: [:site_id] ) end defp tracker_script_configuration(site, now) do installation_meta = site.installation_meta installation_type = if installation_meta do Map.get(installation_meta, "installation_type") end script_config = if installation_meta do Map.get(installation_meta, "script_config", %{}) else %{} end %{ id: Nanoid.generate(), site_id: site.id, installation_type: installation_type |> remap_installation_type(), track_404_pages: Map.get(script_config, "404", false), hash_based_routing: Map.get(script_config, "hash", false), outbound_links: Map.get(script_config, "outbound-links", false), file_downloads: Map.get(script_config, "file-downloads", false), revenue_tracking: Map.get(script_config, "revenue", false), tagged_events: Map.get(script_config, "tagged-events", false), form_submissions: Map.get(script_config, "form-submissions", false), pageview_props: Map.get(script_config, "pageview-props", false), inserted_at: now, updated_at: now } end defp remap_installation_type("WordPress"), do: :wordpress defp remap_installation_type("GTM"), do: :gtm defp remap_installation_type("manual"), do: :manual defp remap_installation_type(nil), do: nil end