Bulk import/export¶
The optional FlyokaiFujinShuttleMarketplace plugin
(flyokai/sw-fujin-shuttle-marketplace) puts the Flyokai Fujin Shuttle bulk
CSV engine into the seller portal — so sellers can import and export products,
variants, inventory and offers in bulk, scoped to their own catalogue.
Requirements¶
composer require flyokai/sw-fujin-shuttle-marketplace
php bin/console plugin:refresh
php bin/console plugin:install --activate FlyokaiFujinShuttleMarketplace
Requires Base (flyokai/sw-marketplace) and the Fujin Shuttle engine
(flyokai/sw-fujin-shuttle). It adds no tables of its own — it reuses Base's
schema, portal auth and ownership model, and Fujin Shuttle's import pipeline.
Profiles¶
Four seller-scoped CSV profiles:
| Profile | Imports / exports | Notes |
|---|---|---|
product |
Seller's products | Create / update; new products are stamped with the seller's ownership. |
product_variants |
Variant children | For configurable products. |
inventory |
Stock levels | Per product/variant. |
seller_offer |
The seller's offers | Price, stock, status — the marketplace-specific profile. |
The first three wrap Fujin Shuttle's standard product profiles; seller_offer
is added by this plugin (request/handler, data depot, import deputy and template
contributor) to round-trip flyokai_seller_offer data.
Ownership enforcement¶
Every imported row passes through a MarketplaceOwnershipGuard that pins the
run to the calling seller:
- A seller may only modify products they own (
product.flyokai_product_owner_id= their seller id). Rows touching other sellers' or operator-owned products are rejected. - New products created by an import are stamped with the seller's ownership.
- For seller-owned products, the guard can auto-seed a
pending_approvalseller offer, so importing a catalogue and listing it is one step. - Category auto-creation is disabled for seller imports
(
auto_create_categories=false) — sellers slot into the operator's category tree, they don't extend it.
This is the same ownership rule the portal
enforces interactively, applied per CSV row. New products still respect
autoApproveProducts; new offers respect autoApproveOffers.
The bulk REST surface¶
Under the portal's JWT auth, at /flyok-portal/bulk/*:
| Method | Path | Purpose |
|---|---|---|
POST |
/flyok-portal/bulk/upload |
Upload a CSV → { file, columns, rows } preview. |
POST |
/flyok-portal/bulk/upload-chunk |
Chunked-upload continuation for large files. |
POST |
/flyok-portal/bulk/run |
Run an import — { dataType, file, dryRun }. |
GET |
/flyok-portal/bulk/export?type=… |
Download an export CSV (product / product_variants / inventory / seller_offer). |
GET |
/flyok-portal/bulk/template?type=… |
Header-only import template. |
GET |
/flyok-portal/bulk/example?type=… |
Header + sample rows. |
Typical flow¶
1. GET /flyok-portal/bulk/template?type=seller_offer → download headers
2. POST /flyok-portal/bulk/upload (multipart CSV) → preview columns/rows
3. POST /flyok-portal/bulk/run { dryRun: true } → validate, no writes
4. POST /flyok-portal/bulk/run { dryRun: false } → import for real
Always dry-run first — it surfaces ownership rejections and validation errors without touching the catalogue.
Where the work runs¶
The bulk controller calls Base's MarketplaceBackend
and the Fujin Shuttle pipeline. On Base that's in-process; large imports will tie
up a PHP-FPM worker for the run. If bulk imports are heavy and frequent, that's
another reason to consider Remote.