patch_retention 0.2.2 → 0.3.1

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: 2ff39a288451016541c8a8f63aca54115fb7f2a4e6a83daea5b503ebe7956fb5
4
- data.tar.gz: 6046dfe6d5692149f069ce54f14fd84bffb9139f3403710eb12c3050619f5130
3
+ metadata.gz: 9642c7116bc29f3cc1e9368c861ac11d13b2357ab778b4f9395fa2bb14c3edb3
4
+ data.tar.gz: 7dc040049c15f9b32eb83d06a986daa0da1c4c881d1dfd2553dc764d9fbba494
5
5
  SHA512:
6
- metadata.gz: a3ea0a8fe3c04033678ebd81da8b003a995baa8515ebb2f518c459acf9a2d4d5f97ccb3499143ea4ee2f2595c3cdcad28b19d97620929e3a9834fad27b57d1f6
7
- data.tar.gz: d4c4fb944b2412112d19155f1f4bbe1d190fc23e9ff9ea3584a8bf5505668c996a708f5a8dc8174080e4cbaa5c8dced9d53eda0ff4f1f114dd33c27f9f60e3f8
6
+ metadata.gz: cd6b62c587f1ad1ed68b579bfcd70403a916de81593248d4850664b4495dc2ff316d279b338952dfb332f038f1c3b63240907345544298becbf14fe749345806
7
+ data.tar.gz: 82fe4b41064b55979b281ad05e48459ae3230e04d91f32065ecab1bf030e337bc56b791a6786ba09fb6bee7b7ec75a808485b8f986713cb888543248278e43f0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.1] - 2025-09-04
4
+
5
+ ### Added
6
+ - Added `tags` parameter support to `CalendarItems.create` method for categorizing calendar items
7
+ - Added `email` parameter to `Contacts.all` method for filtering contacts by email address
8
+
9
+ ### Changed
10
+ - **BREAKING**: Updated `Contacts.all` method to use keyword arguments (limit:, offset:, email:, config:) instead of positional arguments
11
+
12
+ ## [0.3.0] - 2025-07-27
13
+
14
+ ### Added
15
+ - Calendar Items API support with full CRUD operations:
16
+ - `create` - Create calendar events for contacts
17
+ - `update` - Update existing calendar items
18
+ - `find` - Retrieve a specific calendar item
19
+ - `delete` - Remove calendar items
20
+ - `all` - List calendar items with filtering and pagination support
21
+ - Support for calendar item metadata including description, location, external_id, external_data, and tags
22
+ - Comprehensive test coverage for Calendar Items functionality
23
+
3
24
  ## [0.2.0] - 2025-05-26
4
25
 
5
26
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- patch_retention (0.2.2)
4
+ patch_retention (0.3.1)
5
5
  faraday (~> 1.10)
6
6
  zeitwerk (~> 2.6)
7
7
 
data/README.md CHANGED
@@ -118,7 +118,21 @@ Then, you can use the gem's methods to interact with the API.
118
118
  To retrieve all contacts:
119
119
 
120
120
  ```ruby
121
+ # Basic usage
121
122
  contacts = PatchRetention::Contacts.all
123
+
124
+ # With pagination (using keyword arguments)
125
+ contacts = PatchRetention::Contacts.all(limit: 10, offset: 0)
126
+
127
+ # With email filter
128
+ contacts = PatchRetention::Contacts.all(email: 'john.doe@example.com')
129
+
130
+ # With pagination and email filter
131
+ contacts = PatchRetention::Contacts.all(
132
+ limit: 50,
133
+ offset: 0,
134
+ email: 'john@example.com'
135
+ )
122
136
  ```
123
137
 
124
138
  To retrieve a single contact:
@@ -290,6 +304,90 @@ To find a membership:
290
304
  membership = PatchRetention::Memberships.find(membership_id: "mem_xxxxxxxxxxxxxx")
