Sitelet https://github.com/errbit/errbit/pull/2832
Skip to content

This is port of The Errbit to SQL by Claude code - #2832

Open
biow0lf wants to merge 65 commits into
mainfrom
claude-code-port-to-sql
Open

biow0lf wants to merge 65 commits into
mainfrom
claude-code-port-to-sql

Conversation

@biow0lf

@biow0lf biow0lf commented May 13, 2026

Copy link
Copy Markdown
Member

No description provided.

@biow0lf biow0lf self-assigned this May 13, 2026
Copilot AI review requested due to automatic review settings May 13, 2026 21:04
Comment thread app/models/errbit/user.rb
end

def reset_password(new_password, new_password_confirmation)
self.password = new_password
Comment thread app/models/errbit/user.rb

def reset_password(new_password, new_password_confirmation)
self.password = new_password
self.password_confirmation = new_password_confirmation

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR begins an ActiveRecord/SQLite-based SQL port alongside the existing Mongoid implementation. It adds new namespaced Errbit models, SQL schema/migrations, database configuration, and model specs/factories for apps, users, and watchers.

Changes:

  • Enables ActiveRecord and Devise ActiveRecord integration with SQLite configuration.
  • Adds SQL-backed Errbit::App, Errbit::User, and Errbit::Watcher models plus migrations/schema.
  • Adds factories, specs, and test support for the new ActiveRecord models.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
Gemfile Adds SQLite and ActiveRecord test helper dependencies.
Gemfile.lock Locks added SQL/test dependencies.
config/application.rb Enables ActiveRecord railtie.
config/database.yml Adds SQLite database configuration for all environments.
config/initializers/devise.rb Loads Devise ActiveRecord ORM support.
app/models/errbit.rb Adds table name prefix for namespaced SQL models.
app/models/errbit/application_record.rb Adds ActiveRecord base class.
app/models/errbit/app.rb Adds SQL-backed app model subset.
app/models/errbit/user.rb Adds SQL-backed user model subset.
app/models/errbit/watcher.rb Adds SQL-backed watcher model.
db/migrate/20260513192604_create_errbit_users.rb Creates SQL users table.
db/migrate/20260513204143_create_errbit_apps.rb Creates SQL apps table.
db/migrate/20260513204638_create_errbit_watchers.rb Creates SQL watchers table.
db/schema.rb Captures generated ActiveRecord schema.
spec/factories/errbit/app_factory.rb Adds SQL app factory.
spec/factories/errbit/user_factory.rb Adds SQL user factory.
spec/factories/errbit/watcher_factory.rb Adds SQL watcher factories.
spec/models/errbit/app_spec.rb Adds SQL app model specs.
spec/models/errbit/user_spec.rb Adds SQL user model specs.
spec/models/errbit/watcher_spec.rb Adds SQL watcher model specs.
spec/support/active_record.rb Adds ActiveRecord database cleanup hooks.
spec/support/shoulda-matchers.rb Adds Shoulda Matchers configuration.
Comments suppressed due to low confidence (5)

app/models/errbit/user.rb:54

  • watching? calls apps, but this ActiveRecord model does not define an apps association (the only association to apps is through watchers, and no has_many :watchers/has_many :apps, through: exists), so calling this method will raise NoMethodError instead of returning whether the user watches the app.
    def watching?(app)
      apps.all.include?(app)
    end

app/models/errbit/app.rb:4

  • These new ActiveRecord models live under the Errbit:: namespace, but the application still routes and controllers use the existing top-level App, User, and Watcher classes (for example devise_for :users maps to User, and controllers query App). As written, this SQL model is not used by the production code path, so the port will continue reading/writing Mongoid models instead of these tables.
module Errbit
  class App < ApplicationRecord

app/models/errbit/app.rb:28

  • The SQL App model only implements the instance watched_by? helper, but the existing deletion flow calls the class-level App.watched_by(user) scope to find apps before removing a user. If this model replaces the Mongoid App, that code path will raise NoMethodError and user deletion will not clean up watcher rows.
    def watched_by?(user)
      watchers.where(errbit_user_id: user.id).exists?
    end

