Release 1.43.0 — Dabih: Production Hardening
Summary
Production-hardening release shipping four feature areas in one cut:
- ORM-aware N+1 query detection with strict-mode CI enforcement
- Driver-aware
$query->explain()/Builder::explain() - Kubernetes-conventional health probes (
/health/live,/ready,/startup) - Hardened API keys: dedicated
api_keystable with scopes, IP allowlists, expiration, rotation grace, and environment-prefixed plaintext
Four ORM bug fixes that surfaced as prerequisites for the N+1 detector land alongside. ApiKeyAuthenticationProvider is now single-track — legacy users.api_key fallback removed (queried a
column the canonical schema never had); UserRepository::findByApiKey() removed (zero callers verified org-wide).
Changes
Added
- ORM-aware N+1 detection —
PreventsLazyLoadingtrait onModel, four modes (off/warn/strict/auto), per-model opt-out via$instanceLazyLoadingMode, custom violation handler
hook, per-request dedupe. $query->explain()driver-aware — SQLiteEXPLAIN QUERY PLAN, MySQL/PostgreSQLEXPLAIN.Builder::explain()on the ORM applies global scopes.QueryExecutorInterface::getDriverName()— exposes the underlying PDO driver name for other call-sites that need similar branching.- Health probes —
GET /health/live,GET /health/ready,GET /health/startupat canonical paths orchestrators expect. Existing/healthzand/readykeep working. - Hardened API keys — SHA-256 hashed, prefix-indexed for O(1) lookup, collision-tolerant verify,
UNIQUEconstraint onkey_hash.#[RequireScope]route attribute (IS_REPEATABLE—
OR within attribute, AND across stacked attributes) auto-attachesrequire_scopemiddleware viaAttributeRouteLoader. apikey:*CLI —create,list,rotate,revoke.- Router exposes matched route on request —
_route/_route_paramson$request->attributesfor middleware metadata reads. - Docs —
docs/API_KEYS.md(full usage guide),docs/ORM/N_PLUS_ONE_DETECTION.md,docs/FRAMEWORK_IMPROVEMENTS.mdrestructure.
Fixed
- ORM property access routes to relations —
HasAttributes::getAttribute()previously returned null for relation-method names. __isset()is relation-aware —??no longer swallows lazy-load results.- Related-model context propagation —
HasRelationships::newRelatedInstance()passes the parent'sApplicationContextto children. - Eager loading no longer emits
WHERE x = NULL—Builder::getRelation()wraps construction inRelation::noConstraints(...).
Changed
ApiKeyAuthenticationProvideris single-track — all fourAuthenticationProviderInterfacemethods (authenticate,validateToken,refreshTokens,generateTokens) updated to
verify viaApiKeyService::verify()exclusively. No legacyusers.api_keyfallback.
Removed
UserRepository::findByApiKey()— zero callers across the framework, all official extensions, api-skeleton, and other org repos.
Migration Notes
- Run the new migration from
glueful/api-skeleton ^1.26.0:php glueful migrate:run. Creates theapi_keystable that the new auth provider and CLI commands require. - No automatic data migration from
users.api_key— the canonical schema never had that column. Custom installs that added it should usephp glueful apikey:createor
ApiKeyService::create()to mint new keys. - New env var (optional):
DB_LAZY_LOADING_MODE— defaults toauto(warn in development, off elsewhere). Set tostrictin CI to fail tests on accidental N+1 patterns. - External callers of
UserRepository::findByApiKey()must remove the reference. - See
CHANGELOG.md§[1.43.0]→### Upgrade Notesfor the full list.
Test Plan
-
composer test— 857 tests, 1793 assertions, 68 skipped (baseline) -
composer run analyse—[OK] No errors -
composer run phpcs— clean - In api-skeleton:
php glueful migrate:runapplies009_CreateApiKeysTable.phpcleanly;migrate:rollbackdrops it cleanly - Smoke-test
apikey:create --user=<uuid> --name="Test"produces a usable key - Smoke-test
GET /health/live,/health/ready,/health/startupagainst a booted app - Verify
DB_LAZY_LOADING_MODE=strictin a CI test run flags any actual N+1 in the consumer app
Companion PRs
glueful/api-skeleton1.26.0 — shipsdatabase/migrations/009_CreateApiKeysTable.php, bumps framework constraint, mirrorsDB_LAZY_LOADING_MODEin.env.exampleglueful/docs— release notes for 1.43.0 incontent/releases.md
References
- Spec:
docs/superpowers/specs/2026-05-21-api-key-hardening-design.md,docs/superpowers/specs/2026-05-20-n-plus-one-detection-design.md - Plans:
docs/superpowers/plans/2026-05-21-api-key-hardening.md,docs/superpowers/plans/2026-05-20-n-plus-one-detection.md - Roadmap:
docs/FRAMEWORK_IMPROVEMENTS.md§ 5.3, § 6.2.1, § 6.2.2, § 4.3
Closes the near-term core hardening items on the roadmap.