From 166d9d30a001a8a7d3ab82b772df435b67af7f3c Mon Sep 17 00:00:00 2001 From: Mahad Kalam <55807755+skyfallwastaken@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:13:48 +0000 Subject: [PATCH] ahoy is walking the plank (#903) * Remove Ahoy * Simplify migration * sync migrations * Update db/migrate/20260204113033_drop_ahoy_tables.rb Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Gemfile | 4 - Gemfile.lock | 38 +--- app/controllers/application_controller.rb | 5 - app/models/ahoy/event.rb | 9 - app/models/ahoy/visit.rb | 7 - app/views/shared/_nav.html.erb | 5 - config/initializers/ahoy.rb | 12 -- config/initializers/ahoy_captain.rb | 170 ------------------ .../initializers/ahoy_captain_pagy_patch.rb | 10 -- config/routes.rb | 1 - config/skylight.yml | 1 - db/migrate/20260204113033_drop_ahoy_tables.rb | 10 ++ db/schema.rb | 48 +---- 13 files changed, 12 insertions(+), 308 deletions(-) delete mode 100644 app/models/ahoy/event.rb delete mode 100644 app/models/ahoy/visit.rb delete mode 100644 config/initializers/ahoy.rb delete mode 100644 config/initializers/ahoy_captain.rb delete mode 100644 config/initializers/ahoy_captain_pagy_patch.rb create mode 100644 db/migrate/20260204113033_drop_ahoy_tables.rb diff --git a/Gemfile b/Gemfile index a8cb9e7..370727f 100644 --- a/Gemfile +++ b/Gemfile @@ -83,11 +83,7 @@ gem "flamegraph" gem "skylight" -# Ahoy analytics -gem "ahoy_matey" gem "geocoder" -gem "ahoy_captain", git: "https://github.com/johnmcdowall/ahoy_captain.git", branch: "fix_importmaps" - gem "pagy", "~> 43.2" # Airtable syncing diff --git a/Gemfile.lock b/Gemfile.lock index 9474d8b..695593d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,21 +1,3 @@ -GIT - remote: https://github.com/johnmcdowall/ahoy_captain.git - revision: 0916eee4bf1279bc7d69ab003b1b1bd7fac8741c - branch: fix_importmaps - specs: - ahoy_captain (1.1.0) - ahoy_matey (>= 1.1) - chartkick (>= 4) - groupdate (>= 5) - importmap-rails (>= 2) - pagy (>= 4) - rails (>= 6) - ransack (>= 2.3) - rubyzip - stimulus-rails (>= 1.1) - turbo-rails (>= 1.2) - view_component (>= 3) - GEM remote: https://rubygems.org/ specs: @@ -97,10 +79,6 @@ GEM uri (>= 0.13.1) addressable (2.8.8) public_suffix (>= 2.0.2, < 8.0) - ahoy_matey (5.4.1) - activesupport (>= 7.1) - device_detector (>= 1) - safely_block (>= 0.4) ast (2.4.3) autotuner (1.1.0) base64 (0.3.0) @@ -131,7 +109,6 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - chartkick (5.2.1) childprocess (5.1.0) logger (~> 1.5) chunky_png (1.4.0) @@ -150,7 +127,6 @@ GEM debug (1.11.1) irb (~> 1.10) reline (>= 0.3.8) - device_detector (1.1.3) diff-lcs (1.6.2) domain_name (0.6.20240107) doorkeeper (5.8.2) @@ -228,8 +204,6 @@ GEM fugit (>= 1.11.0) railties (>= 6.1.0) thor (>= 1.0.0) - groupdate (6.7.0) - activesupport (>= 7.1) hashie (5.1.0) logger htmlcompressor (0.4.0) @@ -433,10 +407,6 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.3.1) - ransack (4.4.1) - activerecord (>= 7.2) - activesupport (>= 7.2) - i18n rdoc (7.1.0) erb psych (>= 4.0.0) @@ -508,7 +478,6 @@ GEM ruby_identicon (0.0.6) chunky_png (~> 1.4.0) rubyzip (3.2.2) - safely_block (0.5.0) sanitize (7.0.0) crass (~> 1.0.2) nokogiri (>= 1.16.8) @@ -590,10 +559,6 @@ GEM uniform_notifier (1.18.0) uri (1.1.1) useragent (0.16.11) - view_component (4.2.0) - actionview (>= 7.1.0) - activesupport (>= 7.1.0) - concurrent-ruby (~> 1) web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -615,6 +580,7 @@ PLATFORMS aarch64-linux-musl arm-linux-gnu arm-linux-musl + arm64-darwin-23 arm64-darwin-24 arm64-darwin-25 x86_64-linux @@ -623,8 +589,6 @@ PLATFORMS DEPENDENCIES activerecord-import - ahoy_captain! - ahoy_matey autotuner (~> 1.0) bootsnap brakeman diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 27ad0ed..83ebd29 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,7 +6,6 @@ class ApplicationController < ActionController::Base before_action :track_request before_action :set_public_activity before_action :enforce_lockout - after_action :track_action around_action :switch_time_zone, if: :current_user @@ -37,10 +36,6 @@ class ApplicationController < ActionController::Base ) end - def track_action - ahoy.track "Ran action", request.path_parameters - end - def track_request RequestCounter.increment end diff --git a/app/models/ahoy/event.rb b/app/models/ahoy/event.rb deleted file mode 100644 index 8a46720..0000000 --- a/app/models/ahoy/event.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Ahoy::Event < ApplicationRecord - include AhoyCaptain::Ahoy::EventMethods - include Ahoy::QueryMethods - - self.table_name = "ahoy_events" - - belongs_to :visit - belongs_to :user, optional: true -end diff --git a/app/models/ahoy/visit.rb b/app/models/ahoy/visit.rb deleted file mode 100644 index 55a74ea..0000000 --- a/app/models/ahoy/visit.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Ahoy::Visit < ApplicationRecord - include AhoyCaptain::Ahoy::VisitMethods - self.table_name = "ahoy_visits" - - has_many :events, class_name: "Ahoy::Event" - belongs_to :user, optional: true -end diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb index 9ad2a11..6666bcf 100644 --- a/app/views/shared/_nav.html.erb +++ b/app/views/shared/_nav.html.erb @@ -151,11 +151,6 @@ <% end %> <% end %> <% end %> - <% superadmin_tool(nil, "div") do %> - <%= link_to ahoy_captain_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(ahoy_captain_path) ? 'bg-primary text-primary' : 'hover:bg-darkless'}", data: { action: "click->nav#clickLink" } do %> - Ahoy Captain - <% end %> - <% end %> <% superadmin_tool(nil, "div") do %> <%= link_to good_job_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(good_job_path) ? 'bg-primary text-primary' : 'hover:bg-darkless'}", data: { action: "click->nav#clickLink" } do %> GoodBoy diff --git a/config/initializers/ahoy.rb b/config/initializers/ahoy.rb deleted file mode 100644 index f3c9158..0000000 --- a/config/initializers/ahoy.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Ahoy::Store < Ahoy::DatabaseStore -end - -# set to true for JavaScript tracking -Ahoy.api = false - -# set to true for geocoding (and add the geocoder gem to your Gemfile) -# we recommend configuring local geocoding as well -# see https://github.com/ankane/ahoy#geocoding -Ahoy.geocode = false - -Ahoy.job_queue = :literally_whenever diff --git a/config/initializers/ahoy_captain.rb b/config/initializers/ahoy_captain.rb deleted file mode 100644 index 4945548..0000000 --- a/config/initializers/ahoy_captain.rb +++ /dev/null @@ -1,170 +0,0 @@ -AhoyCaptain.configure do |config| - # ==> Event tracking - # - # View name - # The event you use to dictate if a page view occurred - # config.event.view_name = "$view" - # - # URL column - # The properties that indicate what URL was viewed. Ahoy suggested tracking the - # controller and action for each view by default, so we use that here. - # config.event.url_column = "CONCAT(properties->>'controller', '#', properties->>'action')" - # - # If you have a `url` key in your `properties`, you could: - # config.event.url_column = "properties->>'url'" - # - # URL exists - # A query that indicates if a view event has the correct properties for a page view. - # config.event.url_exists = "JSONB_EXISTS(properties, 'controller') AND JSONB_EXISTS(properties, 'action')" - # - # ==> Models - # - # Ahoy::Event model - # config.models.event = '::Ahoy::Event' - # - # Ahoy::Visit model - # config.models.visit = '::Ahoy::Visit' - # - # - # ==> Theme - # - # https://daisyui.com/docs/themes/ - # config.theme = "dark" - - # ==> Disabled widgets - # Some widgets are more expensive than others. You can disable them here. - # - # Here's the list of widgets: - # * sources - # * campaigns.utm_medium - # * campaigns.utm_source - # * campaigns.utm_term - # * campaigns.utm_content - # * campaigns.utm_campaign - # * top_pages - # * entry_pages - # * landing_pages - # * locations.countries - # * locations.regions - # * locations.cities - # * devices.browsers - # * devices.operating_systems - # * devices.device_types - # - # config.disabled_widgets = [] - - # ==> Time periods - # - # Defaults come from lib/ahoy_captain/period_collection.rb - # - # If you want your own entirely, first call reset. - # config.ranges.reset - # - # Then you can add your own. - # config.ranges.add :param_name, "Label", -> { [3.days.ago, Date.today] } - # - # You can also remove an existing one: - # config.ranges.delete(:mtd) - # - # Or add to the defaults: - # config.ranges.add :custom, "Custom", -> { [6.hours.ago, 2.minutes.ago] } - # - # Or overwrite the defaults: - # config.ranges.add :mtd, "Custom MTD", -> { [2.weeks.ago, Time.current] } - # - # And handle the default range, which will be used if no range is given: - # config.ranges.default = '3d' - # - # The max range if a custom range is sent - # config.ranges.max = 180.days - # - # Set to false to disable custom ranges - # config.ranges.custom = true - # - # For an interval to be considered "realtime" it must not have a secondary item in the range - - # ==> Filters - # - # Defaults come from lib/ahoy_captain/filter_configuration.rb - # - # If you want your own entirely, first call reset. - # config.filters.reset - # - # Then you can add your own. - # - # config.filters.register "Group label" do - # filter label: "Some label", column: :column_name, url: :url_for_options, predicates: [:in, :not_in], multiple: true - # end - # - # You can also remove an existing group: - # - # config.filters.delete("Group label") - # - # Remove a specific filter from a group: - # - # config.filters["Group label"].delete(:column_name) - # - # You can add to an existing group: - # - # config.filters["Group label"].filter label: "Some label", column: :column_name, url: :url_for_options, predicates: [:in, :not_in], multiple: true - - # ==> Caching - # config.cache.enabled = false - # - # Cache store should be an ActiveSupport::Cache::Store instance - # config.cache.store = Rails.cache - # - # TTL - # config.cache.ttl = 1.minute - - #==> Goal tracking - # Your mother told you to have goals. Track those goals. - # - # Basically: - # - # config.goal :unique_id do - # label "Some label here" - # name "The event name you're tracking in your Ahoy::Event table" - # end - # - # Real-world example: - # - # config.goal :appointment_paid do - # label "Appointment Paid" - # name "$appointment.paid" - # end - # - # You can also use queries: - # - # config.goal :appointment_paid do - # label "Appointment Paid" - # query do - # ::Ahoy::Event.where(...) - # end - # end - - # ==> Funnels - # Your mother definitely didn't tell you about conversation rate. - # Except, you're here, so... - # - # Basically: - # - # config.funnel :id do - # label "Some label" - # goal :goal_id_1 - # goal :goal_id_2 - # end - # - # Real-world example: - # - # config.funnel :appointments do - # label "Appointment Workflow" - # goal :appointment_created - # goal :appointment_paid - # end - # - # => Realtime interval - # config.realtime_interval = 30.seconds - # - # How frequently the page should refresh if the interval is realtime -end diff --git a/config/initializers/ahoy_captain_pagy_patch.rb b/config/initializers/ahoy_captain_pagy_patch.rb deleted file mode 100644 index e5e8430..0000000 --- a/config/initializers/ahoy_captain_pagy_patch.rb +++ /dev/null @@ -1,10 +0,0 @@ -# pagy did a massive update, reworked a bunch of shit, but ahoy-captain is still using the old API -# this is a fuck ass workaround to update the version of pagy but not make ahoy-captain crash and burn builds -# https://github.com/ddnexus/pagy/releases/tag/v43.0.0 - -class Pagy - module Frontend - # null - end - Backend = Method unless const_defined?(:Backend) -end diff --git a/config/routes.rb b/config/routes.rb index 764f9af..1b207a0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,7 +21,6 @@ Rails.application.routes.draw do constraints AdminLevelConstraint.new(:superadmin) do mount GoodJob::Engine => "good_job" - mount AhoyCaptain::Engine => "/ahoy_captain" mount Flipper::UI.app(Flipper) => "flipper", as: :flipper namespace :admin do diff --git a/config/skylight.yml b/config/skylight.yml index 1c97f26..718cfe5 100644 --- a/config/skylight.yml +++ b/config/skylight.yml @@ -10,6 +10,5 @@ ignored_endpoints: - Api::Hackatime::V1::HackatimeController#status_bar_today - Api::V1::StatsController#user_stats - Rails::HealthController#show - - AhoyCaptain::StatsController#show - ActionDispatch::Routing::RouteSet#* - ActionDispatch::Static diff --git a/db/migrate/20260204113033_drop_ahoy_tables.rb b/db/migrate/20260204113033_drop_ahoy_tables.rb new file mode 100644 index 0000000..9857384 --- /dev/null +++ b/db/migrate/20260204113033_drop_ahoy_tables.rb @@ -0,0 +1,10 @@ +class DropAhoyTables < ActiveRecord::Migration[8.0] + def up + drop_table :ahoy_events, if_exists: true + drop_table :ahoy_visits, if_exists: true + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/schema.rb b/db/schema.rb index a3aad28..414a80b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2026_02_02_210555) do +ActiveRecord::Schema[8.1].define(version: 2026_02_04_113033) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" enable_extension "pg_stat_statements" @@ -47,52 +47,6 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_02_210555) do t.index ["user_id"], name: "index_admin_api_keys_on_user_id" end - create_table "ahoy_events", force: :cascade do |t| - t.string "name" - t.jsonb "properties" - t.datetime "time" - t.bigint "user_id" - t.bigint "visit_id" - t.index ["name", "time"], name: "index_ahoy_events_on_name_and_time" - t.index ["properties"], name: "index_ahoy_events_on_properties", opclass: :jsonb_path_ops, using: :gin - t.index ["time"], name: "index_ahoy_events_on_time" - t.index ["user_id"], name: "index_ahoy_events_on_user_id" - t.index ["visit_id"], name: "index_ahoy_events_on_visit_id" - end - - create_table "ahoy_visits", force: :cascade do |t| - t.string "app_version" - t.string "browser" - t.string "city" - t.string "country" - t.string "device_type" - t.string "ip" - t.text "landing_page" - t.float "latitude" - t.float "longitude" - t.string "os" - t.string "os_version" - t.string "platform" - t.text "referrer" - t.string "referring_domain" - t.string "region" - t.datetime "started_at" - t.text "user_agent" - t.bigint "user_id" - t.string "utm_campaign" - t.string "utm_content" - t.string "utm_medium" - t.string "utm_source" - t.string "utm_term" - t.string "visit_token" - t.string "visitor_token" - t.index ["started_at"], name: "index_ahoy_visits_on_started_at" - t.index ["started_at"], name: "index_ahoy_visits_started_at_with_referring_domain", where: "(referring_domain IS NOT NULL)" - t.index ["user_id"], name: "index_ahoy_visits_on_user_id" - t.index ["visit_token"], name: "index_ahoy_visits_on_visit_token", unique: true - t.index ["visitor_token", "started_at"], name: "index_ahoy_visits_on_visitor_token_and_started_at" - end - create_table "api_keys", force: :cascade do |t| t.datetime "created_at", null: false t.text "name", null: false