Module: CurrentScope::GatingTripwire

Extended by:
ActiveSupport::Concern
Defined in:
lib/current_scope/gating_tripwire.rb

Overview

A4: an opt-in dev/test tripwire that catches an action which completed WITHOUT being gated by Guard's current_scope_check!. Include it on a base controller you want verified — INCLUDING one that never includes Guard (an API base, a hand-rolled ActionController::Base), which is exactly the ungated case Guard's own after_action could never see.

class ApiController < ActionController::Base
include CurrentScope::GatingTripwire
current_scope_skip_tripwire! only: :health   # mark genuinely-public actions
end

It owns its skip API on purpose: it can NOT reuse skip_before_action :current_scope_check!, because on a controller that never included Guard that callback is undefined and skip_before_action raises ArgumentError at class load — self-defeating on the very controllers the tripwire targets. current_scope_skip_tripwire! skips the tripwire's own after_action instead.

Known blind spot: an after_action does not run when a before_action halts the chain (render/redirect) — so an action that renders straight from a before_action escapes the tripwire. It is a strong dev/test aid, not total coverage (Grape/Rack endpoints are out of reach for the same reason). What a catch DOES is config.gating_tripwire (:raise in dev/test, :warn elsewhere) — :warn logs each ungated controller#action once instead of 500ing, so a real app can inventory its ungated surface.

Class Method Summary collapse

Class Method Details

.reset_warnings!Object

Cleared on engine to_prepare — a reload can change whether a site is gated, so a stale latch is a false all-clear — and by tests.



43
44
45
# File 'lib/current_scope/gating_tripwire.rb', line 43

def reset_warnings!
  @warned = nil
end

.warning_unseen?(site) ⇒ Boolean

The :warn latch. ponytail: a plain Set, not a Mutex — worst case under a race is one extra line, and a flood is the thing being prevented. Per-SITE, not per-process (unlike Guard.ledger_warning_emitted?): the point of :warn is an inventory, so every distinct controller#action must get its own line.

Returns:

  • (Boolean)


36
37
38
39
# File 'lib/current_scope/gating_tripwire.rb', line 36

def warning_unseen?(site)
  @warned ||= Set.new
  @warned.add?(site) ? true : false
end