Core architecture
Hubleto is built from small parts that are connected in a few well-defined places. Knowing these places is more useful than knowing every class.
Principles
- Everything is an app. The sign-in page, the desktop, settings and the CRM are apps. An app is a folder with a
manifest.yamland aLoaderclass. The ERP core only loads and wires the apps. - The model describes everything about the data. Columns, relations, labels, table and form descriptions are in the model. The UI asks the model what to display. See the Description API.
- The browser is a thin client. PHP renders the page shell with Twig and the React components fetch the data from JSON endpoints.
- Apps talk to each other through contracts, not by editing each other: managers (
Calendar,Workflow,Dashboards,Settings), events, extendibles andFormCustomizer. - Services are singletons created by the dependency injection container.
The extension points
| You want to… | Extension point | Page |
|---|---|---|
| Add pages, tables and forms | App with controllers, views and models | Apps |
| React when a record is saved or deleted | Event listener | Events and listeners |
| Add something to the menu, tools, mail variables | Extendible | Extendibles |
| Add a tab or a button to a form of another app | FormCustomizer in Loader.tsx |
Customizing forms |
| Run a job periodically | Cron | Scheduled jobs |
| Replace a core service | Service provider | Dependency injection |
| Add a column to a model of another app | Custom column in the configuration | Adding custom columns |
| Let an AI assistant call your code | MCP tool | AI assistant |
Extension points.
Where the code runs
┌──────────────────────────────── PHP (server) ─────────────────────────────┐
│ index.php → boot.php → Loader::init() → AppManager (init() of each app) │
│ Router → Renderer → Controller::prepareView() → Twig view │
│ Api controllers → Model → RecordManager (Eloquent) → MySQL / MariaDB │
└────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────── JavaScript (browser) ─────────────────────────┐
│ Loader.tsx of each app → hblreact-* tags → Table / Form components │
│ request.get() / post() → api/... endpoints │
└────────────────────────────────────────────────────────────────────────────┘
The details of each step are in Core.
