Add feed endpoints#1242
Open
clementbiron wants to merge 48 commits into
Open
Conversation
c81ac32 to
d2ed924
Compare
d3f3652 to
2582940
Compare
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
Ndpnt
reviewed
Apr 29, 2026
#34335620 introduced case-insensitive matching on/service/:serviceId, contradicting the documented case-sensitive service ID format
Filter documents at query time using the existing isTechnicalUpgrade field when the option is disabled, in findAll, findByService and findByServiceAndTermsType.
Feed subscribers want to be notified of changes in the legal content of services, not of re-renderings of existing snapshots with updated extraction rules. Pass includeTechnicalUpgrades: false to all three versions repository queries used by feed routes. Drop the now-dead technical-upgrade branches in classifyRecordType and buildEntryTitle, and update tests accordingly.
Feed tag URIs (RFC 4151) and entry IDs are built by interpolating collection.metadata.id. When this value is missing, the resulting IDs contain double colons and become technically malformed URIs without any feedback to the operator. Throw explicitly at apiRouter setup so the misconfiguration is caught at boot rather than silently emitted in every feed response.
The feed route no longer imports anything from the git repository implementation: titles come straight from the record. Atom-only labels (record-type categories) remain local to the route.
Falling back to new Date() when no entries exist made the feed-level updated value change on every request, which breaks conditional GET: readers would never see a 304 even when nothing changed. Use the Unix epoch as a stable, RFC-valid placeholder until the first entry lands.
Atom feeds are typically polled every few minutes by RSS readers. Setting Last-Modified from the latest entry's fetch date lets Express honour If-Modified-Since and return 304 when nothing changed, saving the cost of building and shipping the XML body for the (frequent) unchanged case.
Xml-js does not escape attribute values
Pass escapeXmlAttribute through xml-js's attributeValueFn rather than wrapping each attribute manually. Escaping now happens at the serialization boundary for every attribute, including those we did not explicitly wrap before
Ndpnt
approved these changes
May 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request adds Atom feed endpoints to the collection API so consumers can subscribe to recent terms updates. A new
/feedendpoint exposes a collection feed, with variants at/feed/:serviceIdand/feed/:serviceId/:termsType.Contrary to what was discussed in #1238, each entry's primary alternate link points to the GitHub commit rather than to the version API. While testing the feed in real readers, a link resolving to a JSON document felt unhelpful for human consumers, who expect to land on a readable page. The version API is still exposed alongside as a related link, so programmatic consumers can discover it from the feed.Update: each entry now exposes a single
alternatelink. By default it points to the version API, which works for any storage backend. Operators who want feed readers to land on a human-readable page can configurecollection-api.feed.versionUrlTemplate(e.g.https://github.com/openTermsArchive/demo-versions/commit/%VERSION_ID); the placeholder is interpolated with the version's identifier.