betalabs/engine-laravel-helper
A Laravel helper package from Betalabs that bundles reusable utility functions for Engine-based applications. It streamlines common tasks so developers can avoid duplicating boilerplate across projects, keeping code cleaner and more consistent within the Betalabs ecosystem.
Architecture fit
betalabs/engine-phpsdk ^3.0, exposing two capability clusters: multi-tenant identity/registry management (Scopes\Tenant, Models\BelongsToTenant, Services\Tenant\Updater) and Brazilian fiscal document handling (Services\NFe\TaxInvoice\Indexer).tenant_id-scoped database, OAuth2 via Laravel Passport, and an upstream "Engine" API as the system of record for credentials and fiscal operations. This is not a general-purpose utility — it is opinionated infrastructure glue.engine-phpsdk, not in this package.Integration feasibility
bootstrap/app.php instead of the package's service provider) is the only non-obvious wiring step.Passport::routes(), so any existing bootstrap or provider code calling it must be deleted — this is a code-path change we must own, not something the package can fix for us.oauth_* migrations if the target database predates them; this is a schema-mutating step on a live auth table set and needs a change window.engine-phpsdk version policy as part of the package's risk surface, not as an implementation detail.Technical risk
v6.0.0 tag points at old code and that v6.0.2 supersedes the entire 6.x line. A mistagged major release in a package that touches credentials and fiscal documents means we must pin exact versions (6.0.2), commit composer.lock, and verify the installed artifact rather than trusting a range constraint.Tenant\Updater previously wrote engine_api_access_token to the tenant's first registry; it now writes exclusively to the engine registry and throws RuntimeException when that registry is absent. Tenants with multiple registries may have tokens in the wrong place today, and will start failing loudly post-upgrade. This is a data-migration problem disguised as a bug fix.NFe\TaxInvoice\Indexer now prefers the nfe registry over the first registry. In an environment where tenants hold multiple registries, this can shift which credentials sign or transmit a fiscal document. The blast radius is regulatory (rejected or misattributed invoices), not merely technical.table.tenant_id resolves ambiguous-column failures on JOINed queries (e.g. _fields=orders->code). The prior failure mode was a hard DB error rather than cross-tenant leakage, which is the better failure — but tenant scoping is a security boundary, and a scope that fails closed on JOINs may have driven teams to bypass it (withoutGlobalScope). We should audit for such workarounds.engine-phpsdk ^3.0 is a major-version floor. The 5.x → 6.x boundary is defined by that dependency, so our upgrade calendar is now partly owned by the vendor.Key questions
engine registry entirely? (Determines backfill scope and RuntimeException exposure.)engine_api_access_token, and is it the one the engine registry should own?nfe-preferred routing change the signing identity for any tenant?withoutGlobalScope to work around the pre-fix ambiguous-column errors?Stack fit
| Dimension | Package requirement | Assessment |
|---|---|---|
| PHP | ^8.2, targeted/tested at 8.5 | Fits if we are on 8.2/8.3; 8.5 is aspirational |
| Laravel | 10, 11, 12 (target 12) | Laravel 10 is past end-of-life for security fixes — package support does not extend our app's supportability |
| Passport | 11 or 12 | Passport 12 needs oauth_* migrations published |
| SDK | betalabs/engine-phpsdk ^3.0 |
Hard coupling; major-version pin |
| DB | Shared schema with tenant_id on tenant-owned tables |
Assumed, not optional |
bootstrap/app.php on Laravel 11/12; Passport::routes() must be removed from all bootstrap paths.Migration path (5.x → 6.x)
6.0.2 explicitly; do not allow ^6.0 in any manifest until the v6.0.0 tag issue is understood. Verify the installed tag/commit post-install.engine-phpsdk ^3.0 resolvable. If either fails, the app stays on 5.x — this is a hard gate, not a soft one.Passport::routes() calls; register package routes in bootstrap/app.php for Laravel 11/12; publish and run Passport 12 migrations where oauth_* tables are absent. Verify the api guard config survives.engine registry for every tenant and ensure engine_api_access_token lands there. For tenants with an nfe registry, confirm the intended fiscal credential._fields=orders->code-style eager/list endpoints that previously hit ambiguous-column errors; grep for withoutGlobalScope workarounds and retire them.Compatibility notes
engine-phpsdk 2.x; those apps are pinned to 5.x indefinitely, which is a long-term fork risk if the vendor stops backporting.Sequencing
RuntimeException is a hard failure, so an un-backfilled tenant will break, not degrade.Maintenance
engine-phpsdk all move independently, and 6.x has already demonstrated that the vendor's release quality is uneven (stale v6.0.0 tag, suite broken across four major versions).Support
engine-phpsdk or the Engine API, not in this package. Our internal team can triage but not fix. Confirm the vendor SLA before this becomes a tier-1 dependency.Scaling
table.tenant_id scope is a performance-positive change: it makes tenant-scoped JOIN queries valid, which means they can use composite indexes on (tenant_id, ...) instead of failing or being rewritten. Verify index coverage on tenant_id for all joined tables, since the fix will enable query patterns that previously errored and are therefore unbenchmarked.Failure modes
| Failure | Symptom | Detection | Mitigation |
|---|---|---|---|
Missing engine registry |
RuntimeException on tenant update |
Upgrade-time, per tenant | Pre-flight backfill script + tenant inventory |
| Token in wrong registry (multi-registry tenants) | Silent write to legacy location, later auth failures | Post-upgrade, delayed | Audit and copy tokens before cutover |
| Fiscal call uses unexpected registry | NF-e issued under wrong credentials / rejected | Customer- or authority-reported — late | Canary tenants + reconciliation of issued documents |
| Passport 12 tables absent | OAuth failures, 500s on auth routes | Staging | Publish and run migrations in the same window |
Passport::routes() left in bootstrap |
Boot-time fatal on Passport 11+ | Immediate | Codebase grep in pre-merge checklist |
Ambiguous tenant_id on JOIN (pre-fix path) |
DB error on list endpoints | QA / synthetic monitoring | Regression tests on _fields JOIN endpoints |
| Mistagged/wrong version installed | Old 6.0.0 code in production | Lockfile review | Exact pin + post-deploy version assertion |
| Test suite falsely green | Undetected regression | — | Do not treat vendor CI as our coverage |
Ramp-up
engine vs nfe distinction, tenant scoping invariants, and Brazilian fiscal document lifecycle. That knowledge currently lives in the vendor's docs and this changelog, not in our codebase.engine registry," and write our own integration tests for the two registry-routing paths before any tenant with multiple registries is exposed.How can I help you explore Laravel packages today?