Aggiunge monitoraggio ops: health check, log scanner, dashboard e notifiche.

Introduce incidenti con dedup, job Sidekiq ogni 3 min, scan log cron, /up/deep,
dashboard /admin/ops e push ntfy; include Sentry opzionale e fix test suite.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-12 08:16:47 +02:00
parent ce8939fffb
commit 52cfffb83f
44 changed files with 1396 additions and 24 deletions

24
backend/db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2026_06_09_100000) do
ActiveRecord::Schema[7.2].define(version: 2026_06_11_120000) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -160,6 +160,28 @@ ActiveRecord::Schema[7.2].define(version: 2026_06_09_100000) do
t.index ["team_id"], name: "index_matches_on_team_id"
end
create_table "ops_incidents", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "kind", null: false
t.string "severity", default: "warning", null: false
t.string "status", default: "open", null: false
t.string "title", null: false
t.text "message"
t.jsonb "metadata", default: {}, null: false
t.string "fingerprint", null: false
t.integer "occurrence_count", default: 1, null: false
t.datetime "first_seen_at", null: false
t.datetime "last_seen_at", null: false
t.datetime "notified_at"
t.datetime "acknowledged_at"
t.datetime "muted_until"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["fingerprint", "status"], name: "index_ops_incidents_on_fingerprint_and_status"
t.index ["fingerprint"], name: "index_ops_incidents_on_fingerprint"
t.index ["last_seen_at"], name: "index_ops_incidents_on_last_seen_at"
t.index ["status", "severity"], name: "index_ops_incidents_on_status_and_severity"
end
create_table "plans", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "slug", null: false
t.string "name", null: false