Class: SiteMapDataPoint
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- SiteMapDataPoint
- Includes:
- Models::DataPointMetrics
- Defined in:
- app/models/site_map_data_point.rb
Overview
== Schema Information
Table name: site_map_data_points
Database name: primary
id :bigint not null, primary key
metric_type :enum not null
period :daterange not null
recorded_at :datetime not null
reference :string
value :decimal(15, 4) not null
created_at :datetime not null
updated_at :datetime not null
site_map_id :bigint not null
source_batch_id :uuid
Indexes
idx_data_points_batch (source_batch_id) WHERE (source_batch_id IS NOT NULL)
idx_data_points_lookup (site_map_id,metric_type,period) USING gist
idx_data_points_metric_period (metric_type,period) USING gist
idx_data_points_reference (site_map_id,metric_type,reference) WHERE (reference IS NOT NULL)
idx_data_points_unique_metric_period (site_map_id, metric_type, period, COALESCE(reference, ''::character varying)) UNIQUE
Foreign Keys
fk_rails_... (site_map_id => site_maps.id) ON DELETE => cascade
SEO time-series metrics per SiteMap. The generic time-series machinery
(scopes, trend/comparison API, period helpers, upsert) lives in
Models::DataPointMetrics; this class holds only the SEO-specific metric
taxonomy and the site_map-named record helpers.
Constant Summary collapse
- GSC_METRICS =
Metric type categories for grouping
%w[gsc_clicks gsc_impressions gsc_ctr gsc_avg_position].freeze
- GA4_METRICS =
Ga4 metrics.
%w[ga4_page_views ga4_sessions ga4_users ga4_bounce_rate ga4_engagement_rate ga4_avg_session_duration].freeze
- AHREFS_METRICS =
Ahrefs metrics.
%w[ahrefs_traffic ahrefs_keywords_count ahrefs_traffic_value ahrefs_domain_rating].freeze
- ADS_METRICS =
Ads metrics.
%w[ads_clicks ads_impressions ads_cost ads_conversions ads_conversion_value].freeze
- KEYWORD_METRICS =
Keyword metrics.
%w[keyword_position keyword_search_volume keyword_traffic_share].freeze
- CLOUDFLARE_METRICS =
Cloudflare edge-analytics metrics (every request at the edge — bots, cache hits, JS-disabled).
%w[cloudflare_requests].freeze
- INVERTED_METRICS =
Metrics where lower is better (for trend interpretation)
%w[ga4_bounce_rate gsc_avg_position keyword_position].freeze
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
-
#reference ⇒ Object
readonly
Keyword metrics carry the keyword in
reference; require it.
Attributes included from Models::DataPointMetrics
Belongs to collapse
Class Method Summary collapse
-
.bulk_record!(site_map:, metrics:, period_start:, period_end:, batch_id: nil, reference: nil) ⇒ Object
Bulk record multiple metrics from a sync (upserts to prevent duplicates).
-
.bulk_record_rows!(rows:) ⇒ void
Bulk-upsert prebuilt SiteMap metric rows that may cover different periods.
-
.record!(site_map:, metric_type:, value:, period_start:, period_end:, reference: nil, batch_id: nil) ⇒ SiteMapDataPoint
Convenience method to record a data point.
Instance Method Summary collapse
- #ads_metric? ⇒ Boolean
- #ahrefs_metric? ⇒ Boolean
- #cloudflare_metric? ⇒ Boolean
- #ga4_metric? ⇒ Boolean
- #gsc_metric? ⇒ Boolean
- #keyword_metric? ⇒ Boolean
Methods included from Models::DataPointMetrics
by_period_start, by_recorded, containing_date, for_metric, for_reference, #inverted_metric?, inverted_metrics, latest, latest_values, overlapping, period_comparison, #period_days, #period_end, #period_start, recent, trend, trend_direction, upsert_data_points!
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#reference ⇒ Object (readonly)
Keyword metrics carry the keyword in reference; require it.
Validations (if => #keyword_metric? ):
61 |
# File 'app/models/site_map_data_point.rb', line 61 validates :reference, presence: true, if: :keyword_metric? |
Class Method Details
.bulk_record!(site_map:, metrics:, period_start:, period_end:, batch_id: nil, reference: nil) ⇒ Object
Bulk record multiple metrics from a sync (upserts to prevent duplicates)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/models/site_map_data_point.rb', line 94 def bulk_record!(site_map:, metrics:, period_start:, period_end:, batch_id: nil, reference: nil) batch_id ||= SecureRandom.uuid now = Time.current rows = metrics.filter_map do |metric_type, value| next if value.nil? { site_map_id: site_map.id, metric_type: metric_type.to_s, value:, period_start:, period_end:, reference:, source_batch_id: batch_id, recorded_at: now } end bulk_record_rows!(rows:) end |
.bulk_record_rows!(rows:) ⇒ void
This method returns an undefined value.
Bulk-upsert prebuilt SiteMap metric rows that may cover different periods.
This keeps a many-page sync to one write while preserving each metric's
actual window (for example 30-day and 90-day visit counts).
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'app/models/site_map_data_point.rb', line 122 def bulk_record_rows!(rows:) normalized_rows = rows.filter_map do |row| next if row[:value].nil? row.merge( metric_type: row.fetch(:metric_type).to_s, period: "[#{row.fetch(:period_start)},#{row.fetch(:period_end)}]", reference: row[:reference] ).except(:period_start, :period_end) end upsert_data_points!(foreign_key: :site_map_id, rows: normalized_rows) end |
.record!(site_map:, metric_type:, value:, period_start:, period_end:, reference: nil, batch_id: nil) ⇒ SiteMapDataPoint
Convenience method to record a data point
74 75 76 77 78 79 80 81 82 83 84 |
# File 'app/models/site_map_data_point.rb', line 74 def record!(site_map:, metric_type:, value:, period_start:, period_end:, reference: nil, batch_id: nil) create!( site_map:, metric_type:, value:, period: period_start..period_end, reference:, source_batch_id: batch_id, recorded_at: Time.current ) end |
Instance Method Details
#ads_metric? ⇒ Boolean
158 159 160 |
# File 'app/models/site_map_data_point.rb', line 158 def ads_metric? ADS_METRICS.include?(metric_type.to_s) end |
#ahrefs_metric? ⇒ Boolean
153 154 155 |
# File 'app/models/site_map_data_point.rb', line 153 def ahrefs_metric? AHREFS_METRICS.include?(metric_type.to_s) end |
#cloudflare_metric? ⇒ Boolean
163 164 165 |
# File 'app/models/site_map_data_point.rb', line 163 def cloudflare_metric? CLOUDFLARE_METRICS.include?(metric_type.to_s) end |
#ga4_metric? ⇒ Boolean
148 149 150 |
# File 'app/models/site_map_data_point.rb', line 148 def ga4_metric? GA4_METRICS.include?(metric_type.to_s) end |
#gsc_metric? ⇒ Boolean
143 144 145 |
# File 'app/models/site_map_data_point.rb', line 143 def gsc_metric? GSC_METRICS.include?(metric_type.to_s) end |
#keyword_metric? ⇒ Boolean
138 139 140 |
# File 'app/models/site_map_data_point.rb', line 138 def keyword_metric? KEYWORD_METRICS.include?(metric_type.to_s) end |