rails_audit_log-graphql 0.1.0 → 0.2.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: 35b1c07883c1e3b4036690804d2cf1600e484771b49a58f3954278d39fb136ae
4
- data.tar.gz: 15b543bf26d1d19ff3e8fbc29488871f325d492cef51b215c60dff8d1f22906b
3
+ metadata.gz: 6c89d640d69c533ded27f477ed99b03275c34b4564c90e6eaccfe86a131f2447
4
+ data.tar.gz: d34b732d907a2db6b9c6c0bfba266933aaf6f21be9c8770caa8c64b50a81c870
5
5
  SHA512:
6
- metadata.gz: 9409ded3977d2fa0f31f5a60be9bf841cabe5e324aed231e8119fc59c433988affe7ab7f873aa31e1de7a2538f054e281c1af46f4946632fa2cff46d39ad35f5
7
- data.tar.gz: f52a3c3d184d1ff8f201011ca014338e4a13b3d1a3d055f1372ea5fa72f4a2898765cde924777d38e5843f21b3319ee13a309cb6e4b37b23130f4986a559daf1
6
+ metadata.gz: faa1b363d2aaebc1b3f5573f0b6c757a5d6b4d1fe8b6a1af7d906bd9877f23cecf897b75640b9f61e24e622d06c4233825be5047bada0d92371f954749a2499f
7
+ data.tar.gz: '08c32d0f02192b6db82d11e414ac04beb42a54ce61bb6dd8b025b2866f1569bc65b7b177ba308a4c0d241d7486029741e03abf082af38726fa2bbd30d6d2c6f4'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2026-06-03
4
+
5
+ ### Added
6
+
7
+ - `auditLogEntriesConnection` — new Relay-style cursor-paginated field returning `AuditLogEntryConnection!` with `nodes`, `edges`, `pageInfo`, and `first`/`after`/`last`/`before` arguments; accepts the same filters as `auditLogEntries`
8
+ - `since:` and `until:` (`ISO8601DateTime`) arguments on both `auditLogEntries` and `auditLogEntriesConnection` for filtering by creation time range
9
+ - `touching:` (`String`) argument on both `auditLogEntries` and `auditLogEntriesConnection` — filters to entries whose `object_changes` include the named attribute
10
+ - `orderBy:` (`AuditLogEntrySortInput`) argument on both `auditLogEntries` and `auditLogEntriesConnection` — accepts `{ field: CREATED_AT, direction: ASC | DESC }`; defaults to `CREATED_AT DESC`
11
+ - `AuditLogEntrySortInput` input object type, `AuditLogEntrySortField` enum, and `SortDirection` enum added to the schema
12
+
3
13
  ## [0.1.0] - 2026-06-03
4
14
 
5
15
  ### Added
data/README.md CHANGED
@@ -94,6 +94,54 @@ List entries with optional filters and offset pagination.
94
94
 
95
95
  Results are ordered by `created_at DESC`.
96
96
 
