rails_audit_log-graphql 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd228bcaff874e10bbd50927cb3bc44d22b5c860acf8dd444624eff80c7dea96
4
- data.tar.gz: 29ebf0ccd63fd0827689d3cf0b5e5bd3b4c6194c12468aa347c0fadb1fe0c5f3
3
+ metadata.gz: 6ca2df96cd0a69c6449fc8585832293c9a06d487a7525f40c1d15762c61710b5
4
+ data.tar.gz: 8262257281bef88c4ab07700ec88b5755ca6b2a095fd879bf5462d403ec1ac00
5
5
  SHA512:
6
- metadata.gz: 81930d3cedc11053354b5b86349d5483b326f43d774ebea49f97bc61e827c1ede95fa61c1b2671c611df266a9f7b4f4e497d472d47d86fc01b9e6863dd2b8df2
7
- data.tar.gz: 158775764845a120940581a0e6c47be8ca3ba992c5195b4bb899c970d069f27dc94faf53c4dde7ee1e4752992d8de62adec09f3f20a68e8209499239e9589887
6
+ metadata.gz: 4598525fe46095cbd1209e9bc3af297950526eb9c7ecfab9e382ee3554f376e73b0db3073986d49cdd05190e42f90e1d09e3f1a00c3ecb948a0f02d04f5ba9f0
7
+ data.tar.gz: 2069e44509afdccf33c443bcf443da4480e83e60034f73bf24b0a7139ab012910d60e17dd85d06897b0642a6e4cb0d0d548a08c6bfbd5ac8318f6bd787d998b3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2026-06-04
4
+
5
+ ### Added
6
+
7
+ - `AuditLogJsonScalar` (`AuditLogJson`) — custom scalar type for `objectChanges`, `object`, and `metadata` fields; replaces the generic `JSON` scalar with a self-documenting type
8
+ - `RecordByIdSource` — `GraphQL::Dataloader::Source` that batch-loads AR records by class name and ID; eliminates N+1 queries when resolving `actor.record` and `auditedResource.record` on list responses
9
+ - `record` field on `AuditLogActor` and `AuditedResource` — returns the database record as JSON, batch-loaded via dataloader
10
+ - `auditLogReify(itemType:, itemId:, at:)` — reconstructs the attribute state of a record at a given point in time; returns `JSON` or `nil` when the record was destroyed or no entry exists
11
+ - `SchemaPlugin` — include into host schema to apply `max_complexity` (200), `max_depth` (10), `default_max_page_size` (25), and `use GraphQL::Dataloader`; all limits configurable via `RailsAuditLog::Graphql.max_complexity=` etc.
12
+
13
+ ## [0.5.0] - 2026-06-04
14
+
15
+ ### Added
16
+
17
+ - `forTenant:` argument on `auditLogEntry`, `auditLogEntries`, and `auditLogEntriesConnection` — explicitly scope results to a tenant ID; overrides auto-tenant
18
+ - Auto-tenant scoping — when `RailsAuditLog.current_tenant` is configured, all queries automatically filter to the current tenant without requiring an explicit argument
19
+ - `auditLogEntriesCount(event:, itemType:, since:)` — new aggregation query returning the count of matching entries; respects auto-tenant
20
+
3
21
  ## [0.4.0] - 2026-06-04
4
22
 
5
23
  ### Added
