Plugins: reference data and lookups (ESCO, NACE, GeoNames) as bundled plugins, with a suggestion-source kind #1252

Open
opened 2026-11-13 10:49:43 +00:00 by tiagoagueda · 0 comments
Owner

The need

Data lookups and reference data should be plugins, so that Postulo stays modular: a person turns one off, replaces it, or installs another for their country, and core carries only the mechanism. What is a plugin today and what is not (read from main, 2026-11-13):

Lookup / data Today
Wikidata (company item, names in other languages) plugin (plugins/wikidata, kind feature), on a press only
Company registers, Annuaire des Entreprises, the Norwegian, Finnish, Czech, Polish registers, GLEIF plugins in one package (plugins/register_lookup: one feature plus the register-adapter kind), so the Annuaire is an adapter, not a plugin of its own
DOI / ORCID publications plugin (plugins/publication_lookups)
Map and GeoNames places plugin (plugins/maps) for the dots, but the offline place table and the city search are read by core (jobs/geocoding.py, jobs/places.py)
ESCO occupations and skills core: jobs/esco.py, fetch_esco, read directly by the application forms and the checks
NACE sectors and industries core: jobs/industries.py, data/nace-2.1.json
Company logo fetching core (jobs/logos.py)

So the lookups with a button are already plugins; the reference vocabularies that feed suggestions (ESCO, NACE, the place table) are not, and #1251 (suggestions in most fields) would add one more core-only mechanism.

Wanted

  1. A suggestion-source plugin kind (beside register-adapter, identifier, link-service): a plugin declares which fields it can suggest for (job_title, skill, industry, city, company, school, ...), the languages it covers, whether it is offline or needs the network, and the licence of its data. #1251's component asks the enabled sources, merges and ranks the answers (the person's own entries first), and shows the source of each suggestion.
  2. ESCO, NACE and GeoNames become bundled plugins (shipped inside core as register_lookup is, installed by default, removable): esco (occupations, skills), nace (sectors and industries, with the short labels of #1248), geonames (cities and postcodes, offline). Core keeps no import of them: forms and checks ask the registry, and the application runs, with plainer fields, when one is absent. Their data files, licences and fetch_* commands move with them.
  3. The Annuaire as its own plugin where it helps (a French user installs it; the rest of the register adapters stay together), decided in this issue: either keep adapters as one package per country or one plugin per register.
  4. Each plugin says what it sends: a lookup that calls a service states the host and the data it sends in its manifest and the consent screen (plugins/consent.py), and is off until the person enables it, as #879 and #1187 decided.
  5. The plugin surface (plugins/api.py, the published postulo.plugins.testing check) gains the kind, with a contract test, and the helloworld reference plugin shows one; the plugin guide in the wiki documents it, for the Writing-a-plugin page.

Decisions to take here

  • Which are bundled and on by default (offline reference data, yes; anything that calls a network service, no).
  • Archive and API: data a plugin created (a company's Wikidata names, an ESCO code) stays when the plugin is removed, and is shown as plain data.
  • Order: the kind and ESCO first (the biggest coupling), NACE with #1248, GeoNames with #1249/#1251's city field.

Tests

The application starts and every form works with each of the three plugins disabled; suggestions come only from enabled sources; the consent screen lists the hosts a lookup contacts; the plugin contract test passes for the new kind; removing a plugin leaves its data readable.

Related: #1251, #1248, #1249, #1245, #879, #1187, #1170.

## The need Data lookups and reference data should be plugins, so that Postulo stays modular: a person turns one off, replaces it, or installs another for their country, and core carries only the mechanism. What is a plugin today and what is not (read from `main`, 2026-11-13): | Lookup / data | Today | | --- | --- | | Wikidata (company item, names in other languages) | **plugin** (`plugins/wikidata`, kind `feature`), on a press only | | Company registers, Annuaire des Entreprises, the Norwegian, Finnish, Czech, Polish registers, GLEIF | **plugins in one package** (`plugins/register_lookup`: one `feature` plus the `register-adapter` kind), so the Annuaire is an adapter, not a plugin of its own | | DOI / ORCID publications | **plugin** (`plugins/publication_lookups`) | | Map and GeoNames places | **plugin** (`plugins/maps`) for the dots, but the offline place table and the city search are read by core (`jobs/geocoding.py`, `jobs/places.py`) | | **ESCO** occupations and skills | **core**: `jobs/esco.py`, `fetch_esco`, read directly by the application forms and the checks | | **NACE** sectors and industries | **core**: `jobs/industries.py`, `data/nace-2.1.json` | | Company logo fetching | **core** (`jobs/logos.py`) | So the lookups with a button are already plugins; the **reference vocabularies that feed suggestions (ESCO, NACE, the place table)** are not, and #1251 (suggestions in most fields) would add one more core-only mechanism. ## Wanted 1. **A `suggestion-source` plugin kind** (beside `register-adapter`, `identifier`, `link-service`): a plugin declares which fields it can suggest for (`job_title`, `skill`, `industry`, `city`, `company`, `school`, ...), the languages it covers, whether it is offline or needs the network, and the licence of its data. #1251's component asks the enabled sources, merges and ranks the answers (the person's own entries first), and shows the source of each suggestion. 2. **ESCO, NACE and GeoNames become bundled plugins** (shipped inside core as `register_lookup` is, installed by default, removable): `esco` (occupations, skills), `nace` (sectors and industries, with the short labels of #1248), `geonames` (cities and postcodes, offline). Core keeps no import of them: forms and checks ask the registry, and the application runs, with plainer fields, when one is absent. Their data files, licences and `fetch_*` commands move with them. 3. **The Annuaire as its own plugin** where it helps (a French user installs it; the rest of the register adapters stay together), decided in this issue: either keep adapters as one package per country or one plugin per register. 4. **Each plugin says what it sends:** a lookup that calls a service states the host and the data it sends in its manifest and the consent screen (`plugins/consent.py`), and is off until the person enables it, as #879 and #1187 decided. 5. **The plugin surface** (`plugins/api.py`, the published `postulo.plugins.testing` check) gains the kind, with a contract test, and the helloworld reference plugin shows one; the plugin guide in the wiki documents it, for the Writing-a-plugin page. ## Decisions to take here - Which are bundled and on by default (offline reference data, yes; anything that calls a network service, no). - Archive and API: data a plugin created (a company's Wikidata names, an ESCO code) stays when the plugin is removed, and is shown as plain data. - Order: the kind and ESCO first (the biggest coupling), NACE with #1248, GeoNames with #1249/#1251's city field. ## Tests The application starts and every form works with each of the three plugins disabled; suggestions come only from enabled sources; the consent screen lists the hosts a lookup contacts; the plugin contract test passes for the new kind; removing a plugin leaves its data readable. Related: #1251, #1248, #1249, #1245, #879, #1187, #1170.
tiagoagueda added this to the 0.6.0 milestone 2026-11-13 10:49:43 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#1252
No description provided.