Skip to content

Case Study — IngoShift as a client-style engagement

Author: Velat Isik. This case study describes the system as built. Wherever the demo uses constructed data, it says so — the deliverable being sold here is the pipeline discipline, not the demo numbers.

1. Client-style problem

A regional actor (economic-development office, SME network, or training provider) needs a continuously updatable picture of the Ingolstadt economy: which skills are demanded, which companies are shifting from combustion-era automotive toward software/batteries/AI, which tenders and research projects matter. Today that picture lives in one-off spreadsheets that die the week they are presented.

2. Constraints

Only legally reusable public sources; no scraping against terms; no person-level data; small-team maintainability; results must survive audit — every number challengeable back to its source; budget favors few working workflows over many half-built ones.

3. Data sources

Fifteen candidate sources were catalogued with verification evidence and license notes. The official TED Search API is implemented and was executed successfully on 2026-07-29; the anonymous response was archived, parsed, and quality-gated. CORDIS bulk data and GENESIS downloads are documented but their collectors currently run on fixtures. DÖE procurement, the Bavarian GENESIS API, Wikidata, and THI still require local re-verification. Because no posting-level jobs source is legally cleared, that pipeline is proven on visibly synthetic data (ADR-008), not hidden behind a realistic-looking demo.

4. Architecture

Raw (immutable, content-addressed) → bronze (validated, lineage mandatory) → silver (normalize/enrich/dedup, drops counted) → quality gate (blocks publication) → gold marts → CLI/exports/report; entity resolution and change detection for the historized company model. See docs/architecture.md.

5. Quality risks and how they are handled

Wrong entity merges (no fuzzy auto-merge; audit log; review queue), suppressed statistical cells (markers retained; completeness-flagged totals), extraction over-claiming (dictionary layer, observed-vs-inferred labels, coverage warning), demo data mistaken for real (data_class on every row into every mart, export, and report), silent coverage loss (drop counts printed and rule-checked).

6. Implementation

Six phases were built with dated ADR amendments for every deviation: 206 tests, strict mypy, a poisoned-fixture test for the blocking quality gate, an automated mart→raw-bytes lineage walk, a byte-reproducible weekly report, a verified official live collector, and a static portfolio dashboard.

7. Analysis

reports/analysis-report.md demonstrates the analysis style: every claim carries its lineage path and data-class label; correlation is never dressed as causality; alternative explanations are listed before recommendations.

8. Decisions enabled

Which skills to teach/hire for (module 1), which companies changed and which merges to trust (module 2), which tenders and research consortia to pursue (module 3) — each traceable, each refreshable by rerunning one command.

9. Limitations

The limitations document is part of the product. TED is live but covers only above-threshold procurement; jobs and companies remain synthetic, other collectors remain fixture-based, history starts with collection, dictionary extraction is limited, and the dashboard is static rather than API-backed.

10. Adapting this for a paying client

Region and themes are configuration (config/regions/, config/taxonomies/); sources are adapters behind a registry with per-source governance notes. A client engagement replaces fixtures with their sources (or the verified public ones), keeps the gate/lineage/reporting spine unchanged, and inherits the audit trail. Packages and pilot structure: docs/portfolio/upwork.md.