byrcsc/laravel-data-sync · 1.x
Run history and status.
Read recent runs with sync:status, interpret the counters and statuses, watch queued batch progress, and query the history models directly.
php artisan sync:status # the last 10 runs
php artisan sync:status products # one definition
php artisan sync:status products --limit=25
php artisan sync:status --failures # one line per failed rowRuns are listed newest first, across all definitions unless you name one.
Run Sync Status · path C/U/S/F Progress
01JQ8Z3M0K2N4P6R8T0V2X4Y6A products completed · bulk 980/20/0/0 1000 rows
01JQ8Z2A9F1M3P5R7T9V1X3Y5B products running · bulk 420/0/0/0 42% (84/200 jobs)
01JQ8Z1K7D0L2N4Q6S8U0W2Y4C products completed · bulk (dry run) 0/0/0/0 12 rows| Column | What it shows |
|---|---|
| Run | The run ULID — what sync:retry takes |
| Sync | The definition name |
| Status · path | The run status, a dry-run marker, and the write path |
| C/U/S/F | Rows created, updated, skipped, failed |
| Progress | Queued batch progress when a batch exists, otherwise the row total |
The write path reads bulk, eloquent, or transfer. It is stored on the run
at creation, so which path a run took is recorded rather than inferred. See the
write path tradeoff.
Statuses
| Status | Meaning |
|---|---|
pending | Recorded, waiting on a worker |
running | In progress |
completed | Every row written |
completed_with_errors | Finished; some rows failed and were recorded |
failed | The run did not finish |
cancelled | The queued batch was cancelled |
completed_with_errors is a success for the file and a problem for some of
its rows: the checksum is marked processed, the file is archived, and the failed
rows sit in sync_row_failures waiting for you. failed is the opposite —
nothing is marked processed and the file is preserved for retry.
Counters
- Created and updated are decided per row against the destination table.
- Skipped covers rows the write mode declined (
CreateOnlyon an existing row,UpdateOnlyon a new one), rows that lost a duplicate resolution, and rows abeforeSave()hook returnedfalsefor. - Failed covers rows that could not be mapped and rows that failed validation.
For a transfer, one file is one row: 1 created for a
transferred file, 1 skipped when the destination already held it or the
filename did not match.
Batch progress
While a queued run is in flight, sync:status reads its batch record and
reports real progress — 42% (84/200 jobs) — instead of a row count. Once the
batch record is pruned by the framework, the row total is shown instead.
A run stuck at running with no batch progress usually means a dead worker.
sync:doctor warns about runs that have been running for more than an hour.
Failed rows
php artisan sync:status products --failures01JQ8Z3M0K2N4P6R8T0V2X4Y6A row 412: {"price_cents":["The price cents must be an integer."]} {"SKU":"DS-1041","Price":"n\/a"}
01JQ8Z3M0K2N4P6R8T0V2X4Y6A row 907: {"row":["Undefined array key \"Currency\""]} [payload capture disabled]Each line carries the run ULID, the row number as the reader counts it, the
validation errors keyed by attribute, and the captured raw payload. Rows whose
payload capture was off show [payload capture disabled] — see sensitive
data.
The run itself also carries a summary: error_summary holds a JSON histogram of
field: message counts, which answers "what went wrong with this file" without
reading 900 individual rows.
Warnings
sync_runs.warnings records non-fatal problems — most often a source cleanup
that failed after a successful import, such as a read-only supplier directory.
The run still completed and the data is still imported. Query the column when a
supplier reports files reappearing:
SyncRun::query()->whereNotNull('warnings')->latest('id')->get();Querying the history
use ByRcsc\LaravelDataSync\Models\SyncRun;
$run = SyncRun::query()->where('ulid', $ulid)->firstOrFail();
$run->status; // RunStatus enum
$run->write_path; // WritePath enum, or null for a transfer
$run->dry_run; // bool
$run->rows_created;
$run->unmapped_columns; // columns in the file no field mapped
$run->error_summary;
$run->archive_path;
$run->file; // the SyncFile ledger row
$run->failures; // SyncRowFailure records
SyncRun::query()
->where('definition', 'products')
->whereIn('status', ['failed', 'completed_with_errors'])
->whereDate('created_at', today())
->get();Both models read their table names from data-sync.tables, so custom names work
without subclassing. They are plain Eloquent models: build a dashboard, expose
them through an admin panel, or ship a daily digest from them.
Remember that runs are pruned on a retention schedule while the ledger is not — see retention and pruning before building reporting that assumes runs live forever.
What to read next
- Events and listeners for reacting to a run as it finishes.
- Failures and retries for acting on what you find here.
- File identity and runs for what each record means.