atlas_rb 1.18.0 → 1.20.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: dfa719c8d880ec4ed326597fe0882537649b69b6e0e52a3df4123353c1019198
4
- data.tar.gz: 1ffae14221914997c13572495b728dbb93cd02c81144cba4eb5ca33f64bb444a
3
+ metadata.gz: 1ec8ebfc7fd51516a1d73d28bc426153f99a1d7d91c6b1b1bf80ffc965396b8f
4
+ data.tar.gz: 284df1abb1bef59118f44483e3ba2b3680daacd03717795417395ee095950f55
5
5
  SHA512:
6
- metadata.gz: b4705dd193fec70bb702846a51aa08a902a772a76964873d89a11ef2963823e7b5217525a3fb2efed339596ce213f04d6aad3cd43bb8b9387c92ea246e1d4740
7
- data.tar.gz: 3ab173992d0243e249f51dd385cb6b7507bd8478adac2abcb1077e49c04bc0dfcb2d4fc665b9e843e72b17337dd9cdf8e8709008078dc0909befd87ef5472ac1
6
+ metadata.gz: e3fc55be0dde3a6d5ff4603284de7e7b2ed4e29c628afbab32d2026befbfc2cc93d4304e4a294043319c60d79a5f51f2e06cf0957a4ffd9e28af8ffc56f64e36
7
+ data.tar.gz: a8dced08d932a266c77d70cfaa90cf7d81c957efce818ce42c5a000508b48d6501ca449a1863f3a73017b2131692c6930bdcd53e282823f7957a43e5e30e38a9
data/.version CHANGED
@@ -1 +1 @@
1
- 1.18.0
1
+ 1.20.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.20.0
4
+
5
+ ### Added — `System.release_embargoes`, recording lapsed embargoes
6
+
7
+ ```ruby
8
+ AtlasRb::System.release_embargoes # => ["abc123"]
9
+ AtlasRb::System.release_embargoes(since: Date.new(2026, 9, 1))
10
+ ```
11
+
12
+ Binds `POST /embargoes/release`, which needs Atlas 0.6.208 or later. An embargo
13
+ lapsing is not a write, so nothing records it unless someone asks. Atlas writes
14
+ one `release_embargo` audit row per lapsed Work, dated to the start of the
15
+ release day in Eastern time, and returns the NOIDs that gained one.
16
+
17
+ Atlas runs no scheduler, so the consumer supplies the schedule; Cerberus calls
18
+ this nightly. A repeat call writes nothing, and Atlas looks back seven days by
19
+ default, so a missed night catches up on the next call. `since` widens that.
20
+ It is a write, so it raises `ReadOnlyModeError` during a maintenance window.
21
+
22
+ ## 1.19.0
23
+
24
+ ### Added — `Resource.search`, the catalog keyword search
25
+
26
+ ```ruby
27
+ AtlasRb::Resource.search("whaling logbook", type: "Work", page: 1, per_page: 25)
28
+ # => Mash with "results" and "pagination"
29
+ ```
30
+
31
+ Binds `GET /resources/search`, which needs Atlas 0.6.199 or later. It is
32
+ Cerberus's search bar for a caller without Blacklight: the same field weights,
33
+ because both come from the Solr core's search handler, and the same filters for
34
+ the global catalog. It returns the whole envelope, as `descendant_works` does, so
35
+ a caller pages with `pagination.pages`.
36
+
37
+ Each row is a Solr digest, and `klass` is a name `Resource.class_for` accepts, so
38
+ loading the full resource is `class_for(hit.klass).find(hit.noid)`.
39
+
40
+ One difference from Cerberus is deliberate. Atlas gates the rows as its own
41
+ `Ability` reads a resource, so an edit group and the depositor count as well as a
42
+ read group. Cerberus's search still checks read groups only, so for staff and
43
+ depositors this can return items that Cerberus's search does not. Every such item
44
+ is one the user can already open.
45
+
3
46
  ## 1.18.0
4
47
 
5
48
  ### Changed — the write surface is type-agnostic, and the typed writes are gone
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- atlas_rb (1.18.0)
4
+ atlas_rb (1.20.0)
5
5
  faraday (~> 2.7)
6
6
  faraday-follow_redirects (~> 0.3.0)
7
7
  faraday-multipart (~> 1)
@@ -16,7 +16,7 @@ GEM
16
16
  base64 (0.3.0)
17
17
  connection_pool (2.5.5)
18
18
  diff-lcs (1.6.1)
19
- faraday (2.14.3)
19
+ faraday (2.14.4)
20
20
  faraday-net_http (>= 2.0, < 3.5)
21
21
  json
22
22
  logger
data/README.md CHANGED
@@ -641,6 +641,31 @@ tombstoned resources come back flagged (`"tombstoned" => true`), so index
641
641
  by `"noid"` rather than assuming positional correspondence. NOIDs only —
642
642
  raw Valkyrie ids are not a supported input.
643
643
 
644
+ ### Searching the catalog (`Resource.search`)
645
+
646
+ A keyword search, as Cerberus's search bar runs it, for a caller that has words
647
+ rather than a NOID:
648
+
649
+ ```ruby
650
+ result = AtlasRb::Resource.search("whaling logbook", type: "Work", per_page: 50)
651
+ result.pagination.total # => 12
652
+ hit = result.results.first
653
+ hit.title # => "Whaling logbook, 1851"
654
+ AtlasRb::Resource.class_for(hit.klass).find(hit.noid)
655
+ ```
656
+
657
+ It searches Works, Collections, Communities and People, most relevant first.
658
+ `type` narrows to one of those four; any other value is a `400`, raised as
659
+ `AtlasRb::ResourceError`. Leave out the text to browse everything the user may
660
+ read, newest first.
661
+
662
+ Each row is a digest read off Solr — `{ "id", "noid", "klass", "title",
663
+ "creators", "year", "thumbnail", "in_progress", "embargoed", "incomplete" }` —
664
+ not the full typed payload. Rows are **gated to the acting user**: public, one of
665
+ their read or edit groups, or a resource they deposited. So the same text can
666
+ return different results for different users. There are no facets and no sort
667
+ option.
668
+
644
669
  ### Missing resources: `nil` on a read, a raise on a write