data/README.md CHANGED
@@ -20,7 +20,11 @@ A [graphql-ruby](https://graphql-ruby.org) API layer for the [`rails_audit_log`]
20
20
  - [auditLogEntry](#auditlogentryid-id-auditlogentry)
21
21
  - [auditLogEntries](#auditlogentries-auditlogentry)
22
22
  - [auditLogEntriesConnection](#auditlogentriesconnection-auditlogentryconnection)
23
+ - [auditLogEntriesCount](#auditlogentriescount-int)
24
+ - [Tenant scoping](#tenant-scoping)
23
25
  - [Authentication](#authentication)
26
+ - [SchemaPlugin](#schemaplugin)
27
+ - [auditLogReify](#auditlogreify)
24
28
  - [Subscriptions](#subscriptions)
25
29
  - [AuditLogSubscriptionsMixin](#auditlogsubscriptionsmixin)
26
30
  - [auditLogEntryCreated](#auditlogentrycreated)
@@ -152,6 +156,7 @@ List entries with optional filters and offset pagination.
152
156
  | `until` | `ISO8601DateTime` | — | Return entries created at or before this time |
153
157
  | `touching` | `String` | — | Filter to entries that changed a specific attribute |
154
158
  | `orderBy` | `AuditLogEntrySortInput` | `CREATED_AT DESC` | Sort field and direction |
159
+ | `forTenant` | `String` | — | Scope to a specific tenant ID; overrides auto-tenant |
155
160
  | `page` | `Int` | `1` | Page number (1-based) |
156
161
  | `perPage` | `Int` | `25` | Results per page |
157
162
 
@@ -167,6 +172,7 @@ Same filters as `auditLogEntries`, but returns a [Relay-style connection](https:
167
172
  | `itemType` | `String` | Filter by audited model class name |
168
173
  | `itemId` | `ID` | Filter by audited record ID |
169
174
  | `actorId` | `ID` | Filter by actor ID |
175
+ | `forTenant` | `String` | Scope to a specific tenant ID; overrides auto-tenant |
170
176
  | `first` | `Int` | Return the first N edges after `after` |
171
177
  | `after` | `String` | Cursor to paginate forward from |
172
178
  | `last` | `Int` | Return the last N edges before `before` |
@@ -207,6 +213,40 @@ Results are ordered by `created_at DESC`.
207
213
 
208
214
  [↑ Back to top](#table-of-contents)
209
215
 
216
+ #### `auditLogEntriesCount(...): Int!`
217
+
218
+ Returns the count of matching audit log entries. Respects auto-tenant when `RailsAuditLog.current_tenant` is configured.
219
+
220
+ | Argument | Type | Description |
221
+ |---|---|---|
222
+ | `event` | `String` | Filter by event type (`create`, `update`, `destroy`) |
223
+ | `itemType` | `String` | Filter by audited model class name |
224
+ | `since` | `ISO8601DateTime` | Count entries created at or after this time |
225
+
226
+ ```graphql
227
+ { auditLogEntriesCount(event: "update", itemType: "Post") }
228
+ ```
229
+
230
+ [↑ Back to top](#table-of-contents)
231
+
232
+ #### Tenant scoping
233
+
234
+ When `RailsAuditLog.current_tenant` is configured, all queries automatically filter to the current tenant:
235
+
236
+ ```ruby
237
+ RailsAuditLog.configure do |c|
238
+ c.current_tenant { Current.tenant_id }
239
+ end
240
+ ```
241
+
242
+ To override or explicitly specify a tenant per query, use the `forTenant:` argument (available on `auditLogEntry`, `auditLogEntries`, and `auditLogEntriesConnection`):
243
+
244
+ ```graphql
245
+ { auditLogEntries(forTenant: "acme") { id event } }
246
+ ```
247
+
248
+ [↑ Back to top](#table-of-contents)
249
+
210
250
  ### Authentication
211
251
 
212
252
  If `RailsAuditLog.authenticate` is configured, the block is called with the GraphQL context before every query. Return a truthy value to allow access; return falsy to raise `GraphQL::ExecutionError` with `"Unauthorized"`.
@@ -221,6 +261,51 @@ If no authenticate block is set, all queries are permitted.
221
261
 
222
262
  [↑ Back to top](#table-of-contents)
223
263
 
264
+ ### SchemaPlugin
265
+
266
+ Include `RailsAuditLog::Graphql::SchemaPlugin` into your schema to enable query protection and dataloader batching in one step:
267
+
268
+ ```ruby
269
+ class MySchema < GraphQL::Schema
270
+ include RailsAuditLog::Graphql::SchemaPlugin
271
+ query Types::QueryType
272
+ end
273
+ ```
274
+
275
+ This applies the following defaults (all overridable via `RailsAuditLog::Graphql.*=`):
276
+
277
+ | Setting | Default | Description |
278
+ |---|---|---|
279
+ | `max_complexity` | `200` | Reject queries whose field-complexity sum exceeds this |
280
+ | `max_depth` | `10` | Reject queries nested deeper than this |
281
+ | `default_max_page_size` | `25` | Assumed page size for connection complexity calculation |
282
+
283
+ Override in an initializer:
284
+
285
+ ```ruby
286
+ RailsAuditLog::Graphql.max_complexity = 500
287
+ RailsAuditLog::Graphql.max_depth = 15
288
+ ```
289
+
290
+ The plugin also adds `AuditLogActor.record` and `AuditedResource.record` fields — nullable JSON fields that load the actual database record via `RecordByIdSource`, a `GraphQL::Dataloader::Source` that batches loads by class name to eliminate N+1 queries on list responses.
291
+
292
+ [↑ Back to top](#table-of-contents)
293
+
294
+ ### `auditLogReify(itemType:, itemId:, at:): JSON`
295
+
296
+ Reconstructs the attribute state of a record at a given point in time. Returns the attributes as JSON, or `nil` when no entry exists at or before `at` or the record was destroyed at that time.
297
+
298
+ ```graphql
299
+ {
300
+ auditLogReify(itemType: "Post", itemId: "42", at: "2026-01-15T12:00:00Z") {
301
+ title
302
+ publishedAt
303
+ }
304
+ }
305
+ ```
306
+
307
+ [↑ Back to top](#table-of-contents)
308
+
224
309
  ### Subscriptions
225
310
 
226
311
  Requires Action Cable in the host application.
data/ROADMAP.md CHANGED
@@ -4,23 +4,6 @@ This gem adds a GraphQL API layer on top of [`rails_audit_log`](https://github.c
4
4
 
5
5
  ---
6
6
 
7
- ## 0.5.0 — Multi-tenancy & Advanced Filtering
8
-
9
- - **Tenant scoping** — automatically scope queries via `RailsAuditLog.current_tenant` when configured
10
- - **`forTenant:` argument** — explicit tenant filter on `auditLogEntries`
11
- - **Aggregations** — `auditLogEntriesCount(event:, itemType:, since:)` for dashboard metrics
12
-
13
- ---
14
-
15
- ## 0.6.0 — Performance & Safety
16
-
17
- - **Dataloader batch loading** — batch-resolve polymorphic `actor` and `item` associations using graphql-ruby's `dataloader` to eliminate N+1 queries on list responses
18
- - **`auditLogReify` query** — `auditLogReify(itemType:, itemId:, at:)` returns the reconstructed object state as JSON at a given point in time, backed by `RailsAuditLog.version_at`
19
- - **Query complexity & depth limits** — built-in defaults (`max_complexity`, `max_depth`) with a config override (`RailsAuditLogGraphql.max_complexity = 200`) to protect against expensive queries before the API is declared stable
20
- - **`AuditLogJsonScalar`** — proper JSON scalar type for `objectChanges` and `metadata` fields, replacing opaque String serialization and making the schema self-documenting
21
-
22
- ---
23
-
24
7
  ## 1.0.0 — Stable API
25
8
 
26
9
  - Full YARD documentation
@@ -14,6 +14,8 @@ module RailsAuditLog
14
14
  ) do
15
15
  argument :id, GraphQL::Types::ID, required: true,
16
16
  description: "ID of the audit log entry."
17
+ argument :for_tenant, String, required: false,
18
+ description: "Scope to a specific tenant ID. Overrides auto-tenant when RailsAuditLog.current_tenant is configured."
17
19
  end
18
20
 
19
21
  base.field(
@@ -31,6 +33,8 @@ module RailsAuditLog
31
33
  argument :until, GraphQL::Types::ISO8601DateTime, required: false, as: :until_time, description: "Return entries created at or before this time."
32
34
  argument :touching, String, required: false, description: "Filter to entries that changed a specific attribute (matches object_changes keys)."
33
35
  argument :order_by, RailsAuditLog::Graphql::InputObjects::AuditLogEntrySortInput, required: false, description: "Sort order. Defaults to CREATED_AT DESC."
36
+ argument :for_tenant, String, required: false,
37
+ description: "Scope to a specific tenant ID. Overrides auto-tenant when RailsAuditLog.current_tenant is configured."
34
38
  argument :page, GraphQL::Types::Int, required: false, default_value: 1, description: "Page number (1-based)."
35
39
  argument :per_page, GraphQL::Types::Int, required: false, default_value: 25, description: "Number of results per page."
36
40
  end
@@ -50,28 +54,79 @@ module RailsAuditLog
50
54
  argument :until, GraphQL::Types::ISO8601DateTime, required: false, as: :until_time, description: "Return entries created at or before this time."
51
55
  argument :touching, String, required: false, description: "Filter to entries that changed a specific attribute (matches object_changes keys)."
52
56
  argument :order_by, RailsAuditLog::Graphql::InputObjects::AuditLogEntrySortInput, required: false, description: "Sort order. Defaults to CREATED_AT DESC."
57
+ argument :for_tenant, String, required: false,
58
+ description: "Scope to a specific tenant ID. Overrides auto-tenant when RailsAuditLog.current_tenant is configured."
59
+ end
60
+
61
+ base.field(
62
+ :audit_log_reify,
63
+ GraphQL::Types::JSON,
64
+ null: true,
65
+ description: "Reconstruct the attribute state of a record at a given point in time. Returns nil when no entry exists at or before `at`, or when the record was destroyed.",
66
+ resolver_method: :resolve_audit_log_reify
67
+ ) do
68
+ argument :item_type, String, required: true, description: "The audited model class name."
69
+ argument :item_id, GraphQL::Types::ID, required: true, description: "The audited record ID."
70
+ argument :at, GraphQL::Types::ISO8601DateTime, required: true, description: "Reconstruct state as of this time."
71
+ end
72
+
73
+ base.field(
74
+ :audit_log_entries_count,
75
+ GraphQL::Types::Int,
76
+ null: false,
77
+ description: "Count audit log entries with optional filters. Respects auto-tenant when RailsAuditLog.current_tenant is configured.",
78
+ resolver_method: :resolve_audit_log_entries_count
79
+ ) do
80
+ argument :event, String, required: false, description: "Filter by event type (create, update, destroy)."
81
+ argument :item_type, String, required: false, description: "Filter by audited model class name."
82
+ argument :since, GraphQL::Types::ISO8601DateTime, required: false, description: "Count entries created at or after this time."
53
83
  end
54
84
  end
55
85
 
56
- def resolve_audit_log_entry(id:)
86
+ def resolve_audit_log_entry(id:, for_tenant: nil)
57
87
  check_authentication!
58
- RailsAuditLog::AuditLogEntry.find_by(id: id)
88
+ tenant_id = for_tenant || RailsAuditLog.current_tenant&.call
89
+ base = tenant_id ? RailsAuditLog::AuditLogEntry.for_tenant(tenant_id) : RailsAuditLog::AuditLogEntry
90
+ base.find_by(id: id)
59
91
  end
60
92
 
61
- def resolve_audit_log_entries(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil, page: 1, per_page: 25)
93
+ def resolve_audit_log_entries(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil, for_tenant: nil, page: 1, per_page: 25)
62
94
  check_authentication!
63
- scope = build_scope(event: event, item_type: item_type, item_id: item_id, actor_id: actor_id, since: since, until_time: until_time, touching: touching, order_by: order_by)
95
+ scope = build_scope(event: event, item_type: item_type, item_id: item_id, actor_id: actor_id, since: since, until_time: until_time, touching: touching, order_by: order_by, for_tenant: for_tenant)
64
96
  scope.limit(per_page).offset((page - 1) * per_page)
65
97
  end
66
98
 
67
- def resolve_audit_log_entries_connection(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil)
99
+ def resolve_audit_log_entries_connection(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil, for_tenant: nil)
100
+ check_authentication!
101
+ build_scope(event: event, item_type: item_type, item_id: item_id, actor_id: actor_id, since: since, until_time: until_time, touching: touching, order_by: order_by, for_tenant: for_tenant)
102
+ end
103
+
104
+ def resolve_audit_log_reify(item_type:, item_id:, at:)
105
+ check_authentication!
106
+ entry = RailsAuditLog::AuditLogEntry
107
+ .where(item_type: item_type, item_id: item_id)
108
+ .where("created_at <= ?", at)
109
+ .order(created_at: :desc, id: :desc)
110
+ .first
111
+ return nil if entry.nil? || entry.event == "destroy"
112
+ to_attrs = (entry.object_changes || {}).transform_values { |v| v[1] }
113
+ entry.object.present? ? entry.object.merge(to_attrs) : to_attrs
114
+ end
115
+
116
+ def resolve_audit_log_entries_count(event: nil, item_type: nil, since: nil)
68
117
  check_authentication!
69
- build_scope(event: event, item_type: item_type, item_id: item_id, actor_id: actor_id, since: since, until_time: until_time, touching: touching, order_by: order_by)
118
+ scope = RailsAuditLog::AuditLogEntry.all
119
+ scope = scope.where(event: event) if event
120
+ scope = scope.where(item_type: item_type) if item_type
121
+ scope = scope.where("created_at >= ?", since) if since
122
+ tenant_id = RailsAuditLog.current_tenant&.call
123
+ scope = scope.for_tenant(tenant_id) if tenant_id
124
+ scope.count
70
125
  end
71
126
 
72
127
  private
73
128
 
74
- def build_scope(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil)
129
+ def build_scope(event: nil, item_type: nil, item_id: nil, actor_id: nil, since: nil, until_time: nil, touching: nil, order_by: nil, for_tenant: nil)
75
130
  sort_field = order_by&.field || :created_at
76
131
  sort_direction = order_by&.direction || :desc
77
132
  scope = RailsAuditLog::AuditLogEntry.order(sort_field => sort_direction)
@@ -85,6 +140,8 @@ module RailsAuditLog
85
140
  safe = ActiveRecord::Base.sanitize_sql_like(touching)
86
141
  scope = scope.where("object_changes LIKE ?", "%\"#{safe}\":%")
87
142
  end
143
+ tenant_id = for_tenant || RailsAuditLog.current_tenant&.call
144
+ scope = scope.for_tenant(tenant_id) if tenant_id
88
145
  scope
89
146
  end
90
147
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module SchemaPlugin
6
+ def self.included(base)
7
+ base.max_complexity(RailsAuditLog::Graphql.max_complexity)
8
+ base.max_depth(RailsAuditLog::Graphql.max_depth)
9
+ base.default_max_page_size(RailsAuditLog::Graphql.default_max_page_size)
10
+ base.use(GraphQL::Dataloader)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module Sources
6
+ class RecordByIdSource < GraphQL::Dataloader::Source
7
+ def initialize(class_name)
8
+ @class_name = class_name
9
+ end
10
+
11
+ def fetch(ids)
12
+ klass = @class_name.safe_constantize
13
+ return ids.map { nil } unless klass
14
+
15
+ records = klass.where(id: ids).index_by { |r| r.id.to_s }
16
+ ids.map { |id| records[id]&.attributes }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -9,6 +9,8 @@ module RailsAuditLog
9
9
 
10
10
  field :id, GraphQL::Types::ID, null: false, description: "The actor's ID."
11
11
  field :type_name, String, null: false, description: "The actor's model class name (e.g. \"User\")."
12
+ field :record, GraphQL::Types::JSON, null: true,
13
+ description: "The actor record loaded from the database, serialized as JSON. Batch-loaded via dataloader."
12
14
 
13
15
  def id
14
16
  object[:id]
@@ -17,6 +19,11 @@ module RailsAuditLog
17
19
  def type_name
18
20
  object[:type_name]
19
21
  end
22
+
23
+ def record
24
+ return nil unless object[:id] && object[:type_name]
25
+ dataloader.with(Sources::RecordByIdSource, object[:type_name]).load(object[:id].to_s)
26
+ end
20
27
  end
21
28
  end
22
29
  end
@@ -11,9 +11,9 @@ module RailsAuditLog
11
11
  field :event, String, null: false
12
12
  field :item_type, String, null: false
13
13
  field :item_id, GraphQL::Types::ID, null: false
14
- field :object_changes, GraphQL::Types::JSON, null: true
15
- field :object, GraphQL::Types::JSON, null: true, method_conflict_warning: false
16
- field :metadata, GraphQL::Types::JSON, null: true
14
+ field :object_changes, Types::AuditLogJsonScalar, null: true
15
+ field :object, Types::AuditLogJsonScalar, null: true, method_conflict_warning: false
16
+ field :metadata, Types::AuditLogJsonScalar, null: true
17
17
  field :reason, String, null: true
18
18
  field :whodunnit_snapshot, String, null: true
19
19
  field :actor_type, String, null: true
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module Types
6
+ class AuditLogJsonScalar < GraphQL::Schema::Scalar
7
+ graphql_name "AuditLogJson"
8
+ description "A JSON blob stored on an audit log entry (objectChanges, object, or metadata)."
9
+
10
+ def self.coerce_input(value, _ctx)
11
+ value.is_a?(Hash) ? value : JSON.parse(value)
12
+ rescue JSON::ParserError
13
+ raise GraphQL::CoercionError, "#{value.inspect} is not valid JSON"
14
+ end
15
+
16
+ def self.coerce_result(value, _ctx)
17
+ value
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -9,6 +9,8 @@ module RailsAuditLog
9
9
 
10
10
  field :id, GraphQL::Types::ID, null: false, description: "The audited record's ID."
11
11
  field :type_name, String, null: false, description: "The audited model class name (e.g. \"Post\")."
12
+ field :record, GraphQL::Types::JSON, null: true,
13
+ description: "The audited record loaded from the database, serialized as JSON. Batch-loaded via dataloader."
12
14
 
13
15
  def id
14
16
  object[:id]
@@ -17,6 +19,10 @@ module RailsAuditLog
17
19
  def type_name
18
20
  object[:type_name]
19
21
  end
22
+
23
+ def record
24
+ dataloader.with(Sources::RecordByIdSource, object[:type_name]).load(object[:id].to_s)
25
+ end
20
26
  end
21
27
  end
22
28
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RailsAuditLog
4
4
  module Graphql
5
- VERSION = "0.4.0"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
@@ -4,6 +4,7 @@ require "graphql"
4
4
  require_relative "graphql/version"
5
5
  require_relative "graphql/types/base_object"
6
6
  require_relative "graphql/types/base_subscription"
7
+ require_relative "graphql/types/audit_log_json_scalar"
7
8
  require_relative "graphql/types/diff_type"
8
9
  require_relative "graphql/types/actor_type"
9
10
  require_relative "graphql/types/audited_resource_type"
@@ -11,13 +12,23 @@ require_relative "graphql/types/audit_log_entry_type"
11
12
  require_relative "graphql/types/sort_direction_enum"
12
13
  require_relative "graphql/types/audit_log_entry_sort_field_enum"
13
14
  require_relative "graphql/input_objects/audit_log_entry_sort_input"
15
+ require_relative "graphql/sources/record_by_id_source"
14
16
  require_relative "graphql/queries/audit_log_entries_query_mixin"
15
17
  require_relative "graphql/subscriptions/audit_log_entry_created"
16
18
  require_relative "graphql/subscriptions/audit_log_subscriptions_mixin"
17
19
  require_relative "graphql/subscriptions/broadcaster"
20
+ require_relative "graphql/schema_plugin"
18
21
 
19
22
  module RailsAuditLog
20
23
  module Graphql
21
24
  class Error < StandardError; end
25
+
26
+ @max_complexity = 200
27
+ @max_depth = 10
28
+ @default_max_page_size = 25
29
+
30
+ class << self
31
+ attr_accessor :max_complexity, :max_depth, :default_max_page_size
32
+ end
22
33
  end
23
34
  end
@@ -2,6 +2,17 @@ module RailsAuditLog
2
2
  module Graphql
3
3
  VERSION: String
4
4
 
5
+ @max_complexity: Integer
6
+ @max_depth: Integer
7
+ @default_max_page_size: Integer
8
+
9
+ def self.max_complexity: () -> Integer
10
+ def self.max_complexity=: (Integer) -> Integer
11
+ def self.max_depth: () -> Integer
12
+ def self.max_depth=: (Integer) -> Integer
13
+ def self.default_max_page_size: () -> Integer
14
+ def self.default_max_page_size=: (Integer) -> Integer
15
+
5
16
  module Types
6
17
  class BaseObject < GraphQL::Schema::Object
7
18
  end
@@ -9,6 +20,11 @@ module RailsAuditLog
9
20
  class BaseSubscription < GraphQL::Schema::Subscription
10
21
  end
11
22
 
23
+ class AuditLogJsonScalar < GraphQL::Schema::Scalar
24
+ def self.coerce_input: (untyped value, untyped ctx) -> Hash[String, untyped]
25
+ def self.coerce_result: (untyped value, untyped ctx) -> untyped
26
+ end
27
+
12
28
  class DiffType < BaseObject
13
29
  def attribute: () -> String
14
30
  def from: () -> untyped
@@ -18,11 +34,13 @@ module RailsAuditLog
18
34
  class ActorType < BaseObject
19
35
  def id: () -> String
20
36
  def type_name: () -> String
37
+ def record: () -> Hash[String, untyped]?
21
38
  end
22
39
 
23
40
  class AuditedResourceType < BaseObject
24
41
  def id: () -> String
25
42
  def type_name: () -> String
43
+ def record: () -> Hash[String, untyped]?
26
44
  end
27
45
 
28
46
  class AuditLogEntryType < BaseObject
@@ -54,6 +72,17 @@ module RailsAuditLog
54
72
  end
55
73
  end
56
74
 
75
+ module Sources
76
+ class RecordByIdSource < GraphQL::Dataloader::Source
77
+ def initialize: (String class_name) -> void
78
+ def fetch: (Array[String] ids) -> Array[Hash[String, untyped]?]
79
+ end
80
+ end
81
+
82
+ module SchemaPlugin
83
+ def self.included: (untyped base) -> void
84
+ end
85
+
57
86
  module Subscriptions
58
87
  class AuditLogEntryCreated < Types::BaseSubscription
59
88
  def subscribe: (?item_type: String?, ?item_id: String?, ?actor_id: String?) -> :no_response
@@ -76,7 +105,7 @@ module RailsAuditLog
76
105
  module AuditLogEntriesQueryMixin
77
106
  def self.included: (untyped base) -> void
78
107
 
79
- def resolve_audit_log_entry: (id: String) -> untyped
108
+ def resolve_audit_log_entry: (id: String, ?for_tenant: String?) -> untyped
80
109
 
81
110
  def resolve_audit_log_entries: (
82
111
  ?event: String?,
@@ -87,6 +116,7 @@ module RailsAuditLog
87
116
  ?until_time: Time?,
88
117
  ?touching: String?,
89
118
  ?order_by: InputObjects::AuditLogEntrySortInput?,
119
+ ?for_tenant: String?,
90
120
  ?page: Integer,
91
121
  ?per_page: Integer
92
122
  ) -> untyped
@@ -99,9 +129,22 @@ module RailsAuditLog
99
129
  ?since: Time?,
100
130
  ?until_time: Time?,
101
131
  ?touching: String?,
102
- ?order_by: InputObjects::AuditLogEntrySortInput?
132
+ ?order_by: InputObjects::AuditLogEntrySortInput?,
133
+ ?for_tenant: String?
103
134
  ) -> untyped
104
135
 
136
+ def resolve_audit_log_reify: (
137
+ item_type: String,
138
+ item_id: String,
139
+ at: Time
140
+ ) -> Hash[String, untyped]?
141
+
142
+ def resolve_audit_log_entries_count: (
143
+ ?event: String?,
144
+ ?item_type: String?,
145
+ ?since: Time?
146
+ ) -> Integer
147
+
105
148
  private
106
149
 
107
150
  def build_scope: (
@@ -112,7 +155,8 @@ module RailsAuditLog
112
155
  ?since: Time?,
113
156
  ?until_time: Time?,
114
157
  ?touching: String?,
115
- ?order_by: InputObjects::AuditLogEntrySortInput?
158
+ ?order_by: InputObjects::AuditLogEntrySortInput?,
159
+ ?for_tenant: String?
116
160
  ) -> untyped
117
161
 
118
162
  def check_authentication!: () -> void
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_audit_log-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith
@@ -86,12 +86,15 @@ files:
86
86
  - lib/rails_audit_log/graphql/input_objects/audit_log_entry_sort_input.rb
87
87
  - lib/rails_audit_log/graphql/queries/audit_log_entries_query_mixin.rb
88
88
  - lib/rails_audit_log/graphql/release_tooling.rb
89
+ - lib/rails_audit_log/graphql/schema_plugin.rb
90
+ - lib/rails_audit_log/graphql/sources/record_by_id_source.rb
89
91
  - lib/rails_audit_log/graphql/subscriptions/audit_log_entry_created.rb
90
92
  - lib/rails_audit_log/graphql/subscriptions/audit_log_subscriptions_mixin.rb
91
93
  - lib/rails_audit_log/graphql/subscriptions/broadcaster.rb
92
94
  - lib/rails_audit_log/graphql/types/actor_type.rb
93
95
  - lib/rails_audit_log/graphql/types/audit_log_entry_sort_field_enum.rb
94
96
  - lib/rails_audit_log/graphql/types/audit_log_entry_type.rb
97
+ - lib/rails_audit_log/graphql/types/audit_log_json_scalar.rb
95
98
  - lib/rails_audit_log/graphql/types/audited_resource_type.rb
96
99
  - lib/rails_audit_log/graphql/types/base_object.rb
97
100
  - lib/rails_audit_log/graphql/types/base_subscription.rb