Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Flowguard Laravel Package

mykholy/laravel-flowguard

Laravel FlowGuard adds configurable flow-control guards to your Laravel application, letting you define rules that inspect and constrain requests before they reach your handlers. Lightweight, easy to install, and simple to tune for your app's needs.

View on GitHub
Deep Wiki
Context7

Getting Started

FlowGuard bundles four reliability primitives for Laravel: idempotent operations, a webhook inbox, a transactional outbox, and reconciliation tooling. The 1.0.2 release is documentation and Composer-metadata only — runtime code, API signatures, dependencies and schema are unchanged, so upgrading from 1.0.x is a composer update with no data migration, no reinstall and no fingerprint rewrite.

Minimal path:

composer require mykholy/laravel-flowguard:^1.0
php artisan migrate
php artisan flowguard:doctor

Where to look first, in order:

  1. README — since 1.0.2 it carries status badges, a supported-versions table and documentation navigation. Read the "practical failure scenarios" section before writing code; it frames what each primitive is actually for.
  2. php artisan flowguard:doctor — run this immediately after install and again in your deploy hook. It's the fastest way to confirm migrations landed, the configured connection/tables resolve, and required config is present before you blame your own code.
  3. config/flowguard.php — publish it and read it end to end. Table names, connection, retry/timeout knobs and retention live here; several "gotchas" below are config-shaped.
  4. Migrations — the operation, inbox, outbox and reconciliation tables define the identities you'll key everything off. Read the columns before designing your keys.

First use case: wrap a single non-idempotent side effect (capture a payment, call a provider's create-order endpoint) in an idempotent operation keyed by a client-supplied key, then add a webhook handler that persists verified payloads into the inbox before queueing processing. That covers the two primitives that cause the most production incidents and validates your install end to end.

Implementation Patterns

Idempotent operations around outbound calls. Derive the key from something stable and scoped — typically Idempotency-Key header + authenticated tenant + route — and resolve it on the server. The 1.0.2 docs specifically call out server-derived merchant context: never trust a client-supplied tenant/merchant id in the key, or a caller can collide keys across tenants. Store the operation record and its outcome, and on replay return the stored result rather than re-executing. Handle the in-flight case explicitly (a second request arriving while the first is mid-call should get a conflict/retry signal, not a second side effect).

Inbox = verify first, persist raw, then process. Webhook signature verification is explicitly host-owned. So the order is: verify the signature → hand the raw payload plus the provider's event id to the inbox (dedupe on that provider id) → process asynchronously via a queued job → mark processed only on success. Persist the raw body: you'll want it for audit, for replay after a bug fix, and for reconciliation evidence.

Outbox = write in the same transaction as the domain change. Insert the domain row and the outbox row inside one DB::transaction, then let a relay/worker publish downstream afterwards. Never call the external system inside the request transaction — that's the failure mode the outbox exists to remove. Because delivery is at least once, every downstream consumer needs its own dedupe on your message identity.

Reconciliation as a scheduled job, not an incident response. Compare internal state against the provider (or against inbox/outbox records) on a schedule in routes/console.php, and let it repair drift — missed webhooks, outbox rows that never got acknowledged, operations stuck in-flight. Treat its output as a health metric; a growing reconciliation backlog is your earliest signal that the relay or webhook path is degraded.

Fault tolerance config over bespoke retries. Set timeouts and retry policy in config and let the package own the retry semantics; adding a second retry loop in your job or HTTP client multiplies attempts and breaks the idempotency assumptions underneath.

Testing. Use RefreshDatabase, fake the provider's HTTP layer, and assert that two calls with the same key produce exactly one provider request and identical responses. Add a test that replays a webhook payload twice and asserts one processed inbox row.

Gotchas and Tips

  • At-least-once is the contract. Inbox processing, outbox relay and downstream consumers all need to be idempotent independently. There is no exactly-once to be had; design for duplicate delivery instead of trying to prevent it.
  • Populated rollback is rejected. The package refuses to roll back a populated database, and 1.0.2 preserves all existing operation, inbox, outbox and reconciliation identities. Treat migrations as forward-only in any environment with data; don't plan on migrate:rollback as a deploy safety net.
  • The host owns the sharp edges. Tenant authentication, verified webhook acceptance, provider-side idempotency keys, timeouts, approvals, downstream deduplication and retention are all explicitly out of scope. FlowGuard gives you the scaffolding, not the policy. If a webhook is accepted unverified, FlowGuard will faithfully persist and process a forged event.
  • Key scope and key growth. Include tenant + endpoint in every idempotency key, and remember retention/pruning of operation and inbox rows is your job. Unbounded tables are the most common way this pattern quietly degrades.
  • The outbox needs a running worker. A deployed relay that isn't scheduled looks identical to a working one until the backlog is hours deep. Alert on outbox age, not just on failures.
  • Server-derived merchant context (newly documented in 1.0.2) is the correct default for multi-tenant apps — derive it from the authenticated session or from the verified webhook's own credentials, never from the request body.
  • flowguard:doctor belongs in CI and in the deploy hook. It catches config/connection drift after environment changes faster than a failed request will.
  • Extension points — configurable connection/table names, key resolution, relay and reconciliation jobs, lifecycle events — are the intended way to adapt behaviour. The library contract and integration boundaries are declared stable across 1.x, so prefer config and events over subclassing internals.
  • 1.0.2 changes nothing at runtime. No data migration, no fingerprint rewrite, existing tags and artifacts unchanged. If you pin by archive, verify the published checksum; if you install from Packagist, a normal composer update is sufficient.
  • Maturity caveat. The release notes state that independent human security review, adopter review and representative production acceptance remain open. Treat this as a library you evaluate against your own failure scenarios rather than one with third-party assurance — run the doctor, read the failure-scenario docs, and exercise the duplicate-delivery paths in staging before trusting it with money movement.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager