Class: Smplkit::Audit::Events
- Inherits:
-
Object
- Object
- Smplkit::Audit::Events
- Defined in:
- lib/smplkit/audit/events.rb
Overview
Audit events surface — accessed via client.audit.events.
#record 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 reads.
Instance Method Summary collapse
- #_close ⇒ Object
-
#flush(timeout: 5.0) ⇒ Object
Block until the in-memory buffer is drained or the timeout elapses.
-
#get(event_id) ⇒ Object
Single-event retrieval.
-
#initialize(api) ⇒ Events
constructor
A new instance of Events.
-
#list(event_type: nil, resource_type: nil, resource_id: nil, actor_type: nil, actor_id: nil, occurred_at_range: nil, search: nil, page_size: nil, page_after: nil) ⇒ Object
List events with filters and cursor pagination.
-
#record(event_type:, resource_type:, resource_id:, occurred_at: nil, actor_type: nil, actor_id: nil, actor_label: nil, data: nil, idempotency_key: nil, do_not_forward: false) ⇒ Object
Enqueue an audit event for asynchronous delivery.
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
#_close ⇒ Object
112 113 114 |
# File 'lib/smplkit/audit/events.rb', line 112 def _close @buffer.close end |
#flush(timeout: 5.0) ⇒ Object
Block until the in-memory buffer is drained or the timeout elapses.
107 108 109 |
# File 'lib/smplkit/audit/events.rb', line 107 def flush(timeout: 5.0) @buffer.flush(timeout: timeout) end |
#get(event_id) ⇒ Object
Single-event retrieval.
Raises NotFoundError when no event with that id exists in the caller’s account.
74 75 76 77 |
# File 'lib/smplkit/audit/events.rb', line 74 def get(event_id) resp = Smplkit::Audit.call_api { @api.get_event(event_id) } AuditEvent.from_resource(resp.data) end |
#list(event_type: nil, resource_type: nil, resource_id: nil, actor_type: nil, actor_id: nil, occurred_at_range: nil, search: 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).
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/smplkit/audit/events.rb', line 82 def list(event_type: nil, resource_type: nil, resource_id: nil, actor_type: nil, actor_id: nil, occurred_at_range: nil, search: nil, page_size: nil, page_after: nil) # Generated client opts use snake_case keys that internally map # to the JSON:API ``filter[*]`` / ``page[*]`` query-string format # (see default_api.rb#list_events_with_http_info). Without the # underscores these silently fall through and the filters never # reach the server. opts = {} opts[:filter_event_type] = event_type if event_type opts[:filter_resource_type] = resource_type if resource_type opts[:filter_resource_id] = resource_id if resource_id opts[:filter_actor_type] = actor_type if actor_type opts[:filter_actor_id] = actor_id if actor_id opts[:filter_occurred_at] = occurred_at_range if occurred_at_range opts[:filter_search] = search if search opts[:page_size] = page_size if page_size opts[:page_after] = page_after if page_after resp = Smplkit::Audit.call_api { @api.list_events(opts) } events = (resp.data || []).map { |r| AuditEvent.from_resource(r) } ListEventsPage.new(events, Smplkit::Audit.next_cursor(resp.links&._next)) end |
#record(event_type:, resource_type:, resource_id:, occurred_at: nil, actor_type: nil, actor_id: nil, actor_label: nil, data: nil, idempotency_key: nil, do_not_forward: false) ⇒ Object
Enqueue an audit event for asynchronous delivery.
Actor attribution (actor_type, actor_id, actor_label) is customer-supplied and free-form. The audit service stores whatever the caller passed and never backfills from the request credential — supply the fields explicitly when you want the event attributed.
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).
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/smplkit/audit/events.rb', line 27 def record(event_type:, resource_type:, resource_id:, occurred_at: nil, actor_type: nil, actor_id: nil, actor_label: nil, data: nil, idempotency_key: nil, do_not_forward: false) raise ArgumentError, "event_type is required" if event_type.nil? || event_type.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? # Pydantic validation on the server expects an ISO-8601 string # for ``occurred_at`` — Ruby's ``Time#to_s`` (which is what the # generated client falls back to during JSON serialization) # emits ``"2026-05-07 04:43:23 UTC"`` and trips the gate. Coerce # Time/DateTime to ``.iso8601`` here so end users can pass the # native Ruby type. normalized_occurred_at = if occurred_at.respond_to?(:iso8601) occurred_at.iso8601 else occurred_at end # Server-side validation also rejects ``data: null`` (the field # is required-non-null in the OpenAPI schema). Always default to # an empty hash so users who omit ``data:`` don't trip the gate. attrs = SmplkitGeneratedClient::Audit::Event.new( event_type: event_type, resource_type: resource_type, resource_id: resource_id, occurred_at: normalized_occurred_at, actor_type: actor_type, actor_id: actor_id, actor_label: actor_label, data: data || {}, do_not_forward: do_not_forward ) resource = SmplkitGeneratedClient::Audit::EventResource.new( id: "", type: "event", attributes: attrs ) body = SmplkitGeneratedClient::Audit::EventRequest.new(data: resource) @buffer.enqueue(body, idempotency_key) end |