291
305
  ```
292
306
 
307
+ **Calendar Items**
308
+
309
+ To create a calendar item:
310
+
311
+ ```ruby
312
+ calendar_item = PatchRetention::CalendarItems.create(
313
+ contact_id: "ct_xxxxxxxxxxxxxx", # Required, ID of the contact
314
+ title: "Tennis Court Reservation", # Required, title of the event
315
+ start_at: "2025-02-01T10:00:00Z", # Required, ISO8601 timestamp - when the event starts
316
+ end_at: "2025-02-01T11:00:00Z", # Required, ISO8601 timestamp - when the event ends
317
+ run_start_at: "2025-02-01T09:30:00Z", # Optional, ISO8601 - when to run the event for this item (defaults to start_at if not set)
318
+ run_end_at: "2025-02-01T11:30:00Z", # Optional, ISO8601 - when to run the event for this item (defaults to end_at if not set)
319
+ data: { # Optional, additional metadata that will be included in the calendar item
320
+ external_id: "res_123456", # Your system's ID
321
+ facility_id: "fac_789",
322
+ court_name: "Court 1",
323
+ reservation_type: "match"
324
+ },
325
+ tags: ["tennis", "premium", "court1"], # Optional, array of tags to categorize the calendar item
326
+ time_occurred: "2025-01-28T09:00:00Z", # Optional, ISO8601 - past or current time for the event (will default to now)
327
+ skip_triggers: false # Optional, if set to false or empty, any automation tied to the calendar item will not run
328
+ )
329
+ # => {"id"=>"cal_xxxxxxxxxxxxxx", "contact_id"=>"ct_xxxxxxxxxxxxxx", ...}
330
+ ```
331
+
332
+ To update a calendar item:
333
+
334
+ ```ruby
335
+ calendar_item = PatchRetention::CalendarItems.update(
336
+ calendar_item_id: "cal_xxxxxxxxxxxxxx",
337
+ title: "Updated Tennis Match",
338
+ end_at: "2025-02-01T12:00:00Z", # Extend by 1 hour
339
+ data: {
340
+ description: "Match extended due to tie-break"
341
+ },
342
+ tags: ["Tennis", "Extended", "Tie-break"] # Tags as separate parameter
343
+ )
344
+ ```
345
+
346
+ To find a calendar item:
347
+
348
+ ```ruby
349
+ calendar_item = PatchRetention::CalendarItems.find(calendar_item_id: "cal_xxxxxxxxxxxxxx")
350
+ ```
351
+
352
+ To delete a calendar item:
353
+
354
+ ```ruby
355
+ result = PatchRetention::CalendarItems.delete(calendar_item_id: "cal_xxxxxxxxxxxxxx")
356
+ # => { success: true }
357
+ ```
358
+
359
+ To list calendar items:
360
+
361
+ ```ruby
362
+ # List all calendar items
363
+ calendar_items = PatchRetention::CalendarItems.all()
364
+
365
+ # List calendar items for a specific contact
366
+ calendar_items = PatchRetention::CalendarItems.all(contact_id: "ct_xxxxxxxxxxxxxx")
367
+
368
+ # List calendar items within ID range (MongoDB IDs)
369
+ calendar_items = PatchRetention::CalendarItems.all(
370
+ min_id: "0123456789abcdefghijklmn", # Get all items on or after this ID
371
+ max_id: "0123456789abcdefghijklmn" # Get all items on or before this ID
372
+ )
373
+
374
+ # List specific calendar items by IDs (comma-separated)
375
+ calendar_items = PatchRetention::CalendarItems.all(
376
+ id: "0123456789abcdefghijklmn,123456789abcdefghijklmn"
377
+ )
378
+
379
+ # Filter by date range (predefined options)
380
+ calendar_items = PatchRetention::CalendarItems.all(
381
+ date_range: "Today" # Options: "Today", "Yesterday", "Last 7 Days", "This Week", "Last Week", "Last 30 Days"
382
+ )
383
+
384
+ # With pagination
385
+ calendar_items = PatchRetention::CalendarItems.all(
386
+ limit: 50, # Default is 50, max is 100
387
+ offset: 25 # Skip first 25 results
388
+ )
389
+ ```
390
+
293
391
  ## Development
294
392
 
295
393
  After checking out the repo, run `bin/setup` to install dependencies.
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PatchRetention
4
+ class CalendarItems
5
+ class << self
6
+ def create(contact_id:, title:, start_at:, end_at:, run_start_at: nil, run_end_at: nil,
7
+ data: nil, time_occurred: nil, skip_triggers: false, tags: nil, config: nil)
8
+ payload = {
9
+ contact_id: contact_id,
10
+ title: title,
11
+ start_at: start_at,
12
+ end_at: end_at,
13
+ }
14
+ payload[:run_start_at] = run_start_at if run_start_at
15
+ payload[:run_end_at] = run_end_at if run_end_at
16
+ payload[:data] = data if data
17
+ payload[:time_occurred] = time_occurred if time_occurred
18
+ payload[:skip_triggers] = skip_triggers unless skip_triggers.nil?
19
+ payload[:tags] = tags if tags
20
+
21
+ response = PatchRetention.connection(config).post("/v2/calendar_items") do |req|
22
+ req.body = payload.to_json
23
+ req.headers["Content-Type"] = "application/json"
24
+ end
25
+
26
+ JSON.parse(response.body)
27
+ rescue Faraday::Error => e
28
+ raise Error, "Failed to create calendar item: #{e.message}"
29
+ end
30
+
31
+ def update(calendar_item_id:, title: nil, start_at: nil, end_at: nil, run_start_at: nil,
32
+ run_end_at: nil, data: nil, tags: nil, config: nil)
33
+ payload = {}
34
+ payload[:title] = title if title
35
+ payload[:start_at] = start_at if start_at
36
+ payload[:end_at] = end_at if end_at
37
+ payload[:run_start_at] = run_start_at if run_start_at
38
+ payload[:run_end_at] = run_end_at if run_end_at
39
+ payload[:data] = data if data
40
+ payload[:tags] = tags if tags
41
+
42
+ response = PatchRetention.connection(config).patch("/v2/calendar_items/#{calendar_item_id}") do |req|
43
+ req.body = payload.to_json
44
+ req.headers["Content-Type"] = "application/json"
45
+ end
46
+
47
+ JSON.parse(response.body)
48
+ rescue Faraday::Error => e
49
+ raise Error, "Failed to update calendar item: #{e.message}"
50
+ end
51
+
52
+ def find(calendar_item_id:, config: nil)
53
+ response = PatchRetention.connection(config).get("/v2/calendar_items/#{calendar_item_id}")
54
+
55
+ JSON.parse(response.body)
56
+ rescue Faraday::Error => e
57
+ raise Error, "Failed to find calendar item: #{e.message}"
58
+ end
59
+
60
+ def delete(calendar_item_id:, config: nil)
61
+ response = PatchRetention.connection(config).delete("/v2/calendar_items/#{calendar_item_id}")
62
+
63
+ { success: response.status == 204 }
64
+ rescue Faraday::Error => e
65
+ raise Error, "Failed to delete calendar item: #{e.message}"
66
+ end
67
+
68
+ def all(contact_id: nil, min_id: nil, max_id: nil, id: nil, date_range: nil, limit: nil, offset: nil, config: nil)
69
+ params = {}
70
+ params[:contact_id] = contact_id if contact_id
71
+ params[:min_id] = min_id if min_id
72
+ params[:max_id] = max_id if max_id
73
+ params[:id] = id if id
74
+ params[:date_range] = date_range if date_range
75
+ params[:limit] = limit if limit
76
+ params[:offset] = offset if offset
77
+
78
+ response = PatchRetention.connection(config).get("/v2/calendar_items", params)
79
+
80
+ JSON.parse(response.body)
81
+ rescue Faraday::Error => e
82
+ raise Error, "Failed to retrieve calendar items: #{e.message}"
83
+ end
84
+ end
85
+ end
86
+ end
@@ -29,13 +29,16 @@ module PatchRetention::Contacts::Find
29
29
  #
30
30
  # @param limit [Integer] The number of contacts to retrieve per page.
31
31
  # @param offset [Integer] The number of contacts to skip before starting to collect the result set.
32
+ # @param email [String] Optional email to filter contacts by.
33
+ # @param config [Configuration] Optional configuration object.
32
34
  # @return [Object] The response from the PatchRetention API.
33
35
  # @raise [PatchRetention::Error] If the API returns a status other than 200.
34
- def all(limit, offset, config = nil)
36
+ def all(limit:, offset:, email: nil, config: nil)
35
37
  raise_error_if_present do
36
38
  PatchRetention.connection(config).get(PatchRetention::Contacts::API_PATH) do |req|
37
39
  req.params["limit"] = limit
38
40
  req.params["offset"] = offset
41
+ req.params["email"] = email if email
39
42
  end
40
43
  end
41
44
  end
@@ -8,8 +8,8 @@ class PatchRetention::Contacts
8
8
  Find.by_id(id, config)
9
9
  end
10
10
 
11
- def all(limit = 30, offset = 0, config = nil)
12
- Find.all(limit, offset, config)
11
+ def all(limit: 30, offset: 0, email: nil, config: nil)
12
+ Find.all(limit: limit, offset: offset, email: email, config: config)
13
13
  end
14
14
 
15
15
  def find_or_create_by(contact_params:, query_params: {}, config: nil)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PatchRetention
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/patch_retention/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "patch_retention"
7
+ spec.version = PatchRetention::VERSION
8
+ spec.authors = ["Playbypoint", "Gerardo Ortega"]
9
+ spec.email = ["webmaster@playbypoint.com", "g3ortega@gmail.com"]
10
+
11
+ spec.summary = "Patch Retention API wrapper."
12
+ spec.description = "Patch Retention API wrapper."
13
+ spec.homepage = "https://playbypoint.com"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.1.0"
16
+
17
+ # spec.metadata["allowed_push_host"] = "Set to your gem server 'https://example.com'"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = "https://playbypoint.com"
21
+ spec.metadata["changelog_uri"] = "https://playbypoint.com"
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(__dir__) do
26
+ %x(git ls-files -z).split("\x0").reject do |f|
27
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
+ end
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ # Runtime dependencies
35
+ spec.add_dependency("faraday", "~> 1.10")
36
+ spec.add_dependency("zeitwerk", "~> 2.6")
37
+
38
+ # Development dependencies
39
+ spec.add_development_dependency("bundler", "~> 2.0")
40
+ spec.add_development_dependency("bundler-audit", "~> 0.9")
41
+ spec.add_development_dependency("byebug")
42
+ spec.add_development_dependency("dotenv", "~> 2.8")
43
+ spec.add_development_dependency("pry")
44
+ spec.add_development_dependency("rake", "~> 13.0")
45
+ spec.add_development_dependency("rspec", "~> 3.0")
46
+ spec.add_development_dependency("rubocop", "~> 1.21")
47
+ spec.add_development_dependency("rubocop-shopify", "~> 2.15")
48
+ spec.add_development_dependency("thor", ">= 1.4.0")
49
+ spec.add_development_dependency("vcr", "~> 6.0")
50
+ spec.add_development_dependency("webmock", "~> 3.0")
51
+
52
+ # Security update for rexml
53
+ spec.add_development_dependency("rexml", ">= 3.3.9")
54
+
55
+ # For more information and examples about making a new gem, check out our
56
+ # guide at: https://bundler.io/guides/creating_gem.html
57
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patch_retention
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Playbypoint
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-07-28 00:00:00.000000000 Z
12
+ date: 2025-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -67,20 +67,6 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0.9'
70
- - !ruby/object:Gem::Dependency
71
- name: thor
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: 1.4.0
77
- type: :development
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: 1.4.0
84
70
  - !ruby/object:Gem::Dependency
85
71
  name: byebug
86
72
  requirement: !ruby/object:Gem::Requirement
@@ -179,6 +165,20 @@ dependencies:
179
165
  - - "~>"
180
166
  - !ruby/object:Gem::Version
181
167
  version: '2.15'
168
+ - !ruby/object:Gem::Dependency
169
+ name: thor
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: 1.4.0
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: 1.4.0
182
182
  - !ruby/object:Gem::Dependency
183
183
  name: vcr
184
184
  requirement: !ruby/object:Gem::Requirement
@@ -251,6 +251,7 @@ files:
251
251
  - docs/references/troubleshooting.md
252
252
  - docs/wip/session-2025-05-26.md
253
253
  - lib/patch_retention.rb
254
+ - lib/patch_retention/calendar_items.rb
254
255
  - lib/patch_retention/configuration.rb
255
256
  - lib/patch_retention/contacts.rb
256
257
  - lib/patch_retention/contacts/delete.rb
@@ -264,6 +265,7 @@ files:
264
265
  - lib/patch_retention/products.rb
265
266
  - lib/patch_retention/util.rb
266
267
  - lib/patch_retention/version.rb
268
+ - patch_retention.gemspec
267
269
  - script/setup_test_env
268
270
  - sig/patch_retention.rbs
269
271
  homepage: https://playbypoint.com