Fetch and transform upstream JSON data into schema.org shaped documents, then persist the result to Typesense.
The current branch is built around dedicated ingestion scripts in run/, not a single generic CLI transform switch. Each script wires a reader, paginator, transform, lock, logger, and Typesense target for one integration.
- PHP 8.2+
- Composer
- cURL extension enabled for PHP
- A reachable Typesense instance for the production-style
run/*scripts
git clone https://github.com/helsingborg-stad/schema.org-transformer.git
cd schema.org-transformer
composer installrun/: executable ingestion entrypoints used in deployments and cron jobssrc/Transforms/: mapping logic for each upstream domainsrc/IO/V2/HttpReader.php: paginated HTTP reader used by the run scriptssrc/Storage/TypesenseStorage/: persistence layer and collection config for Typesensesrc/Paginators/: pagination strategies for WordPress-style and non-paginated APIssrc/LockRunner/: file-lock protection that prevents the same pipeline from running concurrentlytests/andsrc/**/*Test.php: PHPUnit coverage for transforms, mappers, utilities, and storage helpers
Each run/* script follows the same pattern:
- Acquire a lock for the pipeline.
- Read JSON from an upstream HTTP endpoint.
- Apply a dedicated transform.
- Page through the source when needed.
- Clear previously generated documents in a target Typesense collection using a pipeline-specific filter.
- Store the transformed documents in Typesense.
The school transforms also enrich their output by querying the Event collection in Typesense and attaching related events by school name.
| Script | Source env var | Transform | Typesense collection | Pagination |
|---|---|---|---|---|
run/Event |
WP_EVENTS_API_URL |
WPHeadlessEventTransform |
Event |
WordpressPaginator |
run/Event.legacy |
WP_LEGACY_EVENTS_API_URL |
WPLegacyEventTransform |
Event |
WordpressPaginator |
run/Event.library |
AXIELL_EVENTS_URL |
AxiellEventTransform |
Event |
NullPaginator |
run/Event.tix |
TIX_EVENTS_API_URL |
TixEventTransform |
Event |
WordpressPaginator |
run/ExhibitionEvent |
WORDPRESS_EXHIBITION_EVENT_PATH |
WPExhibitionEventTransform |
ExhibitionEvent |
WordpressPaginator |
run/JobPosting.public |
REACHMEE_HELSINGBORG_PATH |
ReachmeeJobPostingTransform |
JobPosting.public |
NullPaginator |
run/JobPosting.private |
REACHMEE_INTRANAT_HELSINGBORG_PATH |
ReachmeeJobPostingTransform |
JobPosting.private |
NullPaginator |
run/ElementarySchool |
ELEMENTARY_SCHOOL_API_URL |
ElementarySchoolTransform |
ElementarySchool |
WordpressPaginator |
run/PreSchool |
PRE_SCHOOL_API_URL |
PreSchoolTransform |
PreSchool |
WordpressPaginator |
run/Project.stratsys.innovation |
STRATSYS_INNOVATION_PATH |
StratsysTransform |
Project |
WordpressPaginator |
The run/* scripts expect these variables unless noted otherwise:
TYPESENSE_HOSTTYPESENSE_PORTTYPESENSE_PROTOCOLTYPESENSE_API_KEY
WP_EVENTS_API_URLWP_LEGACY_EVENTS_API_URLAXIELL_EVENTS_URLTIX_EVENTS_API_URLWORDPRESS_EXHIBITION_EVENT_PATHREACHMEE_HELSINGBORG_PATHREACHMEE_INTRANAT_HELSINGBORG_PATHELEMENTARY_SCHOOL_API_URLPRE_SCHOOL_API_URLSTRATSYS_INNOVATION_PATH
The Stratsys pipeline also requires:
STRATSYS_INNOVATION_AUTHSTRATSYS_INNOVATION_CLIENTIDSTRATSYS_INNOVATION_CLIENTSECRET
Example:
export TYPESENSE_HOST=localhost
export TYPESENSE_PORT=8108
export TYPESENSE_PROTOCOL=http
export TYPESENSE_API_KEY=xyz
export WP_EVENTS_API_URL='https://example.test/wp-json/wp/v2/event?per_page=100'
php run/EventAnother example for Stratsys:
export STRATSYS_INNOVATION_PATH='https://example.test/export'
export STRATSYS_INNOVATION_AUTH='https://example.test/oauth/token'
export STRATSYS_INNOVATION_CLIENTID='client-id'
export STRATSYS_INNOVATION_CLIENTSECRET='client-secret'
php run/Project.stratsys.innovationComposer scripts defined in composer.json:
composer test
composer test-coverage
composer lint
composer lint-fix
composer phpstanTo add a new integration, the current codebase pattern is:
- Add a transform under
src/Transforms/. - Reuse or add a paginator under
src/Paginators/if the source API needs one. - Add a dedicated executable in
run/that wires the source URL, transform, logger, lock, and Typesense collection. - Add PHPUnit coverage for the transform and any mapper or sanitizer classes.
This project is licensed under the MIT License.