Architecture
The big picture
Browser ── Vue 3 single-page app (frontend/app)
│ JSON over /api/v1, session cookie
▼
Laravel ── thin HTTP shell (app/) ──► the core (domain/, namespace Qorekit\)
│
▼
MySQL, MariaDB or PostgreSQL: meta tables + one table per entityThe interface is built once, at release time, and shipped prebuilt in public/build. A server never needs Node.js.
Real tables
Qorekit keeps two kinds of tables:
- Meta tables describe what was built:
modules,entities,fields,choice_lists,choice_items,rolesand their permissions, list layouts. - Entity tables, one per entity, hold the records. Each field is a column of a type that fits it (
VARCHAR,DECIMAL,DATE, …). Fields with several values (multiple choice, several related records or users) live in a shared link table instead.
Every entity table also has id, created_at, updated_at, created_by, updated_by, deleted_at (the trash) and version (for detecting conflicting edits).
The schema engine (domain/Schema) turns meta changes into DDL. Each change is planned, logged and applied so that a change that fails part way can be finished or undone: the meta and the table never disagree for long, and php artisan qorekit:schema-doctor reports it if they do. Changing a field's type builds a new column, converts the values into it and swaps it in.
Layout
| Path | Contents |
|---|---|
app/ | Thin Laravel shell: HTTP controllers, middleware, console commands, providers |
domain/ | The core, one folder per area, namespace Qorekit\ |
sdk/php/ | The public PHP plugin API, namespace Qorekit\Sdk\ |
frontend/app/ | The Vue single-page application |
frontend/ui/ | @qorekit/ui: the component library, shared with plugins |
frontend/sdk/ | @qorekit/sdk: the JavaScript API client and plugin API |
tests/ | Pest tests, including the architecture rules in tests/Arch |
docs/ | This documentation (VitePress) |
build/ | Release, packaging and test tooling |
docker/ | Development databases and the shared-hosting look-alike |
Areas of the core
| Area | Responsible for |
|---|---|
Meta | Modules, entities, fields, choice lists, list layouts |
Schema | Turning meta changes into DDL; the database dialects |
Fields | The field types: validation, storage, conversion |
Records | Reading and writing records; every write goes through RecordService |
Files | Uploads and serving files |
Permissions | Users, roles, record access, the audit log |
Settings, I18n, Themes | Installation settings, languages, the look |
Install, Update, System | The wizard, signed updates, scheduled work and health |
Demo | The public demo mode |
Classes under Qorekit\{Area}\Internal\ are private to their area. The architecture tests enforce this, along with the rule that the SDK never depends on the core.
Rules that keep it portable
- One write path. Every record write, whether from the interface, an import or a plugin, goes through
RecordService, which validates, checks permissions, keeps the version and the audit columns, and raises events. - No raw SQL outside the dialects. Anything engine-specific lives in
domain/Schema/Dialect; everything else uses Laravel's query builder. - Shared hosting first. No Redis, no websockets, no daemons. Queues and sessions use the database; scheduled work runs from cron, or after page requests when there is no cron.
Extending Qorekit
Plugins will add field types, actions and pages through sdk/php (Qorekit\Sdk\) and @qorekit/sdk, using only the Q* components of @qorekit/ui in the interface. The plugin system is still being built; its interfaces may change before version 1.0.