code-rhapsodie/dataflow-bundle
Symfony bundle for building import/export dataflows with one reader, any number of sync or async processing steps, and one or more writers. Schedule and run jobs, manage dataflows from the command line, and work with multiple Doctrine DBAL connections.
Architecture fit — poor for a Laravel codebase. Despite being distributed as a Composer package, this is a Symfony bundle, not a framework-agnostic library. Everything load-bearing is Symfony-specific: registration via config/bundles.php, service discovery through the coderhapsodie.dataflow.type DI tag with autoconfiguration, configuration under the code_rhapsodie_dataflow config tree, and CLI entry points under bin/console. Laravel has no bundle kernel, no compiler passes, and no tagged-service autoconfiguration, so there is no supported path to "install and use."
Integration feasibility — low; this is a port, not an integration. A few constituent ideas are portable in isolation (PSR-3 logging, Flysystem for the exceptions sink, Symfony Console for commands, OptionsResolver as a standalone component, Doctrine DBAL as a second connection), but the bundle's value is the orchestration layer that ties them together through Symfony's container. Attempting to install it in a Laravel app will pull the Symfony framework stack (framework-bundle, http-kernel, routing, dependency-injection) alongside Laravel's own kernel and HTTP layer — expected Composer conflicts and two competing service containers. Budget for a clean-room reimplementation using Laravel primitives (Pipeline/queued jobs, artisan commands, Schedule, Storage), not for integration work.
Technical risk — high. Signals are weak across the board: 18 stars, 0 dependents, single-vendor stewardship, README-and-releases-only maturity, and a composite score of ~28/100 (opportunity ~25). The version matrix is fragile — the 5.x line requires Symfony ^7.3 while 4.x covers 3.4–6.x, meaning upgrade paths are branch-switching exercises. The release metadata lists a 2026-10-02 date that postdates this assessment; recency signals should be re-verified directly against Packagist before any decision. Schema ownership is manual (dump-schema producing SQL you paste into your own migration tool), which shifts migration discipline onto the adopting team. Asynchronous steps depend on Amp generators and scale factors, a niche concurrency model with a thin operational story.
Key questions
league/flysystem + a Messenger transport already in our stack, or are these net-new dependencies?Stack fit — mismatch at the root. The bundle assumes Symfony's kernel, container, and console. Laravel equivalents are mature and already paid for: Illuminate\Pipeline or chained jobs for steps, Bus/Queue + Horizon for concurrency and retries, Schedule for cron, Storage (which already wraps Flysystem 3) for exception dumps, and Eloquent/Query Builder instead of DBAL-managed cr_dataflow_job / cr_dataflow_scheduled tables. Every capability listed in the README has a first-party Laravel analogue with better observability.
Migration path — three options, ranked.
Pipeline, dispatches writes as queued jobs, and records run state in a local dataflow_runs table. Roughly 3–5 engineer-days for the skeleton plus per-flow work; fully idiomatic and supportable.symfony/console, http-kernel, and routing ranges, and an unsupportable dual-kernel runtime.Compatibility. Check PHP and Symfony constraint ranges against the Laravel version in use; Laravel 10/11 already pins symfony/console and symfony/process, which is exactly where the bundle will fight. PSR-3 logging and Flysystem adapters are the only frictionless touchpoints.
Sequencing. (a) 2–3 day spike: confirm Composer resolution in a throwaway Laravel app — if it fails, the decision is made and cheap. (b) In parallel, prototype the internal equivalent on one real import with the highest volume. (c) If the Symfony side-by-side option is chosen, stand up the worker service behind a feature flag and shadow-run one flow against production data before cutover. (d) Retire the spike branch either way.
Maintenance. Single-vendor, low-activity project with no visible contributor depth and zero dependents — no downstream ecosystem is absorbing breakage for us. MIT gives us the right to fork, but forking means owning a Symfony bundle we do not otherwise want. Dependency surface (Symfony framework stack, DBAL, optional Messenger + Flysystem + Amp) is wide relative to the value delivered.
Support. No vendor SLA, no issue-tracker signal in the provided sources, no community answers to lean on. The README is genuinely good — it documents the reader/step/writer contract, Messenger mode, and exceptions mode clearly — but documentation is not support. Internal ramp-up cost falls entirely on us.
Scaling. The pipeline is linear by design: exactly one reader, N steps, M writers, processed row-by-row. That is memory-friendly for large imports and a poor fit for parallel extraction. Concurrency comes from Amp scale factors on individual steps (with a documented caveat that write ordering is only preserved when all steps are scaled at 1) or from Messenger mode dispatching whole jobs to workers. Scheduling is not self-driving: run-pending must be invoked from cron or a scheduler, and the loopInterval/emitInterval tick settings need tuning to avoid a busy loop.
Failure modes to plan for.
run-pending invocations or duplicate queue deliveries could run the same scheduled dataflow twice — a real duplicate-import hazard with no idempotency contract in the README. Design writers to be idempotent regardless.prepare() / write() / finish() gives no rollback; a mid-stream exception leaves a half-written file or partial inserts.JobMessage to a transport means jobs are enqueued and silently never consumed. Add a heartbeat/age alert on pending jobs.composer update.Ramp-up. Engineers must absorb Symfony bundle conventions, DI tagging, PortPHP-style reader/writer adapters, and Amp generator semantics before shipping a first flow — knowledge with near-zero transfer value on a Laravel team. Estimate 1–2 weeks to first production flow versus 2–3 days for the internal reimplementation.
Verdict. Reject for a Laravel stack; the package is architecturally incompatible and the project's health signals do not justify the porting risk. Borrow the design — single reader, ordered step chain, one-or-more writers, persisted run records, queue-backed concurrency — and build it on Laravel primitives. Revisit only if the estate is predominantly Symfony and a dedicated owner is prepared to fork.
How can I help you explore Laravel packages today?