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

Nova Workflow Laravel Package

cammac/nova-workflow

A Laravel Nova package that adds workflow management to your resources: define states, transitions, and approvals, then move models through each stage directly from the Nova UI.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to understand is that cammac/nova-workflow is a Nova resource tool, not a full state-machine library or a BPMN engine. It hangs off a Nova resource and gives editors a UI to move records through defined stages. Treat it as a presentation layer over your own domain logic, not a replacement for it.

Minimal setup:

composer require cammac/nova-workflow
php artisan vendor:publish --provider="Cammac\NovaWorkflow\ToolServiceProvider"
php artisan migrate

Then register the tool in app/Nova/NovaServiceProvider.php (or attach it to a single resource if the package supports per-resource registration — check the README first, this is the most common source of confusion):

use Cammac\NovaWorkflow\NovaWorkflow;

public function tools()
{
    return [
        new NovaWorkflow,
    ];
}

Where to look first, in order:

  1. README.md — this package is small (35 stars, low dependents), so the README is the documentation. There is no docs site.
  2. config/nova-workflow.php after publishing — it tells you which model columns and workflow definitions are expected.
  3. The migrations in database/migrations — these reveal the data model (stage table, pivot, or a status-style column).
  4. src/ on GitHub — with this dependency count, you will likely read source to answer non-trivial questions.

First realistic use case: an Order model with stages draft → pending → approved → shipped. Attach the tool to Order in Nova, define the transitions in your model or config, and let ops staff advance orders from the Nova detail view instead of asking engineers to run tinker.

Implementation Patterns

Keep transitions in the domain, not the UI. The single most maintainable pattern is to define stage semantics on the model and let the Nova tool only invoke them:

class Order extends Model
{
    protected $casts = ['stage' => OrderStage::class];

    public function canTransitionTo(OrderStage $to): bool
    {
        return $this->getStateMachine()->allows($this->stage, $to);
    }
}

If the package expects a config-driven definition, mirror it there and treat the config as the source of truth that both Nova and your app code read.

Pair with Nova Actions for anything with side effects. Workflow tools are notoriously bad at transactional side effects (emails, invoices, inventory). Prefer:

  • Tool = visual stage display + simple stage field updates.
  • Nova Action = "Approve order" with handle(), DB transaction, event dispatch.

This keeps the audit trail and rollback behaviour under your control.

Authorization via policies. Whatever stage-transition method you expose, gate it:

public function approve(User $user, Order $order): bool
{
    return $user->can('manage-orders')
        && $order->stage === OrderStage::Pending;
}

Then wire Nova's canSee/authorizedToUpdate on the tool or hide stages the user cannot reach. Never rely on the UI alone — the tool is a JSON endpoint under the hood.

Events for integration. Fire a domain event on transition and listen for it:

event(new OrderStageChanged($order, $old, $new));

This decouples notifications, ERP sync, and analytics from the Nova tool, and means a package upgrade can't silently break downstream systems.

Seed/test pattern. Write a feature test that hits the transition endpoint:

$this->actingAs($admin)
    ->putJson("/nova-api/orders/{$order->id}/stage", ['stage' => 'approved'])
    ->assertOk();

$this->assertEquals(OrderStage::Approved, $order->fresh()->stage);

With 0 dependents, you are effectively the QA department — have your own regression test around the transition path before a Nova upgrade.

Gotchas and Tips

  • Nova version compatibility is the biggest risk. Low-star, low-maintenance Nova tools frequently break on Nova 4 → 5 upgrades (tool boot signature, Nova::script changes, resource fields() API). Pin the package version in composer.json and test the upgrade path on a branch before touching a production Nova build.

  • Check maintenance before adoption. 35 stars and 0 dependents means no community buffer. Look at the last commit date and open issues on GitHub. If it's stale, plan for a fork under your own namespace — MIT license makes this painless, and you'll likely need to patch it yourself anyway.

  • Don't let the tool own your state column if you have existing status logic. If your app already has a status enum, adding a second stage/workflow column leads to two sources of truth. Either map the workflow onto the existing column or plan a migration consciously.

  • Morph map issues are common. If the tool stores polymorphic references to workflow-owning models, Relation::morphMap() mismatches produce silently empty tool panels. Verify stored model_type values match your map keys, not FQCNs.

  • Nova authorization defaults to true in dev but bites in prod. Nova's Gate::before super-admin bypass and resource policies will interact with the tool's own checks. Test as a non-super-admin user early, not just as admin@local.

  • Debugging: Nova swallows errors from tool endpoints into generic 500s. Reach for storage/logs/laravel.log and php artisan nova:log if available; if the transition endpoint fails silently, dd() inside the package's controller in vendor/ (temporarily) to see the actual request shape.

  • Queue/transaction boundaries. If a transition triggers jobs, dispatch after commit: use DB::afterCommit() or an ShouldDispatchAfterCommit job. Workflow UIs invite rapid clicking; double-fire is real. Add idempotency guards on the transition method.

  • Config caching gotcha. After editing config/nova-workflow.php, run php artisan config:clear — in a Docker build with config:cache baked in, config edits appear to do nothing.

  • Extension points: with a package this small, expect to extend by forking or by wrapping the tool in your own subclass rather than through documented hooks. If you need custom stage rendering, override the resource field rather than fighting the tool's Vue component.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings