moderate 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/CHANGELOG.md +33 -0
- data/README.md +4 -0
- data/db/migrate/20261018200000_add_pending_key_to_moderate_flags.rb +1 -1
- data/db/migrate/20261018210000_add_retention_and_classifications_to_moderate_tables.rb +1 -1
- data/db/migrate/20261019120000_change_moderate_classifications_record_id_to_string.rb +103 -0
- data/gemfiles/rails_8.0.gemfile +1 -0
- data/gemfiles/rails_8.1.gemfile +1 -0
- data/lib/generators/moderate/install_generator.rb +6 -2
- data/lib/generators/moderate/templates/create_moderate_tables.rb.erb +13 -13
- data/lib/moderate/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 855c6c868845a30cb2cc8ace230bb926b77b530eff47ee975b3137ceea0e6278
|
|
4
|
+
data.tar.gz: 87ba2fc546cadd8cdf0e0b53aca9936e2627f810c4ea685884c1742a09ea9565
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 416181ed2e12216dbd154511a5eec55d0f2e4ff9d6840c9f29a3b1b8e1ef126b241dbfa8f8d5145270a5af1cd97949bd1105ea41829da3f5a163ecaa89692885
|
|
7
|
+
data.tar.gz: fe0e4aadad27c758d72928ff95148a992b65e79eef3ba30946a8c76438b9e580536585baa03fa2ddafc363cf4741084291af25e3448de59b6d59298f5dffb09e
|
data/.rubocop.yml
CHANGED
|
@@ -101,3 +101,10 @@ Lint/UselessAccessModifier:
|
|
|
101
101
|
# under a `raise`, or indented under a keyword); the code uses both.
|
|
102
102
|
Layout/LineEndStringConcatenationIndentation:
|
|
103
103
|
Enabled: false
|
|
104
|
+
|
|
105
|
+
# The gem's own migrations are copied into host apps, many of them on Rails' omakase
|
|
106
|
+
# style, which spaces array brackets (`[ :a, :b ]`); they follow that style, checked by
|
|
107
|
+
# test/generators/omakase_style_test.rb.
|
|
108
|
+
Layout/SpaceInsideArrayLiteralBrackets:
|
|
109
|
+
Exclude:
|
|
110
|
+
- "db/migrate/**/*"
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,39 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.0.1] - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Upgrading from 1.0.0
|
|
10
|
+
|
|
11
|
+
- **One migration: run `bin/rails moderate:install:migrations` (if your app holds copies of
|
|
12
|
+
the gem's migrations, `*.moderate.rb`; boot tells you if you forget), then
|
|
13
|
+
`bin/rails db:migrate`.** `db/migrate/20261019120000_change_moderate_classifications_record_id_to_string.rb`
|
|
14
|
+
makes `moderate_classifications.record_id` a string and caps it and `digest` at 64
|
|
15
|
+
characters (which keeps the table's unique index within MySQL's 3072-byte key limit).
|
|
16
|
+
Existing rows keep their ids, as strings. Polymorphic ids compare bytewise on every
|
|
17
|
+
database (on MySQL and Trilogy the column is `utf8mb4_bin`, as `pending_key` is). Guarded
|
|
18
|
+
(a no-op when the column is already a string) and reversible: `down` turns `record_id`
|
|
19
|
+
back into your primary-key type, and first refuses with `ActiveRecord::IrreversibleMigration`,
|
|
20
|
+
naming how many, while any row holds an id that type can't hold (for bigint: anything but
|
|
21
|
+
an integer within the signed 64-bit range, negatives included; for uuid: anything but the
|
|
22
|
+
canonical 8-4-4-4-12 form, in either case); delete those
|
|
23
|
+
classification rows (bookkeeping, re-created on the next classification) and run it
|
|
24
|
+
again.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Attachment classification works in apps that mix uuid and bigint primary keys.**
|
|
29
|
+
1.0.0 created `moderate_classifications.record_id` with the app's one primary-key type,
|
|
30
|
+
so records of the other kind couldn't be claimed or marked classified. It is a string
|
|
31
|
+
now (above).
|
|
32
|
+
- **The migrations an app receives pass a Rails omakase app's RuboCop.** The gem's
|
|
33
|
+
migrations and the install template use omakase's array-bracket spacing, and the copies
|
|
34
|
+
`rails generate moderate:install` writes keep the blank line after the magic comment,
|
|
35
|
+
as `bin/rails moderate:install:migrations` (Rails' own copy) does. A test runs
|
|
36
|
+
rubocop-rails-omakase on both kinds of copies and on the generated initializer, so a host
|
|
37
|
+
needs no exclude for them. The README also explains the `.moderate` suffix Rails adds to
|
|
38
|
+
copied migrations' names in `db:migrate:status`.
|
|
39
|
+
|
|
7
40
|
## [1.0.0] - 2026-10-19
|
|
8
41
|
|
|
9
42
|
The first stable release. The public API is frozen until 2.0: everything listed in the
|
data/README.md
CHANGED
|
@@ -527,6 +527,10 @@ Audit events (`Moderate::Event::AUDIT_NAMES`): `:report_received` · `:appeal_re
|
|
|
527
527
|
|
|
528
528
|
Every hook receives one `Moderate::Event`: `#name` · `#subject` · `#actor` · `#recipients` · `#payload` (always with `:summary`) · `#occurred_at` · `#id` · `#summary` · `#to_h`. The contract for `config.notify`: it is called once per event, after the transaction that caused it commits (never for a rolled-back change); a truthy return means "handed off" (for a DSA notice the gem then treats the Art. 16(4) receipt as sent); a decision notice counts as delivered only when your notifier confirms it with `Moderate.delivered!(report, :decision | :affected_user)` from the mail's actual delivery, which stamps `decision_notified_at` / `affected_user_notified_at` once and starts the appeal window from then (DSA Art. 20(2)); an exception is swallowed, audited as `:notify_failed`, and never rolls back the decision. `config.audit` follows the same rules and its return value is ignored. Payload keys may be added in a minor release, never removed or renamed.
|
|
529
529
|
|
|
530
|
+
## Upgrading within 1.0
|
|
531
|
+
|
|
532
|
+
**1.0.1 adds a migration** (`moderate_classifications.record_id` becomes a string, so apps that mix uuid and bigint primary keys classify attachments on both): run `bin/rails moderate:install:migrations` if your app holds copies of the gem's migrations, then `bin/rails db:migrate`. The copies follow the RuboCop style of a new Rails app (rubocop-rails-omakase), so they need no exclude. In `bin/rails db:migrate:status` a copied migration's name ends in `.moderate` (`Add pending key to moderate flags.moderate`): that is Rails' own naming for migrations copied from an engine, not a broken copy.
|
|
533
|
+
|
|
530
534
|
## Upgrading from a 1.0 beta
|
|
531
535
|
|
|
532
536
|
**1.0.0 adds a migration** (retention columns and `moderate_classifications`): run `bin/rails moderate:install:migrations` if your app holds copies of the gem's migrations (`*.moderate.rb`, as every app installed from 1.0.0.beta4 on does), then `bin/rails db:migrate`. An app without copies gets it through the engine, like beta4's. **A missed copy is no longer silent:** at boot, an app that holds copies but not one of this version's migrations raises `Moderate::ConfigurationError` naming it and the command that copies it (under a rake task, such as that command itself, it logs instead); `config.migration_copies_check = :log` or `:off` changes that.
|
|
@@ -102,7 +102,7 @@ class AddPendingKeyToModerateFlags < ActiveRecord::Migration[7.1]
|
|
|
102
102
|
newest[key] = flag if newest[key].nil? || flag.created_at > newest[key].created_at
|
|
103
103
|
end
|
|
104
104
|
taken = Flag.where.not(pending_key: nil).pluck(:pending_key).to_set
|
|
105
|
-
newest.except(*taken).to_h { |key, flag| [flag.id, key] }
|
|
105
|
+
newest.except(*taken).to_h { |key, flag| [ flag.id, key ] }
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
# The keys to write and the keys already written, in a temporary table whose key
|
|
@@ -98,6 +98,6 @@ class AddRetentionAndClassificationsToModerateTables < ActiveRecord::Migration[8
|
|
|
98
98
|
def key_types
|
|
99
99
|
config = Rails.configuration.generators
|
|
100
100
|
setting = config.options[config.orm][:primary_key_type]
|
|
101
|
-
[setting || :primary_key, setting || :bigint]
|
|
101
|
+
[ setting || :primary_key, setting || :bigint ]
|
|
102
102
|
end
|
|
103
103
|
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# 1.0.1: moderate_classifications.record_id becomes a string, so an app that mixes
|
|
4
|
+
# uuid and bigint primary keys records classifications for every kind of record (1.0.0
|
|
5
|
+
# created it with the app's one primary-key type). `digest` (always 16 hex characters)
|
|
6
|
+
# and `record_id` (a uuid is 36, a bigint at most 20) are capped at 64 characters, so
|
|
7
|
+
# the unique index on (record_type, record_id, field, digest) stays within MySQL's
|
|
8
|
+
# 3072-byte key limit.
|
|
9
|
+
#
|
|
10
|
+
# On MySQL (and Trilogy) record_id is utf8mb4_bin, so ids compare bytewise, as they do
|
|
11
|
+
# on PostgreSQL and SQLite: "abc" and "ABC" are two records.
|
|
12
|
+
#
|
|
13
|
+
# Ships with the gem: `rails generate moderate:install` copies it after the others,
|
|
14
|
+
# an app holding copies gets it with `bin/rails moderate:install:migrations`, and an
|
|
15
|
+
# app without copies gets it through the engine. Guarded, so it is a no-op when the
|
|
16
|
+
# column is already a string, and reversible: `down` turns record_id back into the
|
|
17
|
+
# app's primary-key type, and first refuses (naming how many) if any row holds an id
|
|
18
|
+
# of the other key kind, which that type can't keep.
|
|
19
|
+
class ChangeModerateClassificationsRecordIdToString < ActiveRecord::Migration[8.0]
|
|
20
|
+
# The table as it is, not the app's model: a migration must not depend on code.
|
|
21
|
+
class Classification < ActiveRecord::Base
|
|
22
|
+
self.table_name = "moderate_classifications"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The canonical 8-4-4-4-12 form, either case: what Rails writes for a uuid key. (Other
|
|
26
|
+
# forms PostgreSQL accepts as uuid input, braces or no hyphens, aren't expected here.)
|
|
27
|
+
UUID = /\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/i
|
|
28
|
+
BIGINT = /\A-?\d+\z/
|
|
29
|
+
BIGINT_RANGE = (-(2**63))..((2**63) - 1)
|
|
30
|
+
|
|
31
|
+
def up
|
|
32
|
+
return unless table_exists?(:moderate_classifications)
|
|
33
|
+
return if column_type(:record_id) == :string
|
|
34
|
+
|
|
35
|
+
change_column :moderate_classifications, :digest, :string, limit: 64, null: false
|
|
36
|
+
change_column :moderate_classifications, :record_id, :string, limit: 64, null: false, **binary, **cast("varchar")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def down
|
|
40
|
+
return unless table_exists?(:moderate_classifications)
|
|
41
|
+
return unless column_type(:record_id) == :string
|
|
42
|
+
|
|
43
|
+
key_type = key_type_setting || :bigint
|
|
44
|
+
refuse_unfit_ids!(key_type)
|
|
45
|
+
change_column :moderate_classifications, :record_id, key_type, null: false, **cast(key_type == :uuid ? "uuid" : "bigint")
|
|
46
|
+
change_column :moderate_classifications, :digest, :string, null: false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Rows whose record_id the app's key type can't hold (a uuid in a bigint app, or the
|
|
52
|
+
# reverse): rolling back would fail midway on PostgreSQL and MySQL, or keep the text
|
|
53
|
+
# in an integer column on SQLite.
|
|
54
|
+
def refuse_unfit_ids!(key_type)
|
|
55
|
+
unfit = unfit_ids_count(key_type)
|
|
56
|
+
return if unfit.zero?
|
|
57
|
+
|
|
58
|
+
raise ActiveRecord::IrreversibleMigration,
|
|
59
|
+
"#{unfit} moderate_classifications row(s) hold a record_id that isn't a #{key_type} id, so record_id " \
|
|
60
|
+
"can't go back to #{key_type}. Delete those classification rows first; they are bookkeeping, " \
|
|
61
|
+
"re-created on the next classification."
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def unfit_ids_count(key_type)
|
|
65
|
+
Classification.reset_column_information
|
|
66
|
+
unfit = 0
|
|
67
|
+
Classification.in_batches(of: 1000) do |batch|
|
|
68
|
+
unfit += batch.pluck(:record_id).count { |id| !fits?(id.to_s, key_type) }
|
|
69
|
+
end
|
|
70
|
+
unfit
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# A uuid in the canonical form; a bigint: an optionally negative integer within the
|
|
74
|
+
# signed 64-bit range (a longer one would fail the conversion, not this refusal).
|
|
75
|
+
def fits?(id, key_type)
|
|
76
|
+
return UUID.match?(id) if key_type == :uuid
|
|
77
|
+
|
|
78
|
+
BIGINT.match?(id) && BIGINT_RANGE.cover?(id.to_i)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def mysql?
|
|
82
|
+
connection.adapter_name.downcase.match?(/mysql|trilogy/)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Bytewise comparison on MySQL, whose default collation ignores case.
|
|
86
|
+
def binary
|
|
87
|
+
mysql? ? { collation: "utf8mb4_bin" } : {}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def column_type(name)
|
|
91
|
+
connection.columns(:moderate_classifications).find { |column| column.name == name.to_s }&.type
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# PostgreSQL needs the conversion spelled out; MySQL and SQLite convert by themselves.
|
|
95
|
+
def cast(type)
|
|
96
|
+
connection.adapter_name.downcase.include?("postg") ? { using: "record_id::#{type}" } : {}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def key_type_setting
|
|
100
|
+
config = Rails.configuration.generators
|
|
101
|
+
config.options[config.orm][:primary_key_type]
|
|
102
|
+
end
|
|
103
|
+
end
|
data/gemfiles/rails_8.0.gemfile
CHANGED
data/gemfiles/rails_8.1.gemfile
CHANGED
|
@@ -66,11 +66,15 @@ module Moderate
|
|
|
66
66
|
|
|
67
67
|
private
|
|
68
68
|
|
|
69
|
-
# As Rails' engine copy writes it: magic comments first
|
|
69
|
+
# As Rails' engine copy writes it: magic comments first (with the blank line after
|
|
70
|
+
# them that the source has, which RuboCop's omakase style asks for), then where it
|
|
71
|
+
# came from, then the rest.
|
|
70
72
|
def copied_migration(source, version)
|
|
71
73
|
body = File.read(source)
|
|
72
74
|
magic = body[/\A(?:#.*\b(?:coding|frozen_string_literal):.*\n)+/].to_s
|
|
73
|
-
|
|
75
|
+
rest = body.delete_prefix(magic)
|
|
76
|
+
magic += "\n" if !magic.empty? && rest.start_with?("\n")
|
|
77
|
+
"#{magic}# This migration comes from moderate (originally #{version})\n#{rest.delete_prefix("\n")}"
|
|
74
78
|
end
|
|
75
79
|
|
|
76
80
|
def migration_version
|
|
@@ -70,12 +70,12 @@ class CreateModerateTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
70
70
|
t.timestamps
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
add_index :moderate_reports, [:reportable_type, :reportable_id], name: "index_moderate_reports_on_reportable"
|
|
74
|
-
add_index :moderate_reports, [:reported_user_id, :status], name: "index_moderate_reports_on_reported_user_id_and_status"
|
|
75
|
-
add_index :moderate_reports, [:reporter_id, :created_at], name: "index_moderate_reports_on_reporter_id_and_created_at"
|
|
76
|
-
add_index :moderate_reports, [:status, :created_at], name: "index_moderate_reports_on_status_and_created_at"
|
|
77
|
-
add_index :moderate_reports, [:intake_kind, :created_at], name: "index_moderate_reports_on_intake_kind_and_created_at"
|
|
78
|
-
add_index :moderate_reports, [:legal_reason, :created_at], name: "index_moderate_reports_on_legal_reason_and_created_at"
|
|
73
|
+
add_index :moderate_reports, [ :reportable_type, :reportable_id ], name: "index_moderate_reports_on_reportable"
|
|
74
|
+
add_index :moderate_reports, [ :reported_user_id, :status ], name: "index_moderate_reports_on_reported_user_id_and_status"
|
|
75
|
+
add_index :moderate_reports, [ :reporter_id, :created_at ], name: "index_moderate_reports_on_reporter_id_and_created_at"
|
|
76
|
+
add_index :moderate_reports, [ :status, :created_at ], name: "index_moderate_reports_on_status_and_created_at"
|
|
77
|
+
add_index :moderate_reports, [ :intake_kind, :created_at ], name: "index_moderate_reports_on_intake_kind_and_created_at"
|
|
78
|
+
add_index :moderate_reports, [ :legal_reason, :created_at ], name: "index_moderate_reports_on_legal_reason_and_created_at"
|
|
79
79
|
add_index :moderate_reports, :notifier_email, name: "index_moderate_reports_on_notifier_email"
|
|
80
80
|
add_index :moderate_reports, :resolved_at, name: "index_moderate_reports_on_resolved_at"
|
|
81
81
|
add_index :moderate_reports, :appeal_deadline_at, name: "index_moderate_reports_on_appeal_deadline_at"
|
|
@@ -106,7 +106,7 @@ class CreateModerateTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
106
106
|
t.timestamps
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
add_index :moderate_blocks, [:blocker_id, :blocked_id], unique: true, name: "index_moderate_blocks_on_blocker_id_and_blocked_id"
|
|
109
|
+
add_index :moderate_blocks, [ :blocker_id, :blocked_id ], unique: true, name: "index_moderate_blocks_on_blocker_id_and_blocked_id"
|
|
110
110
|
add_index :moderate_blocks, :created_at, name: "index_moderate_blocks_on_created_at"
|
|
111
111
|
|
|
112
112
|
add_check_constraint :moderate_blocks,
|
|
@@ -147,9 +147,9 @@ class CreateModerateTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
147
147
|
t.timestamps
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
add_index :moderate_flags, [:flaggable_type, :flaggable_id, :field], name: "index_moderate_flags_on_target_and_field"
|
|
151
|
-
add_index :moderate_flags, [:owner_id, :status], name: "index_moderate_flags_on_owner_id_and_status"
|
|
152
|
-
add_index :moderate_flags, [:status, :created_at], name: "index_moderate_flags_on_status_and_created_at"
|
|
150
|
+
add_index :moderate_flags, [ :flaggable_type, :flaggable_id, :field ], name: "index_moderate_flags_on_target_and_field"
|
|
151
|
+
add_index :moderate_flags, [ :owner_id, :status ], name: "index_moderate_flags_on_owner_id_and_status"
|
|
152
|
+
add_index :moderate_flags, [ :status, :created_at ], name: "index_moderate_flags_on_status_and_created_at"
|
|
153
153
|
|
|
154
154
|
# moderate_flags.pending_key (at most one PENDING flag per content + field) is NOT
|
|
155
155
|
# here: the gem's own AddPendingKeyToModerateFlags creates it, for a fresh install
|
|
@@ -188,8 +188,8 @@ class CreateModerateTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
188
188
|
t.timestamps
|
|
189
189
|
end
|
|
190
190
|
|
|
191
|
-
add_index :moderate_appeals, [:report_id, :created_at], name: "index_moderate_appeals_on_report_id_and_created_at"
|
|
192
|
-
add_index :moderate_appeals, [:status, :created_at], name: "index_moderate_appeals_on_status_and_created_at"
|
|
191
|
+
add_index :moderate_appeals, [ :report_id, :created_at ], name: "index_moderate_appeals_on_report_id_and_created_at"
|
|
192
|
+
add_index :moderate_appeals, [ :status, :created_at ], name: "index_moderate_appeals_on_status_and_created_at"
|
|
193
193
|
add_index :moderate_appeals, :appellant_email, name: "index_moderate_appeals_on_appellant_email"
|
|
194
194
|
|
|
195
195
|
# The 1.0 retention columns (redacted_at, held_until) and moderate_classifications
|
|
@@ -209,7 +209,7 @@ class CreateModerateTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
209
209
|
setting = config.options[config.orm][:primary_key_type]
|
|
210
210
|
primary_key_type = setting || :primary_key
|
|
211
211
|
foreign_key_type = setting || :bigint
|
|
212
|
-
[primary_key_type, foreign_key_type]
|
|
212
|
+
[ primary_key_type, foreign_key_type ]
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
def json_column_type
|
data/lib/moderate/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moderate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rameerez
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-10-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activerecord
|
|
@@ -141,6 +141,7 @@ files:
|
|
|
141
141
|
- context7.json
|
|
142
142
|
- db/migrate/20261018200000_add_pending_key_to_moderate_flags.rb
|
|
143
143
|
- db/migrate/20261018210000_add_retention_and_classifications_to_moderate_tables.rb
|
|
144
|
+
- db/migrate/20261019120000_change_moderate_classifications_record_id_to_string.rb
|
|
144
145
|
- docs/chats.md
|
|
145
146
|
- docs/compliance.md
|
|
146
147
|
- docs/configuration.md
|
|
@@ -216,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
216
217
|
- !ruby/object:Gem::Version
|
|
217
218
|
version: '0'
|
|
218
219
|
requirements: []
|
|
219
|
-
rubygems_version: 3.6.
|
|
220
|
+
rubygems_version: 3.6.2
|
|
220
221
|
specification_version: 4
|
|
221
222
|
summary: Let your Rails users report content and block each other (Trust & Safety)
|
|
222
223
|
test_files: []
|