Module: ForestAdminAgent::AuditTrail::Sql::Migrations
- Defined in:
- lib/forest_admin_agent/audit_trail/sql/migrations.rb
Overview
The audit table's schema, as an ordered, append-only list. Nothing has shipped yet, so this is still a
single entry; once a release is out, never edit one — add another, since a database out there has
already recorded the earlier ones as applied. Every statement tolerates being replayed
(if_not_exists), which is what makes a lost race harmless.
Constant Summary collapse
- ALL =
[ { name: '001-create-audit-logs', up: lambda do |connection, table| # if_not_exists: a non-PG race (no advisory lock) can let two instances both reach here. connection.create_table(table, if_not_exists: true) do |t| t.datetime :timestamp, null: false t.string :operation, null: false t.string :collection, null: false # Nullable, because a create's pending row has no id yet; text, because a packed composite id # outgrows a varchar. t.text :record_id # No default on purpose: every write sets it, so a row arriving without one is a bug worth # hearing about rather than a row that quietly claims to be done. t.string :status, null: false t.integer :user_id # Denormalised from the caller at write time: who acted then, not whoever holds that id today. t.text :user_first_name t.text :user_last_name t.text :user_email # Set only on an update that moved a writable primary key: the id the row was filed under # before. What lets a history query follow a record across a rename. t.text :previous_record_id # Smart-action rows only. t.text :action_name t.string :correlation_key t.json :previous_values t.json :new_values end base = table.split('.').last # MySQL cannot index unbounded TEXT, so that one index needs a length prefix. record_id_index = { name: "#{base}_record_id", if_not_exists: true } record_id_index[:length] = 255 if connection.adapter_name.downcase.match?(/mysql|maria/) connection.add_index(table, :record_id, **record_id_index) connection.add_index(table, :correlation_key, name: "#{base}_correlation_key", if_not_exists: true) connection.add_index(table, :user_id, name: "#{base}_user_id", if_not_exists: true) end } ].freeze