Aureus ERP

How Aureus ERP Handles Custom Fields: Beyond Filament’s Static Schemas

custom-field-hero

Aureus ERP is a modular ERP built on Laravel and Filament. Every business tracks slightly different data, so a fixed set of fields is never enough.

A distributor wants a “GST Number” on products. A studio wants a “Billable” toggle on tasks. This post shows how Aureus lets users add those fields themselves, with no developer and no migration.

Key takeaways

The problem: a fixed schema cannot fit every business

In Filament, a form is defined in code. A developer lists each field in a resource’s form() method.

That is fine until a customer needs a field you did not ship. In an ERP this happens constantly, across products, orders, and contacts.

The old answer was “raise a ticket, we will add a migration and deploy”. That is slow, and it does not scale to hundreds of customers who each want something different.

So the goal was clear. Let a user define a new field from the admin panel, and have it behave like any built-in field everywhere.

Why not a JSON column or EAV table?

The common shortcut is to dump custom values into one JSON column, or into an EAV (entity-attribute-value) table.

Both work, but both hurt later. Filtering, sorting, and reporting on a JSON blob or an EAV join is slow and awkward.

Aureus took the opinionated route: create a real, typed column for each custom field. You keep native indexing, filtering, and sorting, at the cost of running schema changes at runtime.

How it works: three layers

The design has three parts: a definition, a real column, and the code that makes Eloquent and Filament aware of it.

Layer 1: the field definition

When a user creates a field, a row is saved in the custom_fields table. The Field model describes it:

The important column is customizable_type. It says exactly which model this field belongs to.

Layer 2: creating the real column at runtime

This is the part most people do not expect. A FieldsColumnManager runs a live schema change when a field is saved:

It also chooses the correct column type from the field’s type:

Every custom column is created as nullable(). There are matching updateColumn() and deleteColumn() methods, so deleting a field drops its column.

This runs automatically when the field is saved. The Fields admin page calls the manager in its lifecycle hooks:

The result: create a “GST Number” field on Products, and a real gst_number column appears on the products table, at runtime.

Layer 3: teaching Eloquent and Filament about the field

A new column is useless if Eloquent does not know about it. A model trait, HasCustomFields, hooks the model lifecycle:

The casts are type-aware, so a multi-select becomes an array, a toggle becomes a boolean, and so on.

On the UI side, four Filament components carry the field through the whole panel: a form field, a table column, an infolist entry, and a filter. A resource merges them into its own schema using a companion trait.

Putting it together: a real example

Here is exactly how the Projects module wires this up. It takes two small changes.

1. Add the model trait to make the Project model custom-field aware:

2. Add the Filament trait to the resource, then merge custom fields into the form, table, and infolist:

That is all. Every merge helper accepts include() and exclude() arrays, so you can choose which custom fields appear where.

From now on, any field a user defines for Projects shows up automatically in the form, table, and infolist, with no further code.

You don’t have to build this from scratch. The same implementation is packaged as the Aureus ERP Custom Fields plugin for Filament.

The full flow

Challenges and how they are handled

Benefits

Frequently asked questions

Does Filament support custom fields out of the box?

No. Filament schemas are defined in PHP by developers. There is no built-in way for an end user to add a field at runtime.

Aureus adds this with a field definition, a runtime column, and components that render it.

Are custom field values stored in JSON or in real columns?

Real columns. Each custom field gets its own typed, nullable column on the model’s table.

This keeps filtering, sorting, and reporting fast and native.

Can I add a custom field to any model?

Any model that uses the HasCustomFields trait. The field targets that model through its customizable_type.

Final thoughts

Filament’s static schemas are the right default for developers, but an ERP has to bend to each customer’s data.

Aureus closed that gap by treating a custom field as a first-class column: defined by the user, created at runtime, understood by Eloquent, and rendered by Filament. The trade is a live schema change for a field that behaves exactly like any other, everywhere it appears.

Want to see how Aureus ERP can adapt to your data? Tell us about your company and we will walk you through it.

Further reading: Aureus ERP Custom Fields plugin, Laravel schema and migrations, Eloquent casting

Exit mobile version