645
670
 
646
671
  The two halves of the API answer an absent resource differently, on purpose.
@@ -155,6 +155,55 @@ module AtlasRb
155
155
  .get('/resources/' + id + '/descendant_works')) { |body| AtlasRb::Mash.new(body) }
156
156
  end
157
157
 
158
+ # Keyword search over the catalog, as Cerberus's search bar searches it.
159
+ #
160
+ # Searches Works, Collections, Communities and People, most relevant
161
+ # first, and returns one page. Atlas gates every row to what the acting
162
+ # user may read — public, one of their read or edit groups, or a resource
163
+ # they deposited — so two users can get different results for the same
164
+ # text. Tombstoned resources, featured Collections, personal roots and
165
+ # unfinished deposits (except the caller's own) never appear.
166
+ #
167
+ # Each row is a digest read off Solr, not a resource: `{ "id", "noid",
168
+ # "klass", "title", "creators", "year", "thumbnail", "in_progress",
169
+ # "embargoed", "incomplete" }`. `klass` is one of the four type names
170
+ # above, which {class_for} accepts, so a caller loads the full resource
171
+ # with `class_for(hit.klass).find(hit.noid)`.
172
+ #
173
+ # @param query [String, nil] the search text. Omit or pass blank to browse
174
+ # everything the user may read, newest first.
175
+ # @param type [String, nil] one of `"Work"`, `"Collection"`, `"Community"`,
176
+ # `"Person"`, to narrow the search to that type.
177
+ # @param page [Integer, nil] 1-based page (default 1 server-side).
178
+ # @param per_page [Integer, nil] page size (server default 25, capped 100).
179
+ # @param nuid [String, nil] optional acting user's NUID. On the relay-signing
180
+ # path it is signed into the assertion `sub`; on the BYO-JWT (`ATLAS_JWT`)
181
+ # path it is ignored (identity lives in the token).
182
+ # @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
183
+ # header. Falls through to {AtlasRb.config}.default_on_behalf_of when omitted.
184
+ # @return [AtlasRb::Mash] the parsed envelope, with a `"results"` digest
185
+ # array and a `"pagination"` block (`total` / `page` / `per_page` / `pages`).
186
+ #
187
+ # @raise [AtlasRb::ResourceError] on any non-2xx — a `400` for an unknown
188
+ # `type`, an auth envelope, a `5xx` — carrying Atlas's status and body.
189
+ # @example Find a Work by a word in its title, then load it
190
+ # result = AtlasRb::Resource.search("whaling logbook", type: "Work")
191
+ # hit = result.results.first
192
+ # AtlasRb::Resource.class_for(hit.klass).find(hit.noid)
193
+ # @example Page through every match
194
+ # (1..AtlasRb::Resource.search("whaling").pagination.pages).flat_map do |page|
195
+ # AtlasRb::Resource.search("whaling", page: page).results
196
+ # end
197
+ def self.search(query = nil, type: nil, page: nil, per_page: nil, nuid: nil, on_behalf_of: nil)
198
+ params = {}
199
+ params[:q] = query if query
200
+ params[:type] = type if type
201
+ params[:page] = page if page
202
+ params[:per_page] = per_page if per_page
203
+ read_body(connection(params, nuid, on_behalf_of: on_behalf_of)
204
+ .get("/resources/search")) { |body| AtlasRb::Mash.new(body) }
205
+ end
206
+
158
207
  # Validate a MODS XML document against Atlas's schema *without* persisting it.
159
208
  #
160
209
  # Useful for surfacing validation errors in UIs before the user commits.
@@ -54,5 +54,27 @@ module AtlasRb
54
54
  response = system_connection.post("/resources/#{id}/reindex_subtree")
55
55
  JSON.parse(response.body)["reindexed"]
56
56
  end
57
+
58
+ # Record the embargoes that have lapsed. Atlas writes one `release_embargo`
59
+ # audit row per lapsed Work, dated to the start of the release day in
60
+ # Eastern time rather than to the call. Atlas runs no scheduler, so the
61
+ # consumer calls this on its own schedule — Cerberus nightly.
62
+ #
63
+ # Idempotent: a repeat call writes nothing. Atlas looks back seven days by
64
+ # default, so a missed night catches up on the next call.
65
+ #
66
+ # @param since [Date, nil] the earliest release date to consider, to widen
67
+ # the default seven-day window.
68
+ # @return [Array<String>] NOIDs of the Works that gained a row on this call.
69
+ # @raise [AtlasRb::ReadOnlyModeError] while a maintenance window is open.
70
+ #
71
+ # @example The nightly call
72
+ # AtlasRb::System.release_embargoes # => ["abc123"]
73
+ # @example Catch up after a long outage
74
+ # AtlasRb::System.release_embargoes(since: Date.new(2026, 9, 1))
75
+ def self.release_embargoes(since: nil)
76
+ path = since ? "/embargoes/release?since=#{since.iso8601}" : "/embargoes/release"
77
+ JSON.parse(system_connection.post(path).body)["released"]
78
+ end
57
79
  end
58
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atlas_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.0
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cliff
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-17 00:00:00.000000000 Z
11
+ date: 2026-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday