composer.json, package.json and their lock files; when this page and a lock
file disagree, the lock file is right.
Backend
Development-only: Telescope, Pail, ide-helper, Ray and Laravel Boost.
Data
How tenant context is held and switched: Tenant-aware execution.
Why migrations are pure DDL: Migration isolation.
Why keys are ULIDs in
uuid columns: ID strategy.
Queues and realtime
Workers are long-lived, which is what Long-lived worker safety
is about. Turning websockets on: Realtime.
Console front end
The staff console — platform administration and the per-assistant screens — is an Inertia application in Vue. Core has no Filament or Livewire: neither is incomposer.json, so in Core’s CI a reference to either fails phpstan’s
unknown-class checks. The PHPat rule NoFilamentTest bites only where Filament
is installed — a local Core checkout with the SaaS overlay.
Translations come from Laravel’s
lang/ files (en, ru, uk) and reach a
page as shared Inertia props, one namespace per page — there is no separate
front-end i18n library. Admin UI language and content language are different
things; see Multilingual.
Solution screens are prebuilt bundles that import Vue, Inertia and @fapost/ui
from the console through an import map, so a Solution never ships its own copy.
See Console UI.
The flow builder
The builder inresources/js/builder is a separate Vite entry with its own root
view and stylesheet. It is still Inertia and Vue, but the canvas holds a lot of
client state, so it keeps it in Pinia stores rather than in page props. Node
configuration forms are rendered from the schema a handler declares, not written
per node — see Builder UI.
resources/js/tma is a third entry: a small Vue Router app served as a Telegram
Mini App for forms.
Extensions
Core is extended from outside, never by forking it. Briefly:fapost/foundation— the public contracts a Solution or Plugin builds against; Core implements them.fapost/support— primitives with no domain meaning, including the builder schema field classes.- Solutions and Plugins — separate Composer packages, added to a checkout with a composer overlay that leaves Core’s own
composer.jsonuntouched. - The SaaS operator package — the control plane of the hosted service (billing, onboarding), a separate repository on top of Core and never part of it. Its operator panel is built on Filament and lives in that package, not in Core.
Gateway and images
The gateway ingateway/ is an optional Go service (Go 1.27, go-redis 9) in
front of webhook ingress: it verifies, deduplicates and queues provider webhooks
without a PHP process. See Webhook gateway.
A release publishes three images from .github/workflows/publish-images.yml:
core and web come from one docker/Dockerfile; its dev target is the local
development image, built from the same base. Running them: Docker Compose.
Quality
CI runs the PHP job twice — on SQLite, what a developer runs locally, and on
PostgreSQL, where schema-per-tenant switching and partitioned tables actually
behave as in production — with a real Redis beside both. The front-end job
type-checks, tests and runs the same production build the
web image does. How
to run all of it: Testing and architecture checks.
Agents working on Core use Jig for task routing and
project knowledge.