app/models/errbit/app.rb:4

  • The existing apps index sorts apps in Ruby (app_scope.to_a.sort), which relies on the Mongoid App including Comparable and defining <=>. This ActiveRecord port omits that comparison method, so wiring it into the existing controller would make the apps index fail with an object comparison error.
module Errbit
  class App < ApplicationRecord

app/models/errbit/app.rb:4

  • This App port does not define the problems association that the existing controllers and views call (app.problems for app pages, feeds, counts, and problem searches). If this replaces the Mongoid model, those core app/error pages will raise instead of showing errors.
module Errbit
  class App < ApplicationRecord

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# frozen_string_literal: true

RSpec.configure do |config|
config.before(:suite) do
Comment thread config/database.yml
Comment on lines +15 to +16
<<: *default
database: storage/production.sqlite3
Comment on lines +8 to +9
t.string :name
t.string :api_key
## Token authenticatable
t.string :authentication_token

t.string :name
Comment on lines +8 to +9
t.references :errbit_user, foreign_key: true
t.string :email
t.string :current_app_version
t.boolean :notify_all_users, null: false, default: false
t.boolean :notify_on_errs, null: false, default: true
t.text :email_at_notices
Comment on lines +37 to +40
def email_choosen
email.blank? ? "chosen" : ""
end

Comment on lines +19 to +20
attr_accessor :_watcher_type

attr_accessor :_watcher_type

def watcher_type
@_watcher_type ||= email.present? ? "email" : "user"
Comment thread app/models/errbit/user.rb
Comment on lines +87 to +89
self.class.validators_on(:password).map { |v| v.validate_each(self, :password, password) }
return false if errors.any?

app.update(app_params)

if app.save
if app.update(app_params)
class HealthController < ActionController::Base # rubocop:disable Rails/ApplicationController
def api_key_tester
app = App.where(api_key: params[:api_key]).first
app = Errbit::App.where(api_key: params[:api_key]).first
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch 2 times, most recently from 3e04589 to 2bea878 Compare May 19, 2026 09:57
@biow0lf
biow0lf requested a review from Copilot May 19, 2026 09:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 194 out of 195 changed files in this pull request and generated 8 comments.

Comment thread app/models/errbit/user.rb
Comment on lines +78 to +80
def watching?(app)
apps.all.include?(app)
end
Comment on lines +84 to +87
def backtrace_lines(problem)
notice = Errbit::NoticeDecorator.new(problem.notices.last)
return unless notice


<br>

<p><%= @comment.body.to_s.gsub("\n", "<br>").html_safe %></p>
Comment thread spec/requests/notices_controller_spec.rb
expect(described_class.table_name).to eq("errbit_watchers")
end

context "validations" do
Comment thread config/database.yml
Comment on lines +14 to +16
production:
<<: *default
database: storage/production.sqlite3
Comment thread spec/system/users_spec.rb
Comment on lines +5 to +12
RSpec.describe "Users", type: :system do
describe "#index" do
# current_user = create(:errbit_user, name: "Ihor Zubkov")
#
# sign_in(current_user)
#
# visit users_path
end
Comment on lines +8 to +13
t.boolean :error_class, null: false, default: true
t.boolean :message, null: false, default: true
t.integer :backtrace_lines, default: -1
t.boolean :component, null: false, default: true
t.boolean :action, null: false, default: true
t.boolean :environment_name, null: false, default: true
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch 2 times, most recently from c63ad6c to 26da3b5 Compare May 20, 2026 02:52
@biow0lf
biow0lf requested a review from Copilot May 20, 2026 02:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 202 out of 203 changed files in this pull request and generated 8 comments.

Comment on lines +84 to +90
def backtrace_lines(problem)
notice = Errbit::NoticeDecorator.new(problem.notices.last)
return unless notice

backtrace = notice.backtrace
return unless backtrace

Comment on lines +9 to +20
def self.run
count = Errbit::Problem.count
puts format(LOG_START, count)

Errbit::Problem.find_each.with_index do |problem, index|
problem.recache
problem.destroy if problem.notices_count == 0

