Skip to main content

2.5.0

· 3 min read
André Aubin
Trefle Core Team

The largest release since Trefle came back. The website has been rebuilt, every upstream source now declares its licence in the API, and a family of endpoint bugs that had been returning 500s went out with it.

Two releases are covered here. 2.4.0 was small and went out quietly: a species you had bookmarked before it was merged into another taxon now resolves through its old slug instead of returning a 404, and the standalone cache-warming service was replaced by a sweep inside the application.

2.5.0 is the substantial one.

Every source now says what its licence is

sources[] on a species payload used to tell you where a value came from. It now tells you what you are allowed to do with it:

{
"id": "3087685",
"name": "GBIF",
"url": "https://www.gbif.org/species/3087685",
"licence": "CC-BY-4.0",
"licence_url": "https://creativecommons.org/licenses/by/4.0/"
}

Only sources with a confirmed licence are filled in. The others stay null rather than carrying a guess — if you see null, it means we have not verified it, not that the data is unencumbered.

Two companion pieces landed with it. There is now a /citation page giving a ready-made citation in plain text, APA and BibTeX, along with a CITATION.cff file in the repository so GitHub and reference managers can read it directly. And accounts created from now on accept terms of use that include a binding attribution clause — API access is unaffected either way, and existing tokens keep working.

Endpoints that were returning 500

A sweep that walks the whole shape of the API — every collection crossed with every filter and order key it accepts — found that /api/v1/corrections failed on every single one of them. Twenty-seven paths, all returning 500:

/api/v1/corrections?filter[user_id]=… 500
/api/v1/corrections?order[record_type]=asc 500

The model was missing the filtering and sorting machinery the controller advertised. Fixed, and covered by a test for each of the eighteen keys so it cannot come back silently.

In the same pass:

  • filter_not[image_url]=null returned nothing on the search endpoints. The list endpoints translate image_url to the real column; the search path had no equivalent, so the filter matched nothing at all. /api/v1/plants/search?q=coco&filter_not[image_url]=null now returns what you would expect.
  • The plants endpoints carried an N+1. The serializer read synonyms and plant.slug per record without preloading them. Removed.

Completion is now public

completion_ratio and complete_data were computed, kept up to date, and visible only to us. They are now on the species payload, so you can tell how much of a record is actually filled in before you rely on it.

A rebuilt website

trefle.io has been redesigned end to end — home, about, donate, explore and account pages — on a shared type and colour system. The browse pages are faster, too: sorting and filtering on the explore views ran without indexes on a table of 464,000 species, which has been corrected.

Under the hood

Sidekiq 7 to 8, the Redis client 5 to 6, and Rack 2.2 to 3.2 as a required consequence. Security updates for rubyzip and devise. Every data-changing job now records what it ran and what it changed, so a bad import is something we can point at rather than reconstruct.

Getting it

Nothing to do — the API is already running this version. If you consume sources[], the two new keys are additive and existing fields are unchanged.