PNLEE StudioCatalogue integration service
ENGINEERING NOTES · 10 OCTOBER 2026 · SYNTHETIC DATA

Reviewing a CSV import before changing a catalogue

Download the runnable example (ZIP)

Python 3.10+ · standard library · includes the PriceLab CSV core and synthetic fixtures. Extract the archive, preserve its folders, and run the commands below from the extracted root. Product writes are limited to the local demonstration directory.

A catalogue import needs a reviewable answer to a practical question: what will this file change? I built a small local prototype that separates preview from application. It reads synthetic supplier CSV data, produces a JSON change plan, and updates a demonstration SQLite catalogue only after confirmation of that exact plan. The downloadable archive includes the unchanged adapter, its PriceLab core, and synthetic fixtures. Use Python 3.10 or later with SQLite for this CSV example; no additional packages are required.

The synthetic incoming file includes these rows:

sku;brand;name;price;stock
001;DEMO;Synthetic item one;12.50;6
002;DEMO;Synthetic item two;20.00;0
003;DEMO;Synthetic new item;5.00;2
BAD;DEMO;Invalid price item;-7.00;4
001;DEMO;Synthetic item one;12.50;6

The baseline contains four products. Preview proposes three changes: update the price and stock of DEMO/001, change DEMO/002 from seven units to zero, and insert DEMO/003. Each change contains its action, complete key, previous row, and proposed row. Invalid and duplicate input stays visible in the report. Nothing is written to the catalogue during preview.

Extract the archive into a new empty folder and preserve its directory layout: pricelab/core.py sits beside the artifacts directory, while the adapter stays under artifacts/catalog-executable-proof-20261010/. The code resolves its root from that location. Run the following original PowerShell sequence from the extraction root. Choose a fresh output directory: initialization refuses to replace an existing database.

python -B -X utf8 artifacts/catalog-executable-proof-20261010/import_proof.py init --config artifacts/catalog-executable-proof-20261010/fixtures/baseline.json --catalog artifacts/catalog-executable-proof-20261010/runs/manual-1/catalog.sqlite
python -B -X utf8 artifacts/catalog-executable-proof-20261010/import_proof.py plan --config artifacts/catalog-executable-proof-20261010/fixtures/incoming.json --catalog artifacts/catalog-executable-proof-20261010/runs/manual-1/catalog.sqlite --out artifacts/catalog-executable-proof-20261010/runs/manual-1/plan.json
Get-Content -LiteralPath artifacts/catalog-executable-proof-20261010/runs/manual-1/plan.json -Raw -Encoding UTF8

Read the complete JSON, including issues and paths. Replace the placeholder below with the plan_id from the reviewed plan:

python -B -X utf8 artifacts/catalog-executable-proof-20261010/import_proof.py apply --plan artifacts/catalog-executable-proof-20261010/runs/manual-1/plan.json --catalog artifacts/catalog-executable-proof-20261010/runs/manual-1/catalog.sqlite --confirm PLAN_ID_FROM_REVIEWED_JSON

The identifier is a SHA256 digest of the plan payload. That payload includes fingerprints of the CSV bytes, configuration bytes, shared core, absolute target path, and logical database state. The database fingerprint covers products, metadata, schema, and triggers. Application checks the confirmation, acquires a write transaction, takes another snapshot, and rebuilds the plan. If the source or target changed, or the submitted plan differs from the rebuilt one, application stops before product writes. Recalculating a modified plan's digest does not bypass that comparison. This digest is not a signature or a permissions system.

Zero stock needs deliberate handling. PriceLab's catalogue output filters out zero-stock offers, so the adapter uses validated offers instead. Otherwise an existing item could retain its old positive stock. The complete product key is (brand, sku, unit, currency). Leading zeros survive, and another brand's SKU 001 remains a separate product. An exact duplicate is reported without adding its stock twice. The negative-price row is excluded. Products missing from this particular feed remain unchanged; omission does not mean deletion.

All updates run inside one SQLite BEGIN IMMEDIATE transaction. In the existing local verification, a trigger installed before preview raises an error on the third write. The first two writes execute, then the exception causes a full rollback. The recorded checks also cover wrong confirmation, changed source, changed target, altered payload, target-path substitution, and a fresh preview after successful import that contains zero changes. These thirteen synthetic checks establish the demonstrated behaviours, not comprehensive production readiness.

The example assumes one supplier and an agreed currency, unit, and price policy. It has no external API, PrestaShop integration, scheduler, image or variant handling. Permissions, operational deployment, and a real supplier's complete mapping would need separate design. No customer data or database is included in the archive. This is demonstration code; no production integration or licence for redistribution is offered.

For related ecommerce work, our E-MIR case describes frontend, administration, and import work: https://studio.pnlee.su/en/cases/emir/. That case is separate from this local SQLite prototype and does not establish a connector demonstrated here.

Author: PNLEE Studio. Our catalogue integration page explains the service context: https://studio.pnlee.su/en/services/catalog-integration/. A paid integration would need a confirmed requirement and agreed scope before a quote.