Class: CompletionKit::PromptServe

Inherits:
ApplicationRecord show all
Defined in:
app/models/completion_kit/prompt_serve.rb

Overview

One row per prompt per day, counting how often that prompt was fetched by a consumer. Rolled up daily rather than stored per request so the table stays bounded by (prompts x days) instead of growing with traffic.

family_key is denormalised so a family's serving history survives deleting an individual version, which prompt_id alone would not.

Constant Summary

Constants inherited from ApplicationRecord

ApplicationRecord::TenantScopedUniquenessValidator

Class Method Summary collapse

Class Method Details

.record!(prompt) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
# File 'app/models/completion_kit/prompt_serve.rb', line 13

def self.record!(prompt)
  today = Date.current
  now = Time.current
  scope = where(prompt_id: prompt.id, served_on: today)

  return if scope.update_all(["serve_count = serve_count + 1, last_served_at = ?", now]).positive?

  create!(prompt_id: prompt.id, family_key: prompt.family_key, served_on: today,
          serve_count: 1, last_served_at: now)
rescue ActiveRecord::RecordNotUnique
  scope.update_all(["serve_count = serve_count + 1, last_served_at = ?", now])
end

.summary_for(prompt, windows: [7, 30]) ⇒ Object

Totals for the whole prompt family, so publishing a new version does not reset the number a user is watching.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/models/completion_kit/prompt_serve.rb', line 28

def self.summary_for(prompt, windows: [7, 30])
  rows = where(family_key: prompt.family_key)
         .pluck(:served_on, :serve_count, :last_served_at)
  return { total: 0, last_served_at: nil }.merge(windows.index_with { 0 }) if rows.empty?

  summary = { total: rows.sum { |_, count, _| count },
              last_served_at: rows.filter_map { |_, _, at| at }.max }
  windows.each_with_object(summary) do |days, acc|
    cutoff = Date.current - (days - 1)
    acc[days] = rows.sum { |on, count, _| on >= cutoff ? count : 0 }
  end
end