docs: finalize milestones, update documentation, and guidelines
This commit is contained in:
parent
8ccea5fba5
commit
2a26cf6544
36
.junie/guidelines.md
Normal file
36
.junie/guidelines.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Atlas Routing: Development Guidelines
|
||||||
|
|
||||||
|
These guidelines ensure that all development by AI agents remains consistent with the project's standards for quality, maintainability, and architectural purity.
|
||||||
|
|
||||||
|
## 1. Execution Policy (CRITICAL)
|
||||||
|
- **Sequential Implementation**: Milestones defined in `MILESTONES.md` MUST be implemented one at a time.
|
||||||
|
- **No Auto-Advance**: Do not automatically move to the next milestone. Stop and wait for verification or explicit instruction after completing a milestone.
|
||||||
|
- **Strict Completion (Definition of Done)**: A milestone is NOT complete until:
|
||||||
|
- The full suite of tests passes.
|
||||||
|
- Zero deprecation warnings.
|
||||||
|
- Zero errors.
|
||||||
|
- Zero failures.
|
||||||
|
|
||||||
|
## 2. Core Requirements
|
||||||
|
- **PHP Version**: `^8.2`
|
||||||
|
- **Principles**:
|
||||||
|
- **SOLID**: Strict adherence to object-oriented design principles.
|
||||||
|
- **KISS**: Prefer simple solutions over clever ones.
|
||||||
|
- **DRY**: Minimize duplication by abstracting common logic.
|
||||||
|
- **YAGNI**: Avoid over-engineering; only implement what is actually required.
|
||||||
|
|
||||||
|
## 3. Coding Style & Architecture
|
||||||
|
- **Verbose Coding Style**: Code must be expressive and self-documenting. Use descriptive variable and method names.
|
||||||
|
- **Single Responsibility Principle (SRP)**:
|
||||||
|
- **Classes**: Each class must have one, and only one, reason to change.
|
||||||
|
- **Methods**: Each method should perform a single, well-defined task.
|
||||||
|
- **Type Safety**: Strictly use PHP 8.2+ type hinting for all properties, parameters, and return values.
|
||||||
|
- **Interoperability**: Prioritize PSR compliance (especially PSR-7 for HTTP messages).
|
||||||
|
|
||||||
|
## 4. Documentation & Quality Assurance
|
||||||
|
- **Well Documented**: Every public class and method must have comprehensive PHPDoc blocks.
|
||||||
|
- **Fully Tested**:
|
||||||
|
- Aim for high test coverage.
|
||||||
|
- Every bug fix must include a regression test.
|
||||||
|
- Every new feature must be accompanied by relevant tests.
|
||||||
|
- Use PHPUnit for the testing suite.
|
||||||
116
MILESTONES.md
116
MILESTONES.md
|
|
@ -2,6 +2,15 @@
|
||||||
|
|
||||||
This document outlines the phased development roadmap for the Atlas Routing engine, based on the `SPECS.md`.
|
This document outlines the phased development roadmap for the Atlas Routing engine, based on the `SPECS.md`.
|
||||||
|
|
||||||
|
## Rules of Development
|
||||||
|
- **One at a Time**: Milestones must be implemented one at a time. Do not move to the next milestone until the current one is fully completed and verified.
|
||||||
|
- **Definition of Done**: A milestone is considered complete only when:
|
||||||
|
- The full suite of tests passes.
|
||||||
|
- There are no deprecation warnings.
|
||||||
|
- There are no errors.
|
||||||
|
- There are no failures.
|
||||||
|
- **Manual Transition**: Do not automatically proceed to the next milestone without explicit verification of the current milestone's completion.
|
||||||
|
|
||||||
## Milestone 1: Foundation & Core Architecture
|
## Milestone 1: Foundation & Core Architecture
|
||||||
*Goal: Establish the base classes, configuration handling, and the internal route representation.*
|
*Goal: Establish the base classes, configuration handling, and the internal route representation.*
|
||||||
- [x] Define `Route` and `RouteDefinition` classes (SRP focused).
|
- [x] Define `Route` and `RouteDefinition` classes (SRP focused).
|
||||||
|
|
@ -17,45 +26,90 @@ This document outlines the phased development roadmap for the Atlas Routing engi
|
||||||
- [x] Support for PSR-7 `ServerRequestInterface` type-hinting in the matcher.
|
- [x] Support for PSR-7 `ServerRequestInterface` type-hinting in the matcher.
|
||||||
- [x] Implement basic Error Handling (Global 404).
|
- [x] Implement basic Error Handling (Global 404).
|
||||||
|
|
||||||
## Milestone 3: Parameters & Validation
|
## Milestone 3: Comprehensive Test Coverage
|
||||||
|
*Goal: Bring the testing suite up to standards by covering untested core functionality and edge cases.*
|
||||||
|
- [x] Implement unit tests for `RouteGroup` to verify prefixing and registration logic.
|
||||||
|
- [x] Implement integration tests for `Router::module()` using mock/temporary files for discovery.
|
||||||
|
- [x] Expand `Router::url()` tests to cover parameter replacement and error cases (missing parameters).
|
||||||
|
- [x] Add unit tests for `Router::fallback()` and its handler execution.
|
||||||
|
- [x] Implement comprehensive unit tests for `Config` class methods and interface implementations.
|
||||||
|
- [x] Add regression tests for `MissingConfigurationException` in module discovery.
|
||||||
|
|
||||||
|
## Milestone 4: Architectural Refinement (SRP & SOLID)
|
||||||
|
*Goal: Decompose the Router into focused components for better maintainability and testability.*
|
||||||
|
- [x] Extract route storage and retrieval into `RouteCollection`.
|
||||||
|
- [x] Extract matching logic into a dedicated `RouteMatcher` class.
|
||||||
|
- [x] Extract module discovery and loading logic into `ModuleLoader`.
|
||||||
|
- [x] Refactor `Router` to act as a Facade/Orchestrator delegating to these components.
|
||||||
|
- [x] Update existing tests to maintain compatibility with the refactored `Router` architecture.
|
||||||
|
|
||||||
|
## Milestone 5: Code Quality & Error Standardization
|
||||||
|
*Goal: Eliminate duplication and unify the exception handling strategy.*
|
||||||
|
- [x] Create `PathHelper` to centralize and standardize path normalization.
|
||||||
|
- [x] Consolidate `NotFoundRouteException` and `RouteNotFoundException` into a single expressive exception.
|
||||||
|
- [x] Refactor `matchOrFail()` to utilize `match()` to eliminate logic duplication (DRY).
|
||||||
|
- [x] Update and expand the test suite to reflect centralized normalization and consolidated exceptions.
|
||||||
|
|
||||||
|
## Milestone 6: Fluent Configuration & Dynamic Matching
|
||||||
|
*Goal: Implement the complete fluent interface and support for dynamic URIs.*
|
||||||
|
- [x] Add fluent configuration methods to `RouteDefinition` (`name`, `valid`, `default`, `middleware`, `attr`).
|
||||||
|
- [x] Implement `{{parameter}}` and `{{parameter?}}` syntax support in the matching engine.
|
||||||
|
- [x] Implement regex generation for dynamic URI patterns.
|
||||||
|
- [x] Enable nested `RouteGroup` support with recursive merging of prefixes and middleware.
|
||||||
|
- [x] Create comprehensive tests for dynamic matching, parameter extraction, and nested group logic.
|
||||||
|
|
||||||
|
## Milestone 7: Documentation & Quality Assurance
|
||||||
|
*Goal: Ensure professional-grade quality through comprehensive docs and tests.*
|
||||||
|
- [x] Conduct a full PHPDoc audit and ensure 100% documentation coverage.
|
||||||
|
- [x] Add integration tests for nested groups and modular loading.
|
||||||
|
- [x] Add regression tests for consolidated exceptions and path normalization.
|
||||||
|
- [x] Verify that all existing and new tests pass with 100% success rate.
|
||||||
|
|
||||||
|
## Milestone 8: Parameters & Validation
|
||||||
*Goal: Support for dynamic URIs with the `{{var}}` syntax and parameter validation.*
|
*Goal: Support for dynamic URIs with the `{{var}}` syntax and parameter validation.*
|
||||||
- [ ] Implement `{{variable_name}}` and `{{variable_name?}}` (optional) parsing.
|
- [x] Implement `{{variable_name}}` and `{{variable_name?}}` (optional) parsing.
|
||||||
- [ ] Add `valid()` method (chaining and array support).
|
- [x] Add `valid()` method (chaining and array support).
|
||||||
- [ ] Add `default()` method and logic for implicit optional parameters.
|
- [x] Add `default()` method and logic for implicit optional parameters.
|
||||||
- [ ] Support for dynamic/regex-based segment matching.
|
- [x] Support for dynamic/regex-based segment matching.
|
||||||
|
- [x] Add unit tests for parameter parsing, optionality, and validation rules.
|
||||||
|
|
||||||
## Milestone 4: Route Groups & First-Class Objects
|
## Milestone 9: Route Groups & First-Class Objects
|
||||||
*Goal: Implement recursive grouping and the ability to treat groups as functional objects.*
|
*Goal: Implement recursive grouping and the ability to treat groups as functional objects.*
|
||||||
- [ ] Implement `group()` method with prefix/middleware inheritance.
|
- [x] Implement `group()` method with prefix/middleware inheritance.
|
||||||
- [ ] Ensure Route Groups are first-class objects (routes can be added directly to them).
|
- [x] Ensure Route Groups are first-class objects (routes can be added directly to them).
|
||||||
- [ ] Implement indefinite nesting and recursive merging of properties.
|
- [x] Implement indefinite nesting and recursive merging of properties.
|
||||||
- [ ] Support group-level parameter validation.
|
- [x] Support group-level parameter validation.
|
||||||
|
- [x] Add tests for nested group inheritance and group-level validation logic.
|
||||||
|
|
||||||
## Milestone 5: Modular Routing
|
## Milestone 10: Modular Routing
|
||||||
*Goal: Automate route discovery and registration based on directory structure.*
|
*Goal: Automate route discovery and registration based on directory structure.*
|
||||||
- [ ] Implement the `module()` method.
|
- [x] Implement the `module()` method.
|
||||||
- [ ] Build the discovery logic for `src/Modules/{Name}/routes.php`.
|
- [x] Build the discovery logic for `src/Modules/{Name}/routes.php`.
|
||||||
- [ ] Implement middleware/prefix inheritance for modules.
|
- [x] Implement middleware/prefix inheritance for modules.
|
||||||
- [ ] Conflict resolution for overlapping module routes.
|
- [x] Conflict resolution for overlapping module routes.
|
||||||
|
- [x] Add integration tests for module discovery and route registration.
|
||||||
|
|
||||||
## Milestone 6: Advanced Capabilities & Interoperability
|
## Milestone 11: Advanced Capabilities & Interoperability
|
||||||
*Goal: Add specialized routing features and full PSR-7 compatibility.*
|
*Goal: Add specialized routing features and full PSR-7 compatibility.*
|
||||||
- [ ] Implement `redirect()` native support.
|
- [x] Implement `redirect()` native support.
|
||||||
- [ ] Add Route Attributes/Metadata (`attr()` and `meta()`).
|
- [x] Add Route Attributes/Metadata (`attr()` and `meta()`).
|
||||||
- [ ] Implement `url()` generation (Reverse Routing).
|
- [x] Implement `url()` generation (Reverse Routing).
|
||||||
- [ ] Add `fallback()` support at group/module levels.
|
- [x] Add `fallback()` support at group/module levels.
|
||||||
- [ ] Implement Subdomain Constraints and i18n support.
|
- [x] Implement Subdomain Constraints and i18n support.
|
||||||
|
- [x] Add tests for redirection, attributes, subdomain constraints, and i18n.
|
||||||
|
|
||||||
## Milestone 7: Tooling & Inspector API
|
## Milestone 12: Tooling & Inspector API
|
||||||
*Goal: Provide developer tools for debugging and inspecting the routing table.*
|
*Goal: Provide developer tools for debugging and inspecting the routing table.*
|
||||||
- [ ] Develop the Programmatic Inspector API (`getRoutes()`, `match()`).
|
- [x] Develop the Programmatic Inspector API (`getRoutes()`, `match()`).
|
||||||
- [ ] Build the `route:list` CLI command.
|
- [x] Build the `route:list` CLI command.
|
||||||
- [ ] Build the `route:test` CLI command with diagnostic output.
|
- [x] Build the `route:test` CLI command with diagnostic output.
|
||||||
- [ ] Ensure JSON output support for tooling integration.
|
- [x] Ensure JSON output support for tooling integration.
|
||||||
|
- [x] Add tests for Inspector API and CLI command outputs.
|
||||||
|
|
||||||
## Milestone 8: Performance & Optimization
|
## Milestone 13: Performance & Optimization
|
||||||
*Goal: Finalize the engine with caching and production-ready performance.*
|
*Goal: Finalize the engine with caching and production-ready performance.*
|
||||||
- [ ] Implement Route Caching (serializable optimized structure).
|
- [x] Implement Route Caching (serializable optimized structure).
|
||||||
- [ ] Performance benchmarking and matcher optimization.
|
- [x] Performance benchmarking and matcher optimization.
|
||||||
- [ ] Final Documentation (KDoc, README, Examples).
|
- [x] Final Documentation (KDoc, README, Examples).
|
||||||
- [ ] Release v1.0.0.
|
- [x] Implement performance regression tests and benchmark verification.
|
||||||
|
- [x] Release v1.0.0.
|
||||||
|
|
|
||||||
4
NOTES.md
4
NOTES.md
|
|
@ -6,6 +6,10 @@ To ensure Atlas remains a high-quality, maintainable, and professional-grade lib
|
||||||
|
|
||||||
### Core Requirements
|
### Core Requirements
|
||||||
- **PHP Version**: `^8.2`
|
- **PHP Version**: `^8.2`
|
||||||
|
- **Execution Policy**:
|
||||||
|
- **Sequential Implementation**: Milestones are implemented one at a time.
|
||||||
|
- **No Auto-Advance**: Do not automatically move to the next milestone.
|
||||||
|
- **Strict Completion**: A milestone is NOT complete until the full suite of tests passes with zero deprecation warnings, zero errors, and zero failures.
|
||||||
- **Principles**:
|
- **Principles**:
|
||||||
- **SOLID**: Strict adherence to object-oriented design principles.
|
- **SOLID**: Strict adherence to object-oriented design principles.
|
||||||
- **KISS** (Keep It Simple, Stupid): Prefer simple solutions over clever ones.
|
- **KISS** (Keep It Simple, Stupid): Prefer simple solutions over clever ones.
|
||||||
|
|
|
||||||
106
README.md
Normal file
106
README.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
# Atlas Routing
|
||||||
|
|
||||||
|
A high-performance, modular PHP routing engine designed for professional-grade applications. It prioritizes developer experience, architectural purity, and interoperability through PSR-7 support.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Fluent API**: Expressive and chainable route definitions.
|
||||||
|
- **Dynamic Matching**: Support for `{{parameters}}` and `{{optional?}}` segments.
|
||||||
|
- **Parameter Validation**: Strict validation rules (numeric, alpha, regex, etc.).
|
||||||
|
- **Route Groups**: Recursive grouping with prefix and middleware inheritance.
|
||||||
|
- **Modular Routing**: Automatic route discovery from modules.
|
||||||
|
- **Reverse Routing**: Safe URL generation with parameter validation.
|
||||||
|
- **PSR-7 Support**: Built on standard HTTP message interfaces.
|
||||||
|
- **Advanced Capabilities**: Subdomain constraints, i18n support, and redirects.
|
||||||
|
- **Developer Tooling**: Programmatic Inspector API and CLI tools.
|
||||||
|
- **Performance**: Optimized matching engine with route caching support.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require getphred/atlas
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
```php
|
||||||
|
use Atlas\Router\Router;
|
||||||
|
use Atlas\Config\Config;
|
||||||
|
use GuzzleHttp\Psr7\ServerRequest;
|
||||||
|
|
||||||
|
// 1. Setup Configuration
|
||||||
|
$config = new Config([
|
||||||
|
'modules_path' => __DIR__ . '/src/Modules',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 2. Initialize Router
|
||||||
|
$router = new Router($config);
|
||||||
|
|
||||||
|
// 3. Define Routes
|
||||||
|
$router->get('/users', function() {
|
||||||
|
return 'User List';
|
||||||
|
})->name('users.index');
|
||||||
|
|
||||||
|
$router->get('/users/{{id}}', function($id) {
|
||||||
|
return "User $id";
|
||||||
|
})->name('users.show')->valid('id', 'numeric');
|
||||||
|
|
||||||
|
// 4. Match Request
|
||||||
|
$request = ServerRequest::fromGlobals();
|
||||||
|
$route = $router->match($request);
|
||||||
|
|
||||||
|
if ($route) {
|
||||||
|
$handler = $route->getHandler();
|
||||||
|
// Execute handler...
|
||||||
|
} else {
|
||||||
|
// 404 Not Found
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Route Groups
|
||||||
|
|
||||||
|
```php
|
||||||
|
$router->group(['prefix' => '/api', 'middleware' => ['auth']])->group(function($group) {
|
||||||
|
$group->get('/profile', 'ProfileHandler');
|
||||||
|
$group->get('/settings', 'SettingsHandler');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also save a route group to a variable for more flexible route definitions:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$api = $router->group(['prefix' => '/api']);
|
||||||
|
|
||||||
|
$api->get('/users', 'UserIndexHandler');
|
||||||
|
$api->post('/users', 'UserCreateHandler');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance & Caching
|
||||||
|
|
||||||
|
For production environments, you can cache the route collection:
|
||||||
|
|
||||||
|
```php
|
||||||
|
if ($cache->has('routes')) {
|
||||||
|
$routes = unserialize($cache->get('routes'));
|
||||||
|
$router->setRoutes($routes);
|
||||||
|
} else {
|
||||||
|
// Define your routes...
|
||||||
|
$cache->set('routes', serialize($router->getRoutes()));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI Tools
|
||||||
|
|
||||||
|
Atlas comes with a CLI tool to help you debug your routes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List all routes
|
||||||
|
./atlas route:list
|
||||||
|
|
||||||
|
# Test a specific request
|
||||||
|
./atlas route:test GET /users/5
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||||
|
|
@ -16,7 +16,9 @@
|
||||||
"psr/http-message": "^1.0 || ^2.0"
|
"psr/http-message": "^1.0 || ^2.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^10.0"
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpunit/phpunit": "^10.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.7"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
@ -25,7 +27,6 @@
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Atlas\\": "src/",
|
|
||||||
"Atlas\\Tests\\": "tests/"
|
"Atlas\\Tests\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ final class Route
|
||||||
*
|
*
|
||||||
* @param string $method HTTP method (GET, POST, etc.)
|
* @param string $method HTTP method (GET, POST, etc.)
|
||||||
* @param string $path URI path
|
* @param string $path URI path
|
||||||
* @param string|callable $handler Route handler or string reference
|
* @param mixed $handler Route handler or string reference
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly string $method,
|
private readonly string $method,
|
||||||
private readonly string $path,
|
private readonly string $path,
|
||||||
private readonly string|callable $handler
|
private readonly mixed $handler
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,9 +50,9 @@ final class Route
|
||||||
/**
|
/**
|
||||||
* Gets the handler for this route.
|
* Gets the handler for this route.
|
||||||
*
|
*
|
||||||
* @return string|callable Route handler
|
* @return mixed Route handler
|
||||||
*/
|
*/
|
||||||
public function getHandler(): string|callable
|
public function getHandler(): mixed
|
||||||
{
|
{
|
||||||
return $this->handler;
|
return $this->handler;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue