Created intent related libraries - #20
Conversation
9603bdf to
ea02826
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new Intent component for temporarily storing “intents” (serializable objects) between stateless requests, along with a Symfony bundle that wires the storage and maintenance command into Symfony applications. It also adds end-user documentation for the component/bundle and updates monorepo Composer/dependency metadata accordingly.
Changes:
- Add
runopencode/intentcomponent: storage contract, DBAL and PSR-6 cache storage implementations, exceptions, and tests. - Add
runopencode/intent-bundleSymfony bundle: configuration, service wiring, schema listener registration, and bundle tests. - Add Sphinx docs for the new component/bundle and update monorepo Composer/dependency files.
Reviewed changes
Copilot reviewed 30 out of 32 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| src/RunOpenCode/Component/Intent/tests/Storage/DbalStorageTest.php | Adds storage conformance test for DBAL-backed intent storage. |
| src/RunOpenCode/Component/Intent/tests/Storage/CacheStorageTest.php | Adds storage conformance test for PSR-6 cache-backed intent storage. |
| src/RunOpenCode/Component/Intent/tests/Command/ClearExpiredIntentsCommandTest.php | Adds tests for the maintenance console command behavior. |
| src/RunOpenCode/Component/Intent/tests/AbstractIntentStorageTestBase.php | Defines shared test suite for any IntentStorageInterface implementation. |
| src/RunOpenCode/Component/Intent/src/Storage/DbalStorage.php | Implements intent persistence in a DB table via Doctrine DBAL. |
| src/RunOpenCode/Component/Intent/src/Storage/CacheStorage.php | Implements intent persistence in a PSR-6 cache pool. |
| src/RunOpenCode/Component/Intent/src/Exception/RuntimeException.php | Adds base runtime exception type for the component. |
| src/RunOpenCode/Component/Intent/src/Exception/NotExistsException.php | Adds “intent not found/available” exception type. |
| src/RunOpenCode/Component/Intent/src/Exception/ExceptionInterface.php | Adds marker interface for component exceptions. |
| src/RunOpenCode/Component/Intent/src/Contract/IntentStorageInterface.php | Defines storage contract for storing/fetching/invalidating/maintenance. |
| src/RunOpenCode/Component/Intent/src/Command/ClearExpiredIntentsCommand.php | Adds console command intended to run storage maintenance. |
| src/RunOpenCode/Component/Intent/README.md | Adds component README (currently placeholder in diff). |
| src/RunOpenCode/Component/Intent/composer.json | Adds component package metadata and dependencies. |
| src/RunOpenCode/Component/Intent/composer-require-checker.json | Adds require-checker whitelist for optional symbols used by the component. |
| src/RunOpenCode/Bundle/IntentBundle/tests/IntentBundleTest.php | Adds Symfony DI extension tests for bundle wiring. |
| src/RunOpenCode/Bundle/IntentBundle/src/IntentBundle.php | Implements bundle config, service registration, and Doctrine type/schema integration. |
| src/RunOpenCode/Bundle/IntentBundle/README.md | Adds bundle README (currently placeholder in diff). |
| src/RunOpenCode/Bundle/IntentBundle/composer.json | Adds bundle package metadata and dependencies. |
| src/RunOpenCode/Bundle/IntentBundle/composer-require-checker.json | Adds require-checker whitelist for optional symbols used by the bundle. |
| phplib.iml | Updates IDE module configuration to include new component/bundle sources and exclusions. |
| docs/source/components/query/index.rst | Tweaks an example connection name in Query component docs. |
| docs/source/components/intent/usage.rst | Adds Intent “Usage” documentation, including command usage section. |
| docs/source/components/intent/storages.rst | Adds Intent storage documentation for DBAL and cache storages. |
| docs/source/components/intent/installation.rst | Adds Intent installation and setup documentation. |
| docs/source/components/intent/index.rst | Adds Intent component landing page and ToC. |
| docs/source/components/index.rst | Adds Intent component to components documentation index. |
| docs/source/bundles/intent-bundle/index.rst | Adds Intent bundle documentation (installation/configuration/usage). |
| docs/source/bundles/index.rst | Adds Intent bundle to bundles documentation index. |
| composer.lock | Updates locked dependencies to include new required packages (e.g., ORM/Console/UID). |
| composer.json | Updates monorepo requirements and PSR-4 mappings for new component/bundle. |
| .php-cs-fixer.cache | Updates PHP-CS-Fixer cache after new/changed files. |
Suppressed comments (4)
src/RunOpenCode/Component/Intent/src/Storage/DbalStorage.php:75
- $tableName is interpolated directly into SQL (SELECT/DELETE) without identifier quoting. If a custom table name contains special characters/reserved words (or is misconfigured), this can break queries; quoting the identifier also avoids accidental SQL injection via configuration.
$row = $this->connection->executeQuery(\sprintf(
'SELECT * FROM %s WHERE id = :id LIMIT 1',
$this->tableName,
), [
src/RunOpenCode/Component/Intent/src/Contract/IntentStorageInterface.php:40
- Grammar: "does not exists" should be "does not exist".
* Invalidates intent with given identifier. Does not throw exception
* if intent with given identifier does not exists.
*/
src/RunOpenCode/Component/Intent/src/Storage/DbalStorage.php:132
- invalidate(): the SQL interpolates $tableName without identifier quoting, and uses executeQuery() for a DELETE. Quote the table identifier and use executeStatement() for DML.
$this->connection->executeQuery(\sprintf('DELETE FROM %s WHERE id = :id', $this->tableName), [
'id' => $identifier,
], [
'id' => UlidType::NAME,
]);
src/RunOpenCode/Component/Intent/src/Storage/DbalStorage.php:144
- maintenance(): the SQL interpolates $tableName without identifier quoting, and uses executeQuery() for a DELETE. Quote the table identifier and use executeStatement() for DML.
$this->connection->executeQuery(\sprintf('DELETE FROM %s WHERE expires_at <= :now', $this->tableName), [
'now' => new \DateTimeImmutable('now'),
], [
'now' => Types::DATETIME_IMMUTABLE,
]);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } catch (\Exception) { | ||
| $io->error('Unable to clear expired contents.'); | ||
| return Command::FAILURE; |
| private function getCommand(IntentStorageInterface $storage): Command | ||
| { | ||
| return new Command('runopencode:intent:maintenance') | ||
| ->setCode(new ClearExpiredIntentsCommand($storage)); | ||
| } |
| use Doctrine\DBAL\Connection; | ||
| use Doctrine\DBAL\Platforms\MySQLPlatform; | ||
| use Doctrine\DBAL\Schema\PrimaryKeyConstraint; | ||
| use Doctrine\DBAL\Types\Type; | ||
| use Doctrine\DBAL\Types\Types; |
|
|
||
| $application = new Application(); | ||
|
|
||
| $application->addCommand(new ClearExpiredIntentsCommand($storage)); |
| use RunOpenCode\Component\Intent\Storage\CacheStorage; | ||
| use Symfony\Component\Cache\Adapter\RedisAdapter; | ||
|
|
||
| $storage = new CacheStorage(RedisAdapter::createConnection('redis://localhost')); |
| * Thrown when one resource does not exists. | ||
| */ |
| * @param Ulid $identifier Identifier for which intent should be fetched. | ||
| * @param bool $invalidate Should intent be invalidated after fetch. Defaults to TRUE. | ||
| * |
| @@ -0,0 +1 @@ | |||
| TODO No newline at end of file | |||
| @@ -0,0 +1 @@ | |||
| TODO No newline at end of file | |||
| // noop | ||
| } | ||
|
|
||
| public function __invoke(SymfonyStyle $io): int |
No description provided.