Skip to content

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_approval seller 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.