Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

It looks like the issue isn’t with Horizon itself, but with how SQL Server connections behave when child processes are spawned.

SQLSTATE[08S01] generally means the SQL Server connection is being dropped or is no longer valid by the time the job runs. This commonly happens when:

A database connection is opened before the worker forks

The new child process tries to reuse the same connection

SQL Server rejects it, causing 08S01 TCP errors

Why it happens

When Horizon auto-scales, it spawns new worker processes. If a database connection was already opened in the parent process (e.g., during bootstrap), the child processes inherit an invalid handle. As soon as they run a query, SQL Server throws the TCP Provider 0x2714 error.

Fixes Force Laravel to refresh DB connections per job

In your job, before running queries:

DB::purge('sqlsrv'); DB::reconnect('sqlsrv');

Disable persistent connections

In config/database.php, for the sqlsrv connection:

'persistent' => false,

Make sure no connection is made before forking

Any code that runs during boot and touches the DB should be avoided or delayed.

Restart workers after config change php artisan horizon:terminate

Why it only happens when new processes start

Parent worker is alive and its DB connection is valid

New workers inherit a connection that SQL Server considers invalid

First query in those workers immediately fails

Once workers reconnect, they continue working normally.

Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

Yes — you can definitely order records in Filament using your custom order field. You have two good options depending on how interactive you want the sorting to be:

Option 1: Simple ordering (no drag-and-drop)

Just tell Filament to sort the table using your order column:

public static function getEloquentQuery(): Builder { return parent::getEloquentQuery()->orderBy('order'); }

This will always display records in the order you set.

You can also add up/down buttons inside the table:

Tables\Actions\Action::make('move_up') ->action(fn ($record) => $record->decrement('order')),

Tables\Actions\Action::make('move_down') ->action(fn ($record) => $record->increment('order')),

Option 2: Drag & Drop Sorting (recommended)

Filament supports drag-and-drop ordering using the Spatie Eloquent Sortable package.

  1. Install the package: composer require spatie/eloquent-sortable

  2. Add this to your model: use Spatie\EloquentSortable\Sortable; use Spatie\EloquentSortable\SortableTrait;

class YourModel extends Model implements Sortable { use SortableTrait;

public $sortable = [
    'order_column_name' => 'order',
    'sort_when_creating' => true,
];

}

  1. Enable reordering in your Filament Resource: public static function canReorder(): bool { return true; }

Now you’ll see a drag-handle in your table and can reorder records with the mouse. Filament will automatically update your order column.

Summary

Yes, ordering is possible You can use arrows, automatic sorting, or drag-and-drop Drag-and-drop is built-in when using Spatie’s sortable package

If you want, I can show you the full working code for your specific resource.

Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

A 419 CSRF Token Mismatch usually means Laravel isn’t receiving the session or the CSRF cookie it expects — even if the route itself isn’t protected.

A few things you can check:

  1. Are you hitting the correct domain/subdomain? Laravel ties CSRF + session cookies to the domain. If your API is on a different domain/port than your frontend, the cookie might not be sent.

  2. If you’re using Axios, make sure withCredentials is enabled:

axios.defaults.withCredentials = true;

  1. Check sanctum.php → stateful domains Even if you’re not using Sanctum, these settings can still affect how cookies are handled.

  2. Verify your session driver If you're using file or database, make sure permissions and storage paths are correct.

  3. If this is an API route, consider adding:

Route::post('/your-route', [YourController::class, 'method'])->withoutMiddleware(['VerifyCsrfToken']);

(But only if it’s truly an API endpoint that doesn’t need session-based CSRF.)

  1. Clear your cookies + Laravel caches:

php artisan config:clear php artisan cache:clear php artisan route:clear php artisan view:clear

Often the issue comes from cross-domain requests where the CSRF cookie never gets sent back.

If you share your frontend domain + backend domain setup, I can help pinpoint it more.

Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

Inertia isn’t ideal for high-frequency updates. It’s better for user-driven actions, not data that refreshes every few hundred milliseconds. For fast updates, API polling (Axios) or WebSockets performs much better, since constant Inertia re-renders add unnecessary overhead. Same idea I follow when building real-time systems for services — even outside tech, like how bail bonds Tampa services at https://www.aftermathbailbonds.com/ rely on fast, reliable updates. For your PBBG, stick with API requests or a real-time setup instead of pushing Inertia past its limits.

Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

Hi — good catch, and thanks for reporting this.

A 403 is technically correct from the server side, but from a UX point of view it’s confusing if the user only finds out after trying to submit. A couple of small improvements would make this much clearer:

What I’d suggest

Show a paid / Pro badge on the submit button (or on the exam page) so users know the feature is gated before they try it.

If they click the button and aren’t entitled, show a modal explaining: why it’s restricted, how to upgrade, and a link to a free trial or support.

Instead of surfacing a raw 403, return a structured error (e.g. 403 { code: "feature_locked", message: "This feature requires a Pro subscription" }) so the client can show a friendly message and CTAs.

Add a tooltip on hover and a short note on the exam page describing which actions are paid features.

Log these 403 hits so product/support can see how many users are blocked and whether messaging needs to change.

Suggested modal text

Feature locked — Pro required Submitting exam answers is a Pro feature. Upgrade to Pro to unlock submissions, progress tracking, and detailed feedback. [Upgrade] [Contact support]

Thanks again for flagging it — small changes like this save a lot of user confusion.

Eimmaarose's avatar

Eimmaarose wrote a reply+100 XP

5mos ago

Hi ainahid,

You can create a Filament resource inside a subfolder by simply specifying the full path when running the Artisan command. For example, if you want to put your resource under a Blog folder:

php artisan make:filament-resource Blog/Post

This will create a PostResource inside:

app/Filament/Resources/Blog/PostResource.php

Filament automatically handles subfolders, so you can also create related resources like:

php artisan make:filament-resource Blog/Author php artisan make:filament-resource Blog/Comment

They’ll all be grouped neatly under app/Filament/Resources/Blog/.

If you want them to appear in a specific navigation group within the panel, you can also set the $navigationGroup property inside each resource, for example:

protected static ?string $navigationGroup = 'Blog';

That way, all your Blog resources will appear together in the sidebar.

Hope that helps!

— Eimmaa Rose