Class: Smplkit::Audit::Events

Inherits:
Object
  • Object
show all
Defined in:
lib/smplkit/audit/events.rb

Overview

Audit events surface — accessed via client.audit.events.

#create is fire-and-forget per ADR-047 §2.6 — the call enqueues the event onto an in-memory bounded buffer and returns immediately. #list and #get are synchronous.

Instance Method Summary collapse

Constructor Details

#initialize(api) ⇒ Events

Returns a new instance of Events.



11
12
13
14
# File 'lib/smplkit/audit/events.rb', line 11

def initialize(api)
  @api = api
  @buffer = EventBuffer.new(api)
end

Instance Method Details

#_closeObject



90
91
92
# File 'lib/smplkit/audit/events.rb', line 90

def _close
  @buffer.close
end

#create(action:, resource_type:, resource_id:, occurred_at: nil, snapshot: nil, data: nil, idempotency_key: nil) ⇒ Object

Enqueue an audit event for asynchronous delivery.

Customer attempts to record events with resource_type starting with smpl. are rejected by the server with a 403 (the buffer logs and drops permanent failures).

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/smplkit/audit/events.rb', line 21

def create(action:, resource_type:, resource_id:,
           occurred_at: nil, snapshot: nil, data: nil, idempotency_key: nil)
  raise ArgumentError, "action is required" if action.nil? || action.to_s.empty?
  raise ArgumentError, "resource_type is required" if resource_type.nil? || resource_type.to_s.empty?
  raise ArgumentError, "resource_id is required" if resource_id.nil? || resource_id.to_s.empty?

  attrs = SmplkitGeneratedClient::Audit::Event.new(
    action: action,
    resource_type: resource_type,
    resource_id: resource_id,
    occurred_at: occurred_at,
    snapshot: snapshot,
    data: data
  )
  resource = SmplkitGeneratedClient::Audit::EventResource.new(
    id: "",
    type: "event",
    attributes: attrs
  )
  body = SmplkitGeneratedClient::Audit::EventResponse.new(data: resource)
  @buffer.enqueue(body, idempotency_key)
end

#flush(timeout: 5.0) ⇒ Object

Block until the in-memory buffer is drained or the timeout elapses.



85
86
87
# File 'lib/smplkit/audit/events.rb', line 85

def flush(timeout: 5.0)
  @buffer.flush(timeout: timeout)
end

#get(event_id) ⇒ Object

Single-event retrieval.

Raises SmplkitGeneratedClient::Audit::ApiError on non-2xx responses (404 if the event is not in the caller’s account).



48
49
50
51
# File 'lib/smplkit/audit/events.rb', line 48

def get(event_id)
  resp = @api.get_event(event_id)
  AuditEvent.from_resource(resp.data)
end

#list(action: nil, resource_type: nil, resource_id: nil, actor_type: nil, actor_id: nil, occurred_at_range: nil, page_size: nil, page_after: nil) ⇒ Object

List events with filters and cursor pagination. Returns a Smplkit::Audit::ListEventsPage whose #events is the page and #next_cursor is the opaque token for the next page (or nil).



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/smplkit/audit/events.rb', line 56

def list(action: nil, resource_type: nil, resource_id: nil,
         actor_type: nil, actor_id: nil, occurred_at_range: nil,
         page_size: nil, page_after: nil)
  opts = {}
  opts[:filteraction] = action if action
  opts[:filterresource_type] = resource_type if resource_type
  opts[:filterresource_id] = resource_id if resource_id
  opts[:filteractor_type] = actor_type if actor_type
  opts[:filteractor_id] = actor_id if actor_id
  opts[:filteroccurred_at] = occurred_at_range if occurred_at_range
  opts[:pagesize] = page_size if page_size
  opts[:pageafter] = page_after if page_after

  resp = @api.list_events(opts)
  events = (resp.data || []).map { |r| AuditEvent.from_resource(r) }
  next_cursor = nil
  if resp.links&._next.is_a?(String)
    next_link = resp.links._next
    if (idx = next_link.index("page[after]="))
      next_cursor = next_link[(idx + "page[after]=".length)..]
      if (amp = next_cursor.index("&"))
        next_cursor = next_cursor[0...amp]
      end
    end
  end
  ListEventsPage.new(events, next_cursor)
end