97
+ #### `auditLogEntriesConnection(...): AuditLogEntryConnection!`
98
+
99
+ Same filters as `auditLogEntries`, but returns a [Relay-style connection](https://relay.dev/graphql/connections.htm) for cursor-based pagination.
100
+
101
+ | Argument | Type | Description |
102
+ |---|---|---|
103
+ | `event` | `String` | Filter by event type (`create`, `update`, `destroy`) |
104
+ | `itemType` | `String` | Filter by audited model class name |
105
+ | `itemId` | `ID` | Filter by audited record ID |
106
+ | `actorId` | `ID` | Filter by actor ID |
107
+ | `first` | `Int` | Return the first N edges after `after` |
108
+ | `after` | `String` | Cursor to paginate forward from |
109
+ | `last` | `Int` | Return the last N edges before `before` |
110
+ | `before` | `String` | Cursor to paginate backward from |
111
+
112
+ Results are ordered by `created_at DESC`.
113
+
114
+ **Example — first page:**
115
+
116
+ ```graphql
117
+ {
118
+ auditLogEntriesConnection(first: 25) {
119
+ nodes {
120
+ id
121
+ event
122
+ itemType
123
+ itemId
124
+ createdAt
125
+ }
126
+ pageInfo {
127
+ hasNextPage
128
+ endCursor
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ **Example — next page using a cursor:**
135
+
136
+ ```graphql
137
+ {
138
+ auditLogEntriesConnection(first: 25, after: "eyJpZCI6NDJ9") {
139
+ nodes { id event }
140
+ pageInfo { hasNextPage endCursor }
141
+ }
142
+ }
143
+ ```
144
+
97
145
  [↑ Back to top](#table-of-contents)
98
146
 
99
147
  ### Authentication
data/ROADMAP.md CHANGED
@@ -4,15 +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.2.0 — Filtering & Connections
8
-
9
- - **Time-range filters** — `since:` and `until:` arguments on `auditLogEntries`
10
- - **`touching:` filter** — narrow results to entries that changed a specific attribute
11
- - **Relay-style connection** — replace offset pagination with cursor-based `AuditLogEntryConnection` for forward/backward pagination
12
- - **Sorting** — `orderBy: { field: CREATED_AT, direction: DESC }`
13
-
14
- ---
15
-
16
7
  ## 0.3.0 — Actor & Resource Resolver Types
17
8
 
18
9
  - **`ActorType`** — resolve the polymorphic `actor` to the concrete type in the host app's schema (requires a configurable type resolver proc)
data/Rakefile CHANGED
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
+ require "bundler/audit/task"
4
5
  require "rspec/core/rake_task"
5
6
  require "standard/rake"
6
7
 
8
+ Bundler::Audit::Task.new
7
9
  RSpec::Core::RakeTask.new(:spec)
8
10
 
9
11
  task default: [:standard, :spec]
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module InputObjects
6
+ class AuditLogEntrySortInput < GraphQL::Schema::InputObject
7
+ graphql_name "AuditLogEntrySortInput"
8
+ description "Sort order for audit log entry queries."
9
+
10
+ argument :field, Types::AuditLogEntrySortFieldEnum, required: true, description: "Field to sort by."
11
+ argument :direction, Types::SortDirectionEnum, required: true, description: "Sort direction (ASC or DESC)."
12
+ end
13
+ end
14
+ end
15
+ end
@@ -27,9 +27,30 @@ module RailsAuditLog
27
27
  argument :item_type, String, required: false, description: "Filter by audited model class name."
28
28
  argument :item_id, GraphQL::Types::ID, required: false, description: "Filter by audited record ID."
29
29
  argument :actor_id, GraphQL::Types::ID, required: false, description: "Filter by actor ID."
30
+ argument :since, GraphQL::Types::ISO8601DateTime, required: false, description: "Return entries created at or after this time."
31
+ argument :until, GraphQL::Types::ISO8601DateTime, required: false, as: :until_time, description: "Return entries created at or before this time."
32
+ argument :touching, String, required: false, description: "Filter to entries that changed a specific attribute (matches object_changes keys)."
33
+ argument :order_by, RailsAuditLog::Graphql::InputObjects::AuditLogEntrySortInput, required: false, description: "Sort order. Defaults to CREATED_AT DESC."
30
34
  argument :page, GraphQL::Types::Int, required: false, default_value: 1, description: "Page number (1-based)."
31
35
  argument :per_page, GraphQL::Types::Int, required: false, default_value: 25, description: "Number of results per page."
32
36
  end
37
+
38
+ base.field(
39
+ :audit_log_entries_connection,
40
+ RailsAuditLog::Graphql::Types::AuditLogEntryType.connection_type,
41
+ null: false,
42
+ description: "List audit log entries with optional filters. Cursor-paginated (Relay connection).",
43
+ resolver_method: :resolve_audit_log_entries_connection
44
+ ) do
45
+ argument :event, String, required: false, description: "Filter by event type (create, update, destroy)."
46
+ argument :item_type, String, required: false, description: "Filter by audited model class name."
47
+ argument :item_id, GraphQL::Types::ID, required: false, description: "Filter by audited record ID."
48
+ argument :actor_id, GraphQL::Types::ID, required: false, description: "Filter by actor ID."
49
+ argument :since, GraphQL::Types::ISO8601DateTime, required: false, description: "Return entries created at or after this time."
50
+ argument :until, GraphQL::Types::ISO8601DateTime, required: false, as: :until_time, description: "Return entries created at or before this time."
51
+ argument :touching, String, required: false, description: "Filter to entries that changed a specific attribute (matches object_changes keys)."
52
+ argument :order_by, RailsAuditLog::Graphql::InputObjects::AuditLogEntrySortInput, required: false, description: "Sort order. Defaults to CREATED_AT DESC."
53
+ end
33
54
  end
34
55
 
35
56
  def resolve_audit_log_entry(id:)
@@ -37,18 +58,36 @@ module RailsAuditLog
37
58
  RailsAuditLog::AuditLogEntry.find_by(id: id)
38
59
  end
39
60
 
40
- def resolve_audit_log_entries(event: nil, item_type: nil, item_id: nil, actor_id: nil, page: 1, per_page: 25)
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)
41
62
  check_authentication!
42
- scope = RailsAuditLog::AuditLogEntry.order(created_at: :desc)
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)
64
+ scope.limit(per_page).offset((page - 1) * per_page)
65
+ end
66
+
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)
68
+ 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)
70
+ end
71
+
72
+ private
73
+
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)
75
+ sort_field = order_by&.field || :created_at
76
+ sort_direction = order_by&.direction || :desc
77
+ scope = RailsAuditLog::AuditLogEntry.order(sort_field => sort_direction)
43
78
  scope = scope.where(event: event) if event
44
79
  scope = scope.where(item_type: item_type) if item_type
45
80
  scope = scope.where(item_id: item_id) if item_id
46
81
  scope = scope.where(actor_id: actor_id) if actor_id
47
- scope.limit(per_page).offset((page - 1) * per_page)
82
+ scope = scope.where("created_at >= ?", since) if since
83
+ scope = scope.where("created_at <= ?", until_time) if until_time
84
+ if touching
85
+ safe = ActiveRecord::Base.sanitize_sql_like(touching)
86
+ scope = scope.where("object_changes LIKE ?", "%\"#{safe}\":%")
87
+ end
88
+ scope
48
89
  end
49
90
 
50
- private
51
-
52
91
  def check_authentication!
53
92
  auth = RailsAuditLog.authenticate
54
93
  return unless auth
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module Types
6
+ class AuditLogEntrySortFieldEnum < GraphQL::Schema::Enum
7
+ graphql_name "AuditLogEntrySortField"
8
+ description "Fields available for sorting audit log entries."
9
+
10
+ value "CREATED_AT", value: :created_at, description: "Sort by creation time."
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAuditLog
4
+ module Graphql
5
+ module Types
6
+ class SortDirectionEnum < GraphQL::Schema::Enum
7
+ graphql_name "SortDirection"
8
+ description "Sort direction for ordered queries."
9
+
10
+ value "ASC", value: :asc, description: "Ascending order."
11
+ value "DESC", value: :desc, description: "Descending order."
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RailsAuditLog
4
4
  module Graphql
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -4,6 +4,9 @@ require "graphql"
4
4
  require_relative "graphql/version"
5
5
  require_relative "graphql/types/base_object"
6
6
  require_relative "graphql/types/audit_log_entry_type"
7
+ require_relative "graphql/types/sort_direction_enum"
8
+ require_relative "graphql/types/audit_log_entry_sort_field_enum"
9
+ require_relative "graphql/input_objects/audit_log_entry_sort_input"
7
10
  require_relative "graphql/queries/audit_log_entries_query_mixin"
8
11
 
9
12
  module RailsAuditLog
@@ -8,6 +8,19 @@ module RailsAuditLog
8
8
 
9
9
  class AuditLogEntryType < BaseObject
10
10
  end
11
+
12
+ class SortDirectionEnum < GraphQL::Schema::Enum
13
+ end
14
+
15
+ class AuditLogEntrySortFieldEnum < GraphQL::Schema::Enum
16
+ end
17
+ end
18
+
19
+ module InputObjects
20
+ class AuditLogEntrySortInput < GraphQL::Schema::InputObject
21
+ def field: () -> Symbol
22
+ def direction: () -> Symbol
23
+ end
11
24
  end
12
25
 
13
26
  module Generators
@@ -22,11 +35,48 @@ module RailsAuditLog
22
35
  module Queries
23
36
  module AuditLogEntriesQueryMixin
24
37
  def self.included: (untyped base) -> void
38
+
25
39
  def resolve_audit_log_entry: (id: String) -> untyped
26
- def resolve_audit_log_entries: (?event: String?, ?item_type: String?, ?item_id: String?, ?actor_id: String?, ?page: Integer, ?per_page: Integer) -> untyped
40
+
41
+ def resolve_audit_log_entries: (
42
+ ?event: String?,
43
+ ?item_type: String?,
44
+ ?item_id: String?,
45
+ ?actor_id: String?,
46
+ ?since: Time?,
47
+ ?until_time: Time?,
48
+ ?touching: String?,
49
+ ?order_by: InputObjects::AuditLogEntrySortInput?,
50
+ ?page: Integer,
51
+ ?per_page: Integer
52
+ ) -> untyped
53
+
54
+ def resolve_audit_log_entries_connection: (
55
+ ?event: String?,
56
+ ?item_type: String?,
57
+ ?item_id: String?,
58
+ ?actor_id: String?,
59
+ ?since: Time?,
60
+ ?until_time: Time?,
61
+ ?touching: String?,
62
+ ?order_by: InputObjects::AuditLogEntrySortInput?
63
+ ) -> untyped
64
+
27
65
  private
66
+
67
+ def build_scope: (
68
+ ?event: String?,
69
+ ?item_type: String?,
70
+ ?item_id: String?,
71
+ ?actor_id: String?,
72
+ ?since: Time?,
73
+ ?until_time: Time?,
74
+ ?touching: String?,
75
+ ?order_by: InputObjects::AuditLogEntrySortInput?
76
+ ) -> untyped
77
+
28
78
  def check_authentication!: () -> void
29
79
  end
30
80
  end
31
81
  end
32
- end
82
+ end
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.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith
@@ -83,10 +83,13 @@ files:
83
83
  - codecov.yml
84
84
  - lib/generators/rails_audit_log/graphql/install/install_generator.rb
85
85
  - lib/rails_audit_log/graphql.rb
86
+ - lib/rails_audit_log/graphql/input_objects/audit_log_entry_sort_input.rb
86
87
  - lib/rails_audit_log/graphql/queries/audit_log_entries_query_mixin.rb
87
88
  - lib/rails_audit_log/graphql/release_tooling.rb
89
+ - lib/rails_audit_log/graphql/types/audit_log_entry_sort_field_enum.rb
88
90
  - lib/rails_audit_log/graphql/types/audit_log_entry_type.rb
89
91
  - lib/rails_audit_log/graphql/types/base_object.rb
92
+ - lib/rails_audit_log/graphql/types/sort_direction_enum.rb
90
93
  - lib/rails_audit_log/graphql/version.rb
91
94
  - sig/rails_audit_log/graphql.rbs
92
95
  homepage: https://github.com/eclectic-coding/rails_audit_log-graphql