Look a company up in its register, on a press, and keep what is ticked (#1021) #1068

Merged
tiagoagueda merged 1 commit from 1021-register-lookup into main 2026-10-28 04:29:21 +00:00
Owner

The online half of #935, built as option B there: a feature plugin beside the
identifier module, which stays offline and always on. Register lookup
offers Look up in ... beside a company's register number, where an adapter
answers for its country, and beside its LEI (GLEIF), to whoever may change the
company. A press is one request carrying the number and nothing else; the
answer is held in the session and shown on a review page modelled on the
Wikidata one (#673): official name, registered office, state and NACE
activity (#897), each an unticked box. Only what is ticked is kept: the name
through update_company (a clash is refused), the office added beside the
company's addresses, the state with the register's page as its source, the
NACE division as an industry. From an LEI, GLEIF's registeredAs is offered to
a company with no register number, and compared with the one it has, the
cross-check that cannot be made offline.

  • The plugin is off until an administrator switches it on: plugins migration
    0012 writes the instance's "off" row, which the switch on Server settings ->
    Plugins removes as for any other plugin. A press is a register learning
    which company somebody here looks at, so it is the operator's decision.
  • Adapters are a new ungoverned plugin kind, register-adapter, with an open
    entry-point group (postulo.register_adapters) modelled on link services
    (#305). An adapter declares its scheme, country and hosts, builds the
    address and reads the JSON; Postulo makes the request through
    public_only_client, https on a declared host only, with its user agent, a
    deadline, a 2 MB limit and no redirects, under POSTULO_REGISTER_LOOKUP_RATE
    (30/h) through core/throttle. A package cannot take a country Postulo
    answers for. RegisterAdapter, RegisterRecord, RegisterAddress and
    RegisterAdapterPlugin are on the plugin surface.
  • Shipped: France (API Recherche d'entreprises), Norway (Enhetsregisteret),
    Finland (YTJ v3), Czechia (ARES), Poland (KRS) and GLEIF, each confirmed on
    2026-10-27 against the register's documentation and a real answer, recorded
    in the adapters' docstring. Estonia is left out: every documented query
    service needs an agreement and a key. The keyed registers (GB, NL, DK, SE)
    are the follow-up.
  • The record of processing lists each register, its hosts, what it is sent
    and its licence while the plugin is on for anybody; the review page shows
    the attribution each licence asks for. THREAT-MODEL.md has the entry.

Closes #1021
Closes #935

Notes for review

  • Decided by the maintainer (2026-10-27): keyless registers plus GLEIF, off by default. The keyed registers (GB, NL, DK, SE) and Estonia are the follow-up issue.
  • Estonia is left out: every documented query service needs a RIK agreement and a key.
  • Confirmed on 2026-10-27 (sources in the docstring of plugins/register_lookup/adapters.py):
    • FR (Licence Ouverte 2.0);
    • NO (NLOD 2.0);
    • FI (YTJ v3, CC BY 4.0);
    • CZ (ARES; no licence stated);
    • PL (KRS);
    • GLEIF (CC0).
  • Off by default: migration plugins 0012_register_lookup_starts_off writes the instance's FORCED_OFF row, and the existing switch removes it.
  • Only confirmed fields are mapped: CZ offers no activity and PL no state. GLEIF's INACTIVE is shown, not offered.
  • A registered office is kept as a new address, never replacing one.
  • Rebased over #913: the record of processing lists both the geocoder and the registers.

🤖 Generated with Claude Code

The online half of #935, built as option B there: a feature plugin beside the identifier module, which stays offline and always on. *Register lookup* offers *Look up in ...* beside a company's register number, where an adapter answers for its country, and beside its LEI (GLEIF), to whoever may change the company. A press is one request carrying the number and nothing else; the answer is held in the session and shown on a review page modelled on the Wikidata one (#673): official name, registered office, state and NACE activity (#897), each an unticked box. Only what is ticked is kept: the name through update_company (a clash is refused), the office added beside the company's addresses, the state with the register's page as its source, the NACE division as an industry. From an LEI, GLEIF's registeredAs is offered to a company with no register number, and compared with the one it has, the cross-check that cannot be made offline. - The plugin is off until an administrator switches it on: plugins migration 0012 writes the instance's "off" row, which the switch on Server settings -> Plugins removes as for any other plugin. A press is a register learning which company somebody here looks at, so it is the operator's decision. - Adapters are a new ungoverned plugin kind, register-adapter, with an open entry-point group (postulo.register_adapters) modelled on link services (#305). An adapter declares its scheme, country and hosts, builds the address and reads the JSON; Postulo makes the request through public_only_client, https on a declared host only, with its user agent, a deadline, a 2 MB limit and no redirects, under POSTULO_REGISTER_LOOKUP_RATE (30/h) through core/throttle. A package cannot take a country Postulo answers for. RegisterAdapter, RegisterRecord, RegisterAddress and RegisterAdapterPlugin are on the plugin surface. - Shipped: France (API Recherche d'entreprises), Norway (Enhetsregisteret), Finland (YTJ v3), Czechia (ARES), Poland (KRS) and GLEIF, each confirmed on 2026-10-27 against the register's documentation and a real answer, recorded in the adapters' docstring. Estonia is left out: every documented query service needs an agreement and a key. The keyed registers (GB, NL, DK, SE) are the follow-up. - The record of processing lists each register, its hosts, what it is sent and its licence while the plugin is on for anybody; the review page shows the attribution each licence asks for. THREAT-MODEL.md has the entry. Closes #1021 Closes #935 ## Notes for review - **Decided by the maintainer (2026-10-27):** keyless registers plus GLEIF, off by default. The keyed registers (GB, NL, DK, SE) and Estonia are the follow-up issue. - **Estonia is left out:** every documented query service needs a RIK agreement and a key. - **Confirmed on 2026-10-27** (sources in the docstring of `plugins/register_lookup/adapters.py`): - FR (Licence Ouverte 2.0); - NO (NLOD 2.0); - FI (YTJ v3, CC BY 4.0); - CZ (ARES; no licence stated); - PL (KRS); - GLEIF (CC0). - **Off by default:** migration `plugins 0012_register_lookup_starts_off` writes the instance's FORCED_OFF row, and the existing switch removes it. - **Only confirmed fields are mapped:** CZ offers no activity and PL no state. GLEIF's INACTIVE is shown, not offered. - **A registered office** is kept as a new address, never replacing one. - **Rebased over #913:** the record of processing lists both the geocoder and the registers. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Look a company up in its register, on a press, and keep what is ticked (#1021)
Some checks failed
CI / Browser tests (Chromium) (pull_request) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (pull_request) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Has been cancelled
CI / Database tests on PostgreSQL (pull_request) Has been cancelled
CI / Security audit (pull_request) Has been cancelled
CI / Browser tests (Chromium) (push) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (push) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (push) Has been cancelled
CI / Database tests on PostgreSQL (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Every Python / Unit tests (Python 3.12) (push) Has been cancelled
Every Python / Unit tests (Python 3.13) (push) Has been cancelled
6c548ad061
The online half of #935, built as option B there: a feature plugin beside the
identifier module, which stays offline and always on. *Register lookup*
offers *Look up in ...* beside a company's register number, where an adapter
answers for its country, and beside its LEI (GLEIF), to whoever may change the
company. A press is one request carrying the number and nothing else; the
answer is held in the session and shown on a review page modelled on the
Wikidata one (#673): official name, registered office, state and NACE
activity (#897), each an unticked box. Only what is ticked is kept: the name
through update_company (a clash is refused), the office added beside the
company's addresses, the state with the register's page as its source, the
NACE division as an industry. From an LEI, GLEIF's registeredAs is offered to
a company with no register number, and compared with the one it has, the
cross-check that cannot be made offline.

- The plugin is off until an administrator switches it on: plugins migration
  0012 writes the instance's "off" row, which the switch on Server settings ->
  Plugins removes as for any other plugin. A press is a register learning
  which company somebody here looks at, so it is the operator's decision.
- Adapters are a new ungoverned plugin kind, register-adapter, with an open
  entry-point group (postulo.register_adapters) modelled on link services
  (#305). An adapter declares its scheme, country and hosts, builds the
  address and reads the JSON; Postulo makes the request through
  public_only_client, https on a declared host only, with its user agent, a
  deadline, a 2 MB limit and no redirects, under POSTULO_REGISTER_LOOKUP_RATE
  (30/h) through core/throttle. A package cannot take a country Postulo
  answers for. RegisterAdapter, RegisterRecord, RegisterAddress and
  RegisterAdapterPlugin are on the plugin surface.
- Shipped: France (API Recherche d'entreprises), Norway (Enhetsregisteret),
  Finland (YTJ v3), Czechia (ARES), Poland (KRS) and GLEIF, each confirmed on
  2026-10-27 against the register's documentation and a real answer, recorded
  in the adapters' docstring. Estonia is left out: every documented query
  service needs an agreement and a key. The keyed registers (GB, NL, DK, SE)
  are the follow-up.
- The record of processing lists each register, its hosts, what it is sent
  and its licence while the plugin is on for anybody; the review page shows
  the attribution each licence asks for. THREAT-MODEL.md has the entry.

Closes #1021
Closes #935

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tiagoagueda force-pushed 1021-register-lookup from 6c548ad061
Some checks failed
CI / Browser tests (Chromium) (pull_request) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (pull_request) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Has been cancelled
CI / Database tests on PostgreSQL (pull_request) Has been cancelled
CI / Security audit (pull_request) Has been cancelled
CI / Browser tests (Chromium) (push) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (push) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (push) Has been cancelled
CI / Database tests on PostgreSQL (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Every Python / Unit tests (Python 3.12) (push) Has been cancelled
Every Python / Unit tests (Python 3.13) (push) Has been cancelled
to e69ff6ca44
Some checks failed
CI / Unit tests and coverage (Python 3.14) (push) Successful in 13m11s
CI / Checks: lint, migrations, catalogues, settings, built files (push) Successful in 2m57s
CI / Security audit (push) Successful in 1m6s
Every Python / Unit tests (Python 3.12) (push) Has been cancelled
CI / Database tests on PostgreSQL (push) Successful in 4m19s
CI / Browser tests (Chromium) (push) Successful in 31m54s
Every Python / Unit tests (Python 3.13) (push) Has been cancelled
CI / Browser tests (Chromium) (pull_request) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (pull_request) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Has been cancelled
CI / Database tests on PostgreSQL (pull_request) Has been cancelled
CI / Security audit (pull_request) Has been cancelled
2026-10-27 21:45:29 +00:00
Compare
tiagoagueda force-pushed 1021-register-lookup from e69ff6ca44
Some checks failed
CI / Unit tests and coverage (Python 3.14) (push) Successful in 13m11s
CI / Checks: lint, migrations, catalogues, settings, built files (push) Successful in 2m57s
CI / Security audit (push) Successful in 1m6s
Every Python / Unit tests (Python 3.12) (push) Has been cancelled
CI / Database tests on PostgreSQL (push) Successful in 4m19s
CI / Browser tests (Chromium) (push) Successful in 31m54s
Every Python / Unit tests (Python 3.13) (push) Has been cancelled
CI / Browser tests (Chromium) (pull_request) Has been cancelled
CI / Unit tests and coverage (Python 3.14) (pull_request) Has been cancelled
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Has been cancelled
CI / Database tests on PostgreSQL (pull_request) Has been cancelled
CI / Security audit (pull_request) Has been cancelled
to 3593e3455e
All checks were successful
CI / Unit tests and coverage (Python 3.14) (push) Successful in 13m56s
CI / Checks: lint, migrations, catalogues, settings, built files (push) Successful in 3m6s
CI / Browser tests (Chromium) (push) Successful in 32m41s
Every Python / Unit tests (Python 3.13) (push) Successful in 13m12s
CI / Database tests on PostgreSQL (push) Successful in 4m9s
Every Python / Unit tests (Python 3.12) (push) Successful in 13m21s
CI / Checks: lint, migrations, catalogues, settings, built files (pull_request) Successful in 3m8s
CI / Browser tests (Chromium) (pull_request) Successful in 32m42s
CI / Security audit (push) Successful in 1m7s
CI / Unit tests and coverage (Python 3.14) (pull_request) Successful in 13m8s
CI / Database tests on PostgreSQL (pull_request) Successful in 4m11s
CI / Security audit (pull_request) Successful in 1m5s
2026-10-28 04:25:33 +00:00
Compare
tiagoagueda deleted branch 1021-register-lookup 2026-10-28 04:29:23 +00:00
Sign in to join this conversation.
No reviewers
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!1068
No description provided.