next unless (index + 1) % LOG_EVERY == 0

puts format(LOG_ITR, index * 100 / count, count - index)
end
Comment on lines +9 to +19
def self.run
count = Errbit::Notice.count
puts format(LOG_START, count)

Errbit::Notice.find_each.with_index do |notice, index|
refingerprint(notice)

next unless (index + 1) % LOG_EVERY == 0

puts format(LOG_ITR, index * 100 / count, count - index)
end
Comment on lines +21 to +25
puts "Finished generating notice fingerprints"
puts "Destroying orphaned err records"

Errbit::Err.find_each { |err| err.destroy if err.notices.empty? }

Comment on lines 29 to 41
desc "Remove notices in batch"
task :notices_delete, [:problem_id] => [:environment] do
task :notices_delete, [:problem_id] => [:environment] do |_task, args|
BATCH_SIZE = 1000
if args[:problem_id]
item_count = Problem.find(args[:problem_id]).notices.count
item_count = Errbit::Problem.find(args[:problem_id]).notices.count
removed_count = 0
puts "Notices to remove: #{item_count}"
while item_count > 0
Problem.find(args[:problem_id]).notices.limit(BATCH_SIZE).each do |notice|
notice.remove
Errbit::Problem.find(args[:problem_id]).notices.limit(BATCH_SIZE).each do |notice|
notice.destroy
removed_count += 1
end
item_count -= BATCH_SIZE
Comment on lines +37 to +42
<p class="heading">COMMENT:</p>

<br>

<p><%= @comment.body.to_s.gsub("\n", "<br>").html_safe %></p>
</div>
Comment thread spec/system/users_spec.rb
Comment on lines +5 to +12
RSpec.describe "Users", type: :system do
describe "#index" do
# current_user = create(:errbit_user, name: "Ihor Zubkov")
#
# sign_in(current_user)
#
# visit users_path
end
Comment on lines +7 to +12
def initialize(*problems)
problems = problems.flatten.uniq
@merged_problem = problems[0]
@child_problems = problems[1..]
fail ArgumentError, "need almost 2 uniq different problems" if @child_problems.empty?
end
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch 2 times, most recently from cb45f31 to 08c3a4c Compare May 23, 2026 19:48
@biow0lf
biow0lf requested a review from Copilot May 23, 2026 19:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 202 out of 203 changed files in this pull request and generated 7 comments.

Comment thread app/models/errbit/user.rb
Comment on lines +78 to +80
def watching?(app)
apps.all.include?(app)
end
Comment on lines +84 to +94
def backtrace_lines(problem)
notice = Errbit::NoticeDecorator.new(problem.notices.last)
return unless notice

backtrace = notice.backtrace
return unless backtrace

output = +""
backtrace.lines[0..4].each { |line| output << backtrace_line(line) }
"```#{output}```"
end
Comment thread config/database.yml
Comment on lines +14 to +16
production:
<<: *default
database: storage/production.sqlite3
Comment thread spec/system/users_spec.rb
Comment on lines +5 to +12
RSpec.describe "Users", type: :system do
describe "#index" do
# current_user = create(:errbit_user, name: "Ihor Zubkov")
#
# sign_in(current_user)
#
# visit users_path
end
Comment on lines +12 to +16
it "saves a new problem for the app" do
expect {
post "/notifier_api/v2/notices", params: {data: xml}
expect(response).to be_successful
end.to change(errbit_app.problems, :count).by(1)
}.to change { errbit_app.problems.count }.by(1)
expect(f_1).not_to eq(f_2)
end

context "two backtraces with the same first two lines" do
Comment on lines +5 to +8
FIELDS = [
:name, :username, :email, :password, :github_login, :per_page, :time_zone,
:password, :password_confirmation
].freeze
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch from 08c3a4c to 8e1f898 Compare May 25, 2026 11:15
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch 2 times, most recently from 40c0729 to 45e0c13 Compare June 4, 2026 16:00
@biow0lf
biow0lf force-pushed the claude-code-port-to-sql branch from 45e0c13 to 10e6fb9 Compare July 5, 2026 21:28

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants