Implement CLEANUP.md fixes: security, DI, routing, streaming, concurrency, and generator improvements#4
Open
vedavith wants to merge 15 commits into
Open
Implement CLEANUP.md fixes: security, DI, routing, streaming, concurrency, and generator improvements#4vedavith wants to merge 15 commits into
vedavith wants to merge 15 commits into
Conversation
…ng, provisioning rollback - Route tenant:create through TenantService.onboard() so tenant is registered in DB - Add provisioning rollback: drop tenant DB on migration failure - Add migrate:all-tenants command for keeping existing tenant DBs in sync - Complete HTTP layer: Pipeline middleware runner, Router, Request::path(), Response value object (withJson/send/immutable) - Add SubdomainTenantResolver and wire into TenantResolverFactory - Add RequestLifecycle helper for concurrency safety (Swoole/RoadRunner) - Add tenant suspend/resume/offboard to TenantService + TenantRepository - Add connection registry to TenantConnectionResolver (reuse PDO per DB) - Run CoreSchemaManager for both tenancy strategies (always create tenants table) - Add --config-dir option to generate:all command - Expand ConfigValidator to require all database.* keys - 185 tests passing, 1 skipped (getallheaders unavailable in CLI SAPI)
- ARCHITECTURE.md: rewrite covering all current components — Pipeline, Router, SubdomainTenantResolver, RequestLifecycle, MigrateAllTenantsCommand, tenant lifecycle, connection pooling, HTTP layer, boot sequence, concurrency notes - CONCEPT.md: expand from stub to full glossary of every major class and concept - CLEANUP.md: document known limitations and deferred work — parameterised routes, DI container, migration dry-run, tenant ID validation, SQL injection notes
TenantRepository gains allActive() which selects only status='active' rows. MigrateAllTenantsCommand switches from all() to allActive() so suspended tenants are excluded from bulk migration runs.
assertColumnName() enforces ^[a-zA-Z0-9_]+$ on every column name passed to create(), where(), and update() before it is interpolated into SQL. Throws InvalidArgumentException on violation.
MigrationRunner::run() and rollback() accept a $dryRun flag. In dry-run mode all writes are skipped and output is prefixed with [DRY RUN]. migrate, migrate:rollback, and migrate:all-tenants gain a --dry-run option wired through to the runner.
onboard() now rejects tenant IDs that do not match ^[a-zA-Z0-9_-]+$ before touching the database. TenantRepository and TenantProvisioner can be injected via constructor, eliminating the need for overload: mocks in tests.
Container supports bind(), singleton(), instance(), and make(). Auto- wiring resolves typed constructor parameters recursively. Application creates a container on boot, registers TenantRepository, TenantProvisioner, and TenantService as singletons, and exposes it via getContainer().
MigrationBuilder emits CONSTRAINT ... FOREIGN KEY from relations.belongsTo and INDEX / UNIQUE INDEX from indexes. SchemaValidator validates both new sections. EntitySchema exposes getIndexes().
subdomainDepth + 3 hardcoded threshold replaced with a configurable minParts parameter (default 3). Set tenancy.subdomain_min_parts: 2 in application.yaml to support two-part hosts like acme.io. TenantResolverFactory reads the new config key.
Router delegates to nikic/fast-route for route matching. {name} segments
are resolved to named captures available via Request::param() and params().
Method mismatches now return 405 instead of 404. Exact routes registered
before parameterised ones take priority.
Response::stream(callable) sends status and headers then delegates output to the caller. The callable echoes chunks and controls flush timing, avoiding full-body buffering for large responses.
TenantContext::setTenantId() throws LogicException if a tenant is already set, turning silent tenant leaks into hard errors. Applications using RequestLifecycle::begin() correctly are unaffected as begin() calls clear() before each request.
--parallel N (default 5) spawns N concurrent subprocesses via symfony/process, each running migrate:all-tenants --tenant=<id>. Cross-platform: works on Linux, macOS, and Windows. --dry-run is forwarded to subprocesses automatically. Also adds nikic/fast-route dependency used by the HTTP router.
CLEANUP.md updated to reflect all completed fixes. Orphaned root-level scripts run-generator.php and test.php removed.
Documents: DI container, column name validation, tenant ID validation, parameterised routes with FastRoute, response streaming, dry-run mode, parallel migrate:all-tenants workers, configurable subdomain min parts, FK and index generator support, TenantContext lifecycle enforcement, and updated CLI command table with key options.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan