2025-12-14 23:10:01 +00:00
# Phred Framework Milestones
Phred supports REST and JSON:API via env setting; batteries-included defaults, swappable components.
## ~~M0 — Project bootstrap (repo readiness)~~
* ~~Tasks:~~
* ~~Finalize `composer.json` (namespaces, scripts, suggests) and `LICENSE` .~~
* ~~Add `.editorconfig` , `.gitattributes` , `.gitignore` , example `.env.example` .~~
* ~~Set up CI (lint, static analysis, unit tests) and basic build badge.~~
* ~~Acceptance:~~
* ~~Fresh clone installs (without running suggested packages) and passes linters/analysis/tests.~~
## ~~M1 — Core HTTP kernel and routing~~
* ~~Tasks:~~
* ~~Implement the HTTP kernel: `PSR-15` pipeline via `Relay` .~~
* ~~Wire `nyholm/psr7(-server)` factories and server request creation.~~
* ~~Integrate `nikic/fast-route` with a RouteCollector and dispatcher.~~
* ~~Define route → controller resolution (invokable controllers).~~
* ~~Add minimal app bootstrap (front controller) and DI container wiring (`PHP-DI`).~~
2025-12-15 02:09:06 +00:00
* ~~Addendum: Route groups (prefix only) via `Router::group()` ~~
2025-12-14 23:10:01 +00:00
* ~~Acceptance:~~
* ~~Sample route returning a JSON 200 via controller.~~
* ~~Controllers are invokable (`__invoke(Request)`), one route per controller.~~
2025-12-15 02:09:06 +00:00
* ~~Route groups (prefix only) work and are tested.~~
## ~~M2 — Configuration and environment~~
* ~~Tasks:~~
* ~~Load `.env` via `vlucas/phpdotenv` and expose `Phred\Support\Config` .~~
* ~~Define configuration precedence and document keys (e.g., `API_FORMAT` , `APP_ENV` , `APP_DEBUG` ).~~
* ~~Acceptance:~~
* ~~App reads config from `.env` ; unit test demonstrates override behavior.~~
2025-12-15 15:15:49 +00:00
## ~~M3 — API formats and content negotiation~~
* ~~Tasks:~~
* ~~Finalize `ContentNegotiationMiddleware` using `.env` and `Accept` header.~~
* ~~Bind `ApiResponseFactoryInterface` to `RestResponseFactory` or `JsonApiResponseFactory` based on format.~~
* ~~Provide developer‑ facing helpers for common responses (`ok`, `created` , `error` ).~~
* ~~Acceptance:~~
* ~~Demo endpoints respond correctly as REST or JSON:API depending on `API_FORMAT` and `Accept` .~~
## ~~M4 — Error handling and problem details~~
* ~~Tasks:~~
* ~~Finalize `ProblemDetailsMiddleware` with RFC7807 (REST) and JSON:API error documents.~~
* ~~Integrate `filp/whoops` for dev mode (`APP_DEBUG=true`).~~
* ~~Map common exceptions to HTTP status codes; include correlation/request IDs in responses/logs.~~
* ~~Acceptance:~~
* ~~Throwing an exception yields a standards‑ compliant error response; debug mode shows Whoops page.~~
Implement M5 service providers, M6 MVC bases, and URL extension negotiation; update docs and tests
• M5: Add ServiceProviderInterface and ProviderRepository; integrate providers into Kernel (register before container build, boot after); add RouteRegistry with clear(); add default core providers (Routing, Template, ORM, Flags, Testing) and AppServiceProvider; add contracts and default drivers (Template/Eyrie, Orm/Pairity, Flags/Flagpole, Testing/Codeception)
• Routing: allow providers to contribute routes; add ProviderRouteTest
• Config: add config/providers.php; extend config/app.php with driver keys; document env keys
• M6: Introduce MVC bases: Controller, APIController (JSON helpers), ViewController (html + renderView helpers), View (transformData + renderer); add ViewWithDefaultTemplate and default-template flow; adjust method signatures to data-first and delegate template override to View
• HTTP: Add UrlExtensionNegotiationMiddleware (opt-in via URL_EXTENSION_NEGOTIATION, whitelist via URL_EXTENSION_WHITELIST with default json|php|none); wire before ContentNegotiationMiddleware
• Tests: add UrlExtensionNegotiationTest and MvcViewTest; ensure RouteRegistry::clear prevents duplicate routes in tests
• Docs: Update README with M5 provider usage, M6 MVC examples and template selection conventions, and URL extension negotiation; mark M5 complete in MILESTONES; add M12 task to provide XML support and enable xml in whitelist by default
2025-12-15 22:08:57 +00:00
## ~~M5 — Dependency Injection and Service Providers~~
* ~~Tasks:~~
* ~~Define Service Provider interface and lifecycle (register, boot).~~
* ~~Module discovery loads providers in order (core → app → module).~~
* ~~Add examples for registering controllers, services, config, and routes via providers.~~
* ~~Define contracts: `Template\Contracts\RendererInterface` , `Orm\Contracts\*` , `Flags\Contracts\FeatureFlagClientInterface` , `Testing\Contracts\TestRunnerInterface` .~~
* ~~Define config/env keys for driver selection (e.g., `TEMPLATE_DRIVER` , `ORM_DRIVER` , `FLAGS_DRIVER` , `TEST_RUNNER` ).~~
* ~~Provide “default adapter” Service Providers for the shipped packages and document swap procedure.~~
* ~~Acceptance:~~
* ~~Providers can contribute bindings and routes; order is deterministic and tested.~~
* ~~Drivers can be switched via `.env` /config without changing controllers/services; example provider route covered by tests.~~
Refactor M7 module scaffolding, route inclusion, and tests; implement providers discovery; fix URL extension negotiation; clean docs
• Add Service Providers loading from config/providers.php and merge with runtime config; ensure AppServiceProvider boots and contributes routes
• Create RouteGroups and guard module route includes in routes/web.php; update Kernel to auto-mount module routes and apply provider routes
• Implement create:module as a console Command (extends Phred\Console\Command):
◦ Args: name, prefix; Flags: --update-composer, --no-dump
◦ Stable root resolution (dirname(DIR, 2)); robust args/flags handling under ArrayInput
◦ Scaffolds module dirs (Controllers, Views, Templates, Routes, Providers, etc.), ensures Controllers exists, adds .gitkeep
◦ Writes Provider, View, Controller, Template stubs (fix variable interpolation via placeholders)
◦ Appends guarded include snippet to routes/web.php
◦ Optional composer PSR-4 mapping update (+ backup) and optional autoload dump
◦ Prevents providers.php corruption via name validation and existence checks
• Add URL extension negotiation middleware tweaks:
◦ Only set Accept for .json (and future .xml), never for none/php
◦ Never override existing Accept header
• Add MVC base classes (Controller, APIController, ViewController, View, ViewWithDefaultTemplate); update ViewController signature and View render contract
• Add tests:
◦ CreateModuleCommandTest with setup/teardown to snapshot/restore routes/web.php and composer.json; asserts scaffold and PSR-4 mapping
◦ ProviderRouteTest for provider-contributed route
◦ UrlExtensionNegotiationTest sets API_FORMAT=rest and asserts content-type behavior
◦ MvcViewTest validates transformData+render
• Fix config/providers.php syntax and add comment placeholder for modules
• Update README: M5/M6/M7 docs, MVC examples, template selection conventions, modules section, URL extension negotiation, and module creation workflow
• Update MILESTONES.md: mark M6/M7 complete; add M8 task for register:orm; note M12 XML extension support
2025-12-16 22:14:22 +00:00
## ~~M6 — MVC: Controllers, Views, Templates~~
* ~~Tasks:~~
* ~~Controller base class and conventions (request/response helpers).~~
* ~~View layer (data preparation) with `getphred/eyrie` template engine integration.~~
* ~~Template rendering helper: `$this->render(<template>, <data>)` .~~
* ~~Acceptance:~~
* ~~Example page rendered through View → Template; API coexists with full‑ site rendering.~~
* ~~Rendering works via RendererInterface and can be swapped (e.g., Eyrie → Twig demo) with only configuration/provider changes.~~
## ~~M7 — Modules (Django‑ style app structure)~~
* ~~Tasks:~~
* ~~Define module filesystem layout (Nested Controllers/Views/Services/Models/Templates/Routes/Tests).~~
* ~~Module loader: auto‑ register providers, routes, templates.~~
* ~~Namespacing and autoload guidance.~~
* ~~Core CLI: add `create:module <name>` command to scaffold a module with nested resources.~~
* ~~ORM‑ agnostic module layout (to support Pairity DAO/DTO and Eloquent Active Record):~~
* ~~`Modules/< X > /Models/` — domain models (pure PHP, ORM‑ neutral)~~
* ~~`Modules/< X > /Repositories/` — repository interfaces (DI targets for services)~~
* ~~`Modules/< X > /Persistence/Pairity/` — DAOs, DTOs, mappers, repository implementations~~
* ~~`Modules/< X > /Persistence/Eloquent/` — Eloquent models, scopes, repository implementations~~
* ~~`Modules/< X > /Database/Migrations/*` — canonical migrations for the module (no duplication per driver)~~
* ~~Acceptance:~~
* ~~Creating a module with the CLI makes it discoverable; routes/templates work without manual wiring.~~
* ~~Switching `ORM_DRIVER` between `pairity` and `eloquent` requires no changes to services/controllers; providers bind repository interfaces to driver implementations.~~
2025-12-21 23:01:10 +00:00
## ~~M8 — Database access, migrations, and seeds~~
* ~~Tasks:~~
* ~~Integrate `getphred/pairity` for ORM/migrations/seeds.~~
* ~~Define config (`DB_*`), migration paths (app and modules), and seeder conventions.~~
* ~~CLI commands: `migrate` , `migration:rollback` , `seed` , `seed:rollback` .~~
* ~~All persistence usage in examples goes through Orm contracts; can be swapped (Pairity → Doctrine adapter demo optional).~~
* ~~Add `register:orm <driver>` command:~~
* ~~Verify or guide installation of the ORM driver package.~~
* ~~Update `.env` (`ORM_DRIVER=< driver > `) safely.~~
* ~~Create `modules/*/Persistence/<Driver>/` directories for existing modules.~~
* ~~Acceptance:~~
* ~~Running migrations modifies a test database; seeds populate sample data; CRUD demo works.~~
* ~~All persistence usage in examples goes through Orm contracts; can be swapped (Pairity → Doctrine adapter demo optional).~~
2025-12-14 23:10:01 +00:00
## M9 — CLI (phred) and scaffolding
* Tasks:
* Implement Symfony Console app in `bin/phred` .
Refactor M7 module scaffolding, route inclusion, and tests; implement providers discovery; fix URL extension negotiation; clean docs
• Add Service Providers loading from config/providers.php and merge with runtime config; ensure AppServiceProvider boots and contributes routes
• Create RouteGroups and guard module route includes in routes/web.php; update Kernel to auto-mount module routes and apply provider routes
• Implement create:module as a console Command (extends Phred\Console\Command):
◦ Args: name, prefix; Flags: --update-composer, --no-dump
◦ Stable root resolution (dirname(DIR, 2)); robust args/flags handling under ArrayInput
◦ Scaffolds module dirs (Controllers, Views, Templates, Routes, Providers, etc.), ensures Controllers exists, adds .gitkeep
◦ Writes Provider, View, Controller, Template stubs (fix variable interpolation via placeholders)
◦ Appends guarded include snippet to routes/web.php
◦ Optional composer PSR-4 mapping update (+ backup) and optional autoload dump
◦ Prevents providers.php corruption via name validation and existence checks
• Add URL extension negotiation middleware tweaks:
◦ Only set Accept for .json (and future .xml), never for none/php
◦ Never override existing Accept header
• Add MVC base classes (Controller, APIController, ViewController, View, ViewWithDefaultTemplate); update ViewController signature and View render contract
• Add tests:
◦ CreateModuleCommandTest with setup/teardown to snapshot/restore routes/web.php and composer.json; asserts scaffold and PSR-4 mapping
◦ ProviderRouteTest for provider-contributed route
◦ UrlExtensionNegotiationTest sets API_FORMAT=rest and asserts content-type behavior
◦ MvcViewTest validates transformData+render
• Fix config/providers.php syntax and add comment placeholder for modules
• Update README: M5/M6/M7 docs, MVC examples, template selection conventions, modules section, URL extension negotiation, and module creation workflow
• Update MILESTONES.md: mark M6/M7 complete; add M8 task for register:orm; note M12 XML extension support
2025-12-16 22:14:22 +00:00
* Generators: `create:<module>:controller` , `create:<module>:model` , `create:<module>:migration` , `create:<module>:seed` , `create:<module>:test` , `create:<module>:view` .
2025-12-14 23:10:01 +00:00
* Utility commands: `test[:<module>]` , `run` , `db:backup` , `db:restore` .
* Acceptance:
* Commands generate files with correct namespaces/paths and pass basic smoke tests.
## M10 — Security middleware and auth primitives
* Tasks:
* Add CORS, Secure Headers middlewares; optional CSRF for template routes.
* JWT support (lcobucci/jwt) with simple token issue/verify service.
* Configuration for CORS origins, headers, methods.
* Bind FeatureFlagClientInterface with a default adapter (Flagpole); add small sample usage and env config.
* Acceptance:
* CORS preflight and secured endpoints behave as configured; JWT‑ protected route example works.
## M11 — Logging, HTTP client, and filesystem
* Tasks:
* Monolog setup with handlers and processors (request ID, memory, timing).
* Guzzle PSR‑ 18 client exposure; DI binding for HTTP client interface.
* Flysystem integration with local adapter; abstraction for storage disks.
* Acceptance:
* Logs include correlation IDs; sample outbound HTTP call via client; file upload/storage demo works.
## M12 — Serialization/validation utilities and pagination
* Tasks:
* REST default: Symfony Serializer normalizers/encoders; document extension points.
* Add simple validation layer (pick spec or integrate later if preferred; at minimum, input filtering and error shape alignment with Problem Details).
* Pagination helpers (links/meta), REST and JSON:API compatible outputs.
Implement M5 service providers, M6 MVC bases, and URL extension negotiation; update docs and tests
• M5: Add ServiceProviderInterface and ProviderRepository; integrate providers into Kernel (register before container build, boot after); add RouteRegistry with clear(); add default core providers (Routing, Template, ORM, Flags, Testing) and AppServiceProvider; add contracts and default drivers (Template/Eyrie, Orm/Pairity, Flags/Flagpole, Testing/Codeception)
• Routing: allow providers to contribute routes; add ProviderRouteTest
• Config: add config/providers.php; extend config/app.php with driver keys; document env keys
• M6: Introduce MVC bases: Controller, APIController (JSON helpers), ViewController (html + renderView helpers), View (transformData + renderer); add ViewWithDefaultTemplate and default-template flow; adjust method signatures to data-first and delegate template override to View
• HTTP: Add UrlExtensionNegotiationMiddleware (opt-in via URL_EXTENSION_NEGOTIATION, whitelist via URL_EXTENSION_WHITELIST with default json|php|none); wire before ContentNegotiationMiddleware
• Tests: add UrlExtensionNegotiationTest and MvcViewTest; ensure RouteRegistry::clear prevents duplicate routes in tests
• Docs: Update README with M5 provider usage, M6 MVC examples and template selection conventions, and URL extension negotiation; mark M5 complete in MILESTONES; add M12 task to provide XML support and enable xml in whitelist by default
2025-12-15 22:08:57 +00:00
* URL extension negotiation: add XML support
* Provide `XmlResponseFactory` (or encoder) and integrate with negotiation.
* Enable `xml` in `URL_EXTENSION_WHITELIST` by default.
2025-12-14 23:10:01 +00:00
* Acceptance:
* Example endpoint validates input, returns 422 with details; paginated listing includes links/meta.
## M13 — OpenAPI and documentation
* Tasks:
* Integrate `zircote/swagger-php` annotations.
* CLI/task to generate OpenAPI JSON; optional serve route and Redoc UI pointer.
* Document auth, pagination, error formats.
* Acceptance:
* Generated OpenAPI document validates; matches sample endpoints.
## M14 — Testing, quality, and DX
* Tasks:
* Establish testing structure with Codeception (unit, integration, API suites).
* Add fixtures/factories via Faker for examples.
* PHPStan level selection and baseline; code style via php-cs-fixer ruleset.
* Pre‑ commit hooks (e.g., GrumPHP) optional.
* Define TestRunnerInterface and a Codeception adapter; otherwise, state tests are run via Composer script only.
* Acceptance:
* `composer test` runs green across suites; static analysis passes.
* CLI tests run via TestRunnerInterface;
* CLI tests run green per module and across suites.
## M15 — Caching and performance (optional default)
* Tasks:
* Provide `PSR-16` cache interface binding; suggest `symfony/cache` when enabled.
* Simple response caching middleware and ETag/Last‑ Modified helpers.
* Rate limiting middleware (token bucket) suggestion/integration point.
* Acceptance:
* Sample endpoint demonstrates cached responses and conditional requests.
## M16 — Production hardening and deployment
* Tasks:
* Config for envs (dev/test/stage/prod), error verbosity, trusted proxies/hosts.
* Docker example, PHP‑ FPM + Nginx config templates.
* Healthcheck endpoint, readiness/liveness probes.
* Acceptance:
* Containerized demo serves both API and template pages; healthchecks pass.
## M17 — JSON:API enhancements (optional package)
* Tasks:
* If enabled, integrate `neomerx/json-api` fully: includes, sparse fieldsets, relationships, sorting, filtering, pagination params.
* Adapters/Schema providers per resource type.
* Acceptance:
* JSON:API conformance tests for selected endpoints pass; docs updated.
## M18 — Examples and starter template
* Tasks:
* Create `examples/blog` module showcasing controllers, views, templates, ORM, auth, pagination, and both API formats.
* Provide `composer create-project` skeleton template instructions.
* Acceptance:
* New users can scaffold a working app in minutes following README.
## M19 — Documentation site
* Tasks:
* Expand README into a docs site (MkDocs or similar): getting started, concepts, reference, guides.
* Versioned docs and upgrade notes.
* Acceptance:
* Docs published; links in README; examples maintained.
## M20 — Governance and roadmap tracking
* Tasks:
* Define contribution guide, issue templates, RFC process for changes.
* Public roadmap (this milestone list) tracked as GitHub Projects/Issues.
* Acceptance:
* Contributors can propose features via RFC; roadmap is visible and updated.
## Notes on sequencing and parallelization
* M0– M4 are critical path for the HTTP core and should be completed sequentially.
* M5– M8 can progress in parallel with M9 (CLI) once the kernel is stable.
* Optional tracks (M15, M17) can be deferred without blocking core usability.