diff --git a/.continue/rules/controller-feature-folder-structure.md b/.continue/rules/controller-feature-folder-structure.md new file mode 100644 index 0000000..e4368e3 --- /dev/null +++ b/.continue/rules/controller-feature-folder-structure.md @@ -0,0 +1,9 @@ +--- +globs: UI/Controller/**/*.php +description: When creating new controllers in the UI/Controller directory, a + corresponding feature subfolder should be created to organize related + controller files +alwaysApply: true +--- + +All controllers in the UI/Controller directory must be placed within feature-specific subdirectories \ No newline at end of file diff --git a/.continue/rules/data-layer-file-placement.md b/.continue/rules/data-layer-file-placement.md new file mode 100644 index 0000000..54dd954 --- /dev/null +++ b/.continue/rules/data-layer-file-placement.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/** +description: This rule ensures that all implementation files belonging to the + Data layer are consistently organized under the /src/Data directory structure, + maintaining clear separation between Logic and Data layers. +alwaysApply: true +--- + +All files in the Data layer must be placed within the /src/Data directory \ No newline at end of file diff --git a/.continue/rules/doctrine-repository-best-practices.md b/.continue/rules/doctrine-repository-best-practices.md new file mode 100644 index 0000000..329418e --- /dev/null +++ b/.continue/rules/doctrine-repository-best-practices.md @@ -0,0 +1,7 @@ +--- +globs: '["**/Data/**/*Repository.php"]' +description: Prevents the common error of using invalid Doctrine ORM attributes + in Repository classes +--- + +When creating Doctrine repositories, NEVER use #[ORM\EntityManager] as this is not a valid Doctrine mapping attribute and causes runtime errors. Repositories must only be instantiated via Dependency Injection with EntityManagerInterface in their constructor. Valid ORM attributes for Repositories include: none (standard), or optionally #[ORM\HasEntityListeners] if needed. Mapping attributes like #[ORM\Entity], #[ORM\Table], #[ORM\JoinColumn] are ONLY for Entity classes, not Repository classes. \ No newline at end of file diff --git a/.continue/rules/dto-location-rule.md b/.continue/rules/dto-location-rule.md new file mode 100644 index 0000000..fd50aed --- /dev/null +++ b/.continue/rules/dto-location-rule.md @@ -0,0 +1,10 @@ +--- +globs: src/Logic/**/DTO/* +description: This rule ensures that all DTO (Data Transfer Object) files are + correctly placed within the Logic layer according to the feature-based + architecture, with proper naming conventions for feature directories and clear + separation of data transfer objects. +alwaysApply: true +--- + +All DTO files in the Logic layer must be placed within /src/Logic/[FeatureName]/DTO directory, where [FeatureName] is a valid feature-specific subdirectory. If the FeatureName is unknown or ambiguous, developers must actively provide a proper feature name rather than defaulting to 'Unknown'. \ No newline at end of file diff --git a/.continue/rules/entity-directory-structure-with-feature-validation.md b/.continue/rules/entity-directory-structure-with-feature-validation.md new file mode 100644 index 0000000..6c0fff9 --- /dev/null +++ b/.continue/rules/entity-directory-structure-with-feature-validation.md @@ -0,0 +1,11 @@ +--- +globs: src/Data/*/Entity/*.php +description: This rule enforces that entities are placed in feature-specific + directories under /src/Data/[FeatureName]/Entity. When [FeatureName] is + unknown or ambiguous, the developer must select an appropriate feature name + instead of automatically using a default 'Unknown' directory to maintain + proper architecture and code organization. +alwaysApply: true +--- + +All entities must be located in /src/Data/[FeatureName]/Entity directory, where [FeatureName] is a valid feature-specific subdirectory. If the feature name cannot be determined, developers must actively provide a proper feature name rather than defaulting to 'Unknown'. This ensures consistent architectural separation. \ No newline at end of file diff --git a/.continue/rules/entity-directory-structure-with-php-attributes.md b/.continue/rules/entity-directory-structure-with-php-attributes.md new file mode 100644 index 0000000..3b83e8c --- /dev/null +++ b/.continue/rules/entity-directory-structure-with-php-attributes.md @@ -0,0 +1,11 @@ +--- +globs: src/Data/*/Entity/*.php +description: This rule enforces proper entity organization in the Data layer + with clear separation by feature. It mandates usage of modern PHP attributes + for Doctrine mappings instead of annotations to align with contemporary PHP + standards and Symfony best practices. When feature names cannot be determined, + explicit developer decisions are required rather than automatic defaults. +alwaysApply: true +--- + +All entities must be placed in /src/Data/[FeatureName]/Entity directory, where [FeatureName] represents a valid feature-specific subdirectory. Entities must use modern PHP attributes (not annotations) for Doctrine mapping. When the FeatureName is unknown or ambiguous, developers must actively select an appropriate feature name rather than defaulting to 'Unknown'. \ No newline at end of file diff --git a/.continue/rules/entity-directory-structure.md b/.continue/rules/entity-directory-structure.md new file mode 100644 index 0000000..a8f8bd7 --- /dev/null +++ b/.continue/rules/entity-directory-structure.md @@ -0,0 +1,10 @@ +--- +globs: src/Data/*/Entity/*.php +description: This rule ensures consistent entity placement within the + feature-based architecture by requiring entities to be stored in a specific + directory structure under /src/Data/[FeatureName]/Entity, with proper Doctrine + configuration for each directory. +alwaysApply: true +--- + +All entities must be located in /src/Data/[FeatureName]/Entity directory, where [FeatureName] is the feature-specific subdirectory. If [FeatureName] is unknown, use "Unknown" as the directory name. \ No newline at end of file diff --git a/.continue/rules/feature-based-architecture-rules.md b/.continue/rules/feature-based-architecture-rules.md new file mode 100644 index 0000000..8230a7a --- /dev/null +++ b/.continue/rules/feature-based-architecture-rules.md @@ -0,0 +1,9 @@ +--- +globs: src/**/*.php +description: Enforce architectural rules for Feature-Based Development including + repository interface definition in Logic layer, implementations in Data layer, + and proper data flow through Services using DTOs. +alwaysApply: true +--- + +Follow feature-based architecture with clear separation between Logic, Data, and Shared layers \ No newline at end of file diff --git a/.continue/rules/feature-name-validation-for-entities.md b/.continue/rules/feature-name-validation-for-entities.md new file mode 100644 index 0000000..4c62d4d --- /dev/null +++ b/.continue/rules/feature-name-validation-for-entities.md @@ -0,0 +1,10 @@ +--- +globs: src/Data/*/Entity/*.php +description: This rule requires that when entities are created and the feature + name cannot be determined, instead of defaulting to an 'Unknown' directory, + developers must actively select or define a proper feature name to maintain + clean architectural separation. +alwaysApply: true +--- + +When creating entities, if [FeatureName] is unknown, prompt the user to provide a feature name rather than automatically using 'Unknown'. This ensures proper categorization of entities within the feature-based architecture. \ No newline at end of file diff --git a/.continue/rules/logic-layer-file-placement.md b/.continue/rules/logic-layer-file-placement.md new file mode 100644 index 0000000..52c968a --- /dev/null +++ b/.continue/rules/logic-layer-file-placement.md @@ -0,0 +1,9 @@ +--- +globs: src/Logic/** +description: This rule ensures that all implementation files belonging to the + Logic layer are consistently organized under the /src/Logic directory + structure, maintaining clear separation between Logic and other layers. +alwaysApply: true +--- + +All files in the Logic layer must be placed within the /src/Logic directory \ No newline at end of file diff --git a/.continue/rules/manager-location-rule.md b/.continue/rules/manager-location-rule.md new file mode 100644 index 0000000..3e70ea8 --- /dev/null +++ b/.continue/rules/manager-location-rule.md @@ -0,0 +1,11 @@ +--- +globs: src/Logic/**/Manager/* +description: This rule ensures that all manager implementations are correctly + placed within the Logic layer according to the feature-based architecture, + with proper naming conventions for feature directories. Managers serve as + orchestration layers that expose Provider and Processor methods while + implementing caching. +alwaysApply: true +--- + +All manager implementations must be located in the Logic layer under feature-specific subdirectories: /src/Logic/[FeatureName]/Manager. Feature names must be properly capitalized and follow the PascalCase convention. Managers expose methods from Providers and Processors and implement caching functionality. \ No newline at end of file diff --git a/.continue/rules/mapper-location-rule.md b/.continue/rules/mapper-location-rule.md new file mode 100644 index 0000000..e0aeda9 --- /dev/null +++ b/.continue/rules/mapper-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/**/Mapper/* +description: This rule ensures that all mapper implementations are correctly + placed within the Data layer according to the feature-based architecture, with + proper naming conventions for feature directories. +alwaysApply: true +--- + +All mapper implementations must be located in the Data layer under feature-specific subdirectories: /src/Data/[FeatureName]/Mapper. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/minimal-comments-rule.md b/.continue/rules/minimal-comments-rule.md new file mode 100644 index 0000000..809db4c --- /dev/null +++ b/.continue/rules/minimal-comments-rule.md @@ -0,0 +1,10 @@ +--- +globs: "**/*.php" +description: Comments should only be used for complex logic, business rules, + non-obvious decisions, or explanations of why something is done (not what is + done). Code should be readable without comments. Remove all unnecessary + comments that don't add value to understanding the code. +alwaysApply: true +--- + +Only add comments when they provide essential clarification that the code itself cannot convey. Avoid redundant or obvious comments; let code be self-documenting through clear naming and structure. \ No newline at end of file diff --git a/.continue/rules/model-directory-structure.md b/.continue/rules/model-directory-structure.md new file mode 100644 index 0000000..b9103d9 --- /dev/null +++ b/.continue/rules/model-directory-structure.md @@ -0,0 +1,10 @@ +--- +globs: src/Logic/**/Models/*.php +description: This rule ensures consistent architectural separation by placing + all model files in their respective feature-specific directories within the + Logic layer. It prevents improper placement of models and enforces clear + organization based on features. +alwaysApply: true +--- + +All model files in the Logic layer must be placed within /src/Logic/[FeatureName]/Models directory, where [FeatureName] is a valid feature-specific subdirectory. If the FeatureName is unknown or ambiguous, developers must actively provide a proper feature name rather than defaulting to 'Unknown'. \ No newline at end of file diff --git a/.continue/rules/model-location-rule.md b/.continue/rules/model-location-rule.md new file mode 100644 index 0000000..7a6fdb3 --- /dev/null +++ b/.continue/rules/model-location-rule.md @@ -0,0 +1,10 @@ +--- +globs: src/Logic/**/Models/* +description: This rule ensures that all model files are correctly placed within + the Logic layer according to the feature-based architecture, with proper + naming conventions for feature directories and clear separation of business + logic models. +alwaysApply: true +--- + +All model files in the Logic layer must be placed within /src/Logic/[FeatureName]/Models directory, where [FeatureName] is a valid feature-specific subdirectory. If the FeatureName is unknown or ambiguous, developers must actively provide a proper feature name rather than defaulting to 'Unknown'. \ No newline at end of file diff --git a/.continue/rules/no-closing-php-tag.md b/.continue/rules/no-closing-php-tag.md new file mode 100644 index 0000000..21459d8 --- /dev/null +++ b/.continue/rules/no-closing-php-tag.md @@ -0,0 +1,8 @@ +--- +globs: "**/*.php" +description: In PHP files, omit the closing ?> tag to prevent issues with + whitespace and ensure consistent file handling +alwaysApply: true +--- + +Do not include the closing PHP tag (?>) at the end of PHP files \ No newline at end of file diff --git a/.continue/rules/processor-interface-location-rule.md b/.continue/rules/processor-interface-location-rule.md new file mode 100644 index 0000000..f996268 --- /dev/null +++ b/.continue/rules/processor-interface-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Logic/**/Processor/* +description: This rule ensures that all processor interface definitions are + correctly placed within the Logic layer according to the feature-based + architecture, with proper naming conventions for feature directories. +alwaysApply: true +--- + +All processor interfaces must be located in the Logic layer under feature-specific subdirectories: /src/Logic/[FeatureName]/Processor. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/processor-location-rule.md b/.continue/rules/processor-location-rule.md new file mode 100644 index 0000000..60df044 --- /dev/null +++ b/.continue/rules/processor-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/**/Processor/* +description: This rule ensures that all processor implementations are correctly + placed within the Data layer according to the feature-based architecture, with + proper naming conventions for feature directories. +alwaysApply: true +--- + +All processor implementations must be located in the Data layer under feature-specific subdirectories: /src/Data/[FeatureName]/Processor. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/provider-and-processor-model-usage.md b/.continue/rules/provider-and-processor-model-usage.md new file mode 100644 index 0000000..1b7eadc --- /dev/null +++ b/.continue/rules/provider-and-processor-model-usage.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/**/*{Provider,Processor}.php +description: Ensure that data providers and processors in the Data layer depend + exclusively on models defined in the Logic layer's Models directory, + maintaining proper architectural separation between layers +alwaysApply: true +--- + +Providers and Processors in the Data layer must only use models from the Logic layer's Models directory \ No newline at end of file diff --git a/.continue/rules/provider-interface-location-rule.md b/.continue/rules/provider-interface-location-rule.md new file mode 100644 index 0000000..1102905 --- /dev/null +++ b/.continue/rules/provider-interface-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Logic/**/Provider/* +description: This rule ensures that all provider interface definitions are + correctly placed within the Logic layer according to the feature-based + architecture, with proper naming conventions for feature directories. +alwaysApply: true +--- + +All provider interfaces must be located in the Logic layer under feature-specific subdirectories: /src/Logic/[FeatureName]/Provider. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/provider-location-rule.md b/.continue/rules/provider-location-rule.md new file mode 100644 index 0000000..643aa83 --- /dev/null +++ b/.continue/rules/provider-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/**/Provider/* +description: This rule ensures that all provider implementations are correctly + placed within the Data layer according to the feature-based architecture, with + proper naming conventions for feature directories. +alwaysApply: true +--- + +All provider implementations must be located in the Data layer under feature-specific subdirectories: /src/Data/[FeatureName]/Provider. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/provider-processor-repository-relationship-rule.md b/.continue/rules/provider-processor-repository-relationship-rule.md new file mode 100644 index 0000000..31172fd --- /dev/null +++ b/.continue/rules/provider-processor-repository-relationship-rule.md @@ -0,0 +1,9 @@ +--- +description: This rule describes the architectural relationships between + components in your Symfony application, clarifying how Providers and + Processors interact with data sources and how they relate to repository + patterns and integration APIs. +alwaysApply: true +--- + +Providers deliver data to the Logic layer. Processors write data. The Logic layer defines requirements through interfaces. Providers and Processors can utilize repositories or integration APIs for data access. \ No newline at end of file diff --git a/.continue/rules/repository-implementation-location.md b/.continue/rules/repository-implementation-location.md new file mode 100644 index 0000000..06db8ae --- /dev/null +++ b/.continue/rules/repository-implementation-location.md @@ -0,0 +1,8 @@ +--- +globs: src/Features/*/Data/Repository/*.php +description: The Data layer handles concrete storage mechanisms while keeping + business logic unaware of these details. +alwaysApply: true +--- + +Repository implementations must be located in the Data layer, using entities for persistence. \ No newline at end of file diff --git a/.continue/rules/repository-interface-definition-location.md b/.continue/rules/repository-interface-definition-location.md new file mode 100644 index 0000000..e662b68 --- /dev/null +++ b/.continue/rules/repository-interface-definition-location.md @@ -0,0 +1,8 @@ +--- +globs: src/Features/*/Logic/Repository/*.php +description: Ensures that business logic is decoupled from data access + implementation details, promoting flexibility and testability. +alwaysApply: true +--- + +Repository interfaces must be defined in the Logic layer, not in the Data layer. \ No newline at end of file diff --git a/.continue/rules/repository-location-rule.md b/.continue/rules/repository-location-rule.md new file mode 100644 index 0000000..44501e3 --- /dev/null +++ b/.continue/rules/repository-location-rule.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/**/Repository/* +description: This rule ensures that all repository implementations are correctly + placed within the Data layer according to the feature-based architecture, with + proper naming conventions for feature directories. +alwaysApply: true +--- + +All repository implementations must be located in the Data layer under feature-specific subdirectories: /src/Data/[FeatureName]/Repository. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/repository-location.md b/.continue/rules/repository-location.md new file mode 100644 index 0000000..f89a1d5 --- /dev/null +++ b/.continue/rules/repository-location.md @@ -0,0 +1,9 @@ +--- +globs: src/Data/*/Repository/*.php +description: Enforce consistent placement of repository implementations within + feature-specific directories in the Data layer, ensuring proper organization + by feature name. +alwaysApply: true +--- + +All repository implementations must be located in the Data layer under feature-specific subdirectories: /src/Data/[FeatureName]/Repository. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/repository-pattern.md b/.continue/rules/repository-pattern.md new file mode 100644 index 0000000..8a0c8d5 --- /dev/null +++ b/.continue/rules/repository-pattern.md @@ -0,0 +1,9 @@ +--- +globs: "**/Repository/*.php,**/Data/**/*Repository*.php,**/Logic/**/*Repository*.php" +description: Enforce clear separation between Logic, Data, and Shared layers by + ensuring proper placement of repositories according to domain-driven design + principles. +alwaysApply: true +--- + +All repository implementations must be located in the Data layer and use entities for persistence. Repository interfaces must be defined in the Logic layer, not in the Data layer. Services in the Logic layer must depend on repository interfaces defined in their respective Logic folder. \ No newline at end of file diff --git a/.continue/rules/request-handling-in-controllers.md b/.continue/rules/request-handling-in-controllers.md new file mode 100644 index 0000000..1fdf272 --- /dev/null +++ b/.continue/rules/request-handling-in-controllers.md @@ -0,0 +1,10 @@ +--- +globs: src/UI/**/*.php +description: Defines best practices for handling HTTP requests in Symfony 7. + Ensures strict separation of concerns by transforming raw request data into + immutable DTOs at the boundary of the UI layer, preventing leakage of + infrastructure details into business logic. +alwaysApply: true +--- + +The Request object must only be used in the UI layer (Controllers). Immediately convert request data into DTOs located in /src/Logic/[FeatureName]/DTO before passing them to UseCases. Use $request->getPayload() for JSON APIs, $request->query/request for forms, and $request->attributes for route parameters. Never pass the Request object to Logic or Data layers. \ No newline at end of file diff --git a/.continue/rules/service-dependency-on-repository-interfaces.md b/.continue/rules/service-dependency-on-repository-interfaces.md new file mode 100644 index 0000000..a7101ac --- /dev/null +++ b/.continue/rules/service-dependency-on-repository-interfaces.md @@ -0,0 +1,8 @@ +--- +globs: src/Features/*/Logic/Service/*.php +description: This enforces dependency inversion, allowing for easy mocking and + testing without touching actual data sources. +alwaysApply: true +--- + +Services in the Logic layer must depend on repository interfaces defined in their respective Logic folder. \ No newline at end of file diff --git a/.continue/rules/shared-components-location.md b/.continue/rules/shared-components-location.md new file mode 100644 index 0000000..f1541b8 --- /dev/null +++ b/.continue/rules/shared-components-location.md @@ -0,0 +1,7 @@ +--- +globs: src/Shared/**/*.php +description: Reduces duplication and promotes consistency throughout the application. +alwaysApply: true +--- + +Common components like DTOs, Interfaces, Helpers, and Exceptions are placed in the Shared layer for reuse across features. \ No newline at end of file diff --git a/.continue/rules/shared-layer-file-placement.md b/.continue/rules/shared-layer-file-placement.md new file mode 100644 index 0000000..818f564 --- /dev/null +++ b/.continue/rules/shared-layer-file-placement.md @@ -0,0 +1,10 @@ +--- +globs: src/Shared/** +description: This rule ensures that all cross-cutting implementation files + belonging to the Shared layer are consistently organized under the /src/Shared + directory structure, maintaining clear separation between shared components + and feature-specific layers. +alwaysApply: true +--- + +All files in the Shared layer must be placed within the /src/Shared directory \ No newline at end of file diff --git a/.continue/rules/simplify-repository-usage.md b/.continue/rules/simplify-repository-usage.md new file mode 100644 index 0000000..e73c070 --- /dev/null +++ b/.continue/rules/simplify-repository-usage.md @@ -0,0 +1,22 @@ +--- +globs: '["src/**/*Repository.php"]' +description: Ensures minimal boilerplate by avoiding unnecessary custom + Repository classes for standard CRUD operations, while still allowing them for + complex queries. +alwaysApply: true +--- + +In Symfony and Doctrine based applications, avoid creating custom Repository classes for simple CRUD or standard query operations (e.g., findOneBy, findBy). Instead, use Doctrine's native EntityRepository directly via $entityManager->getRepository(Entity::class) within the Provider or Processor implementations. + +Only create a custom repository when: +1. Complex queries involving multiple joins, subselects, or specialized search logic are required. +2. Query logic is reused across multiple Providers/Processors and warrants encapsulation for DRY compliance. + +When no custom repository is needed, Inject EntityManagerInterface directly into the Provider or Processor and fetch the repository inline as shown below: + +```php +$repository = $this->entityManager->getRepository(EntityClass::class); +$result = $repository->findOneBy(['id' => $id]); +``` + +Do not create an empty or wrapper Repository class that only delegates to Doctrine's native methods. \ No newline at end of file diff --git a/.continue/rules/symfony-74-request-handling.md b/.continue/rules/symfony-74-request-handling.md new file mode 100644 index 0000000..aa44bd1 --- /dev/null +++ b/.continue/rules/symfony-74-request-handling.md @@ -0,0 +1,8 @@ +k--- +globs: "**/UI/**/*Controller*.php" +description: Ensures compliance with Symfony 7.4 deprecations and enforces + strict separation of concerns by isolating Request handling to the UI layer. +alwaysApply: true +--- + +In Symfony 7.4+, never use the deprecated `Request::get()` method. Instead, use `$request->attributes` for route parameters, `$request->query` for query parameters, and `$request->getPayload()` for body data (JSON/Forms). Immediately convert request data into DTOs in Controllers. Never pass the Request object to Logic or Data layers. \ No newline at end of file diff --git a/.continue/rules/symfony-dto-validation-strategy.md b/.continue/rules/symfony-dto-validation-strategy.md new file mode 100644 index 0000000..061e9a8 --- /dev/null +++ b/.continue/rules/symfony-dto-validation-strategy.md @@ -0,0 +1,11 @@ +--- +globs: "**/UI/**/*.php, **/Logic/**/DTO/*.php" +description: Defines the standard for input validation in Symfony 7 projects. + Logic layer DTOs hold the validation rules via attributes. The UI layer is + responsible for executing the validation using the injected validator service, + ensuring clean separation of concerns and preventing invalid data from + entering the business logic. +alwaysApply: false +--- + +All input validation must be performed on DTOs located in /src/Logic/[FeatureName]/DTO using PHP 8 #[Assert\...] attributes. Controllers in the UI layer (/src/UI/...) must inject Symfony\Component\Validator\Validator\ValidatorInterface, validate the DTO before passing it to UseCases, and handle validation errors immediately. \ No newline at end of file diff --git a/.continue/rules/ui-layer-file-placement.md b/.continue/rules/ui-layer-file-placement.md new file mode 100644 index 0000000..0e31f26 --- /dev/null +++ b/.continue/rules/ui-layer-file-placement.md @@ -0,0 +1,9 @@ +--- +globs: src/UI/** +description: This rule ensures that all implementation files belonging to the UI + layer are consistently organized under the /src/UI directory structure, + maintaining clear separation between UI and other layers. +alwaysApply: true +--- + +All files in the UI layer must be placed within the /src/UI directory \ No newline at end of file diff --git a/.continue/rules/ui-layer-separation.md b/.continue/rules/ui-layer-separation.md new file mode 100644 index 0000000..541c8f2 --- /dev/null +++ b/.continue/rules/ui-layer-separation.md @@ -0,0 +1,9 @@ +--- +globs: "**/*.php" +description: Diese Regel stellt sicher, dass die UI-Schicht klar in Frontend, + API und CLI unterteilt ist, was die Wartbarkeit und Skalierbarkeit des + Projekts verbessert. +alwaysApply: true +--- + +Alle Dateien in der UI-Schicht müssen in feature-spezifische Unterverzeichnisse unter /src/UI platziert werden: /src/UI/Frontend, /src/UI/Api oder /src/UI/CLI. \ No newline at end of file diff --git a/.continue/rules/ui-layer-structure.md b/.continue/rules/ui-layer-structure.md new file mode 100644 index 0000000..4e37f1a --- /dev/null +++ b/.continue/rules/ui-layer-structure.md @@ -0,0 +1,10 @@ +--- +globs: src/UI/**/* +description: Ensures proper separation of concerns in the UI layer by organizing + controllers and related components into feature-specific subdirectories for + Frontend (web UI), Api (REST/GraphQL endpoints), and CLI (command-line + interface). This promotes clear architectural boundaries and maintainability. +alwaysApply: true +--- + +The UI layer must be divided into three subdirectories: Frontend, Api, and CLI under /src/UI. Controllers and related UI components must be organized into these respective subdirectories based on their purpose: Frontend for web UI controllers, Api for REST/GraphQL endpoints, and CLI for command-line interface commands. \ No newline at end of file diff --git a/.continue/rules/use-modern-php-attributes.md b/.continue/rules/use-modern-php-attributes.md new file mode 100644 index 0000000..b0cd648 --- /dev/null +++ b/.continue/rules/use-modern-php-attributes.md @@ -0,0 +1,10 @@ +--- +globs: "**/*.php" +description: Ensure all new code uses modern PHP attribute syntax rather than + legacy annotation syntax for better type safety and code clarity. This applies + to routing, validation, security, and other Symfony components that support + attributes. +alwaysApply: true +--- + +Always use PHP attributes instead of annotations for routing and other Symfony features in PHP 8+ projects \ No newline at end of file diff --git a/.continue/rules/use-symfony-http-status-constants.md b/.continue/rules/use-symfony-http-status-constants.md new file mode 100644 index 0000000..63bb697 --- /dev/null +++ b/.continue/rules/use-symfony-http-status-constants.md @@ -0,0 +1,9 @@ +--- +globs: "**/UI/**/*Controller*.php" +description: Improves code readability and maintainability by using + self-documenting constants instead of magic numbers for HTTP status codes. + Applies to all controllers in the UI layer and any response handling. +alwaysApply: true +--- + +Always use Symfony Response HTTP status constants (e.g., Response::HTTP_OK, Response::HTTP_CREATED, Response::HTTP_NOT_FOUND) instead of magic numbers (e.g., 200, 201, 404) when setting HTTP status codes in controllers and responses. \ No newline at end of file diff --git a/.continue/rules/usecase-input-via-dtos.md b/.continue/rules/usecase-input-via-dtos.md new file mode 100644 index 0000000..eb5965b --- /dev/null +++ b/.continue/rules/usecase-input-via-dtos.md @@ -0,0 +1,8 @@ +--- +globs: src/Logic/**/UseCase/*.php, src/Logic/**/DTO/*.php +description: Enforces the use of DTOs for UseCase entry points to maintain clean + architecture, immutability, and type safety. +alwaysApply: true +--- + +UseCase methods must accept DTOs (Data Transfer Objects) for input parameters instead of raw arrays or Request objects. DTOs must be located in the /src/Logic/[FeatureName]/DTO directory and should be immutable (readonly properties). This ensures decoupling between the Logic and UI layers. Simple primitive inputs (like a single ID) may be passed directly, but complex data structures require DTOs. \ No newline at end of file diff --git a/.continue/rules/usecase-location-rule.md b/.continue/rules/usecase-location-rule.md new file mode 100644 index 0000000..aacf344 --- /dev/null +++ b/.continue/rules/usecase-location-rule.md @@ -0,0 +1,10 @@ +--- +globs: src/Logic/**/UseCase/* +description: This rule ensures that all use case implementations are correctly + placed within the Logic layer according to the feature-based architecture, + with proper naming conventions for feature directories. Use cases represent + specific business logic operations. +alwaysApply: true +--- + +All use case implementations must be located in the Logic layer under feature-specific subdirectories: /src/Logic/[FeatureName]/UseCase. Feature names must be properly capitalized and follow the PascalCase convention. \ No newline at end of file diff --git a/.continue/rules/workflow-for-multiple-usecases.md b/.continue/rules/workflow-for-multiple-usecases.md new file mode 100644 index 0000000..db85e6a --- /dev/null +++ b/.continue/rules/workflow-for-multiple-usecases.md @@ -0,0 +1,10 @@ +--- +globs: src/Logic/**/*Controller.php, src/Logic/**/Manager/*.php +description: Workflows werden verwendet, wenn eine Controller-Aktion oder ein + Manager mehrere UseCases koordinieren muss. Dies sorgt für saubere Trennung + von Concerns, Wiederverwendbarkeit einzelner UseCases und bessere Testbarkeit. + Der Workflow definiert die Reihenfolge und Abhängigkeiten zwischen UseCases. +alwaysApply: false +--- + +Wenn mehrere UseCases kombiniert oder in einer bestimmten Reihenfolge ausgeführt werden müssen, ist ein Workflow zu verwenden. Workflows orchestrieren die Ausführung mehrerer UseCases und kapseln komplexe Geschäftsprozesse. Sie gehören in /src/Logic/[FeatureName]/Workflow und werden vom Manager aufgerufen, nicht direkt vom Controller. \ No newline at end of file diff --git a/composer.json b/composer.json index 67d871f..15ba27d 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,8 @@ "php": ">=8.4", "ext-ctype": "*", "ext-iconv": "*", + "symfony/ai-bundle": "^0.9.0", + "symfony/ai-ollama-platform": "*", "symfony/console": "8.1.*", "symfony/dotenv": "8.1.*", "symfony/flex": "^2", @@ -14,8 +16,6 @@ "symfony/runtime": "8.1.*", "symfony/yaml": "8.1.*" }, - "require-dev": { - }, "config": { "allow-plugins": { "php-http/discovery": true, diff --git a/composer.lock b/composer.lock index 01fe080..c6e1eb9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,331 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8f2d2bb175ffe409da49e7034d1f3a93", + "content-hash": "195e80116efda7da3c1470e3891dd63f", "packages": [ + { + "name": "doctrine/deprecations", + "version": "1.1.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=14" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" + }, + "time": "2026-02-07T07:09:04+00:00" + }, + { + "name": "oskarstark/enum-helper", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/OskarStark/enum-helper.git", + "reference": "14e185f1cc259d7cd3f61eea17f9b174a886a6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/OskarStark/enum-helper/zipball/14e185f1cc259d7cd3f61eea17f9b174a886a6da", + "reference": "14e185f1cc259d7cd3f61eea17f9b174a886a6da", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "phpunit/phpunit": "<10" + }, + "require-dev": { + "ergebnis/php-cs-fixer-config": "^6.58", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5", + "rector/rector": "^2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "OskarStark\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + } + ], + "description": "This library provides helpers for several enum operations", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/OskarStark/enum-helper/issues", + "source": "https://github.com/OskarStark/enum-helper/tree/1.8.4" + }, + "time": "2026-02-05T08:59:09+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", + "webmozart/assert": "^1.9.1 || ^2" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" + }, + "time": "2026-03-18T20:49:53+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" + }, + "time": "2026-01-06T21:53:42+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + }, + "time": "2026-01-25T14:56:51+00:00" + }, { "name": "psr/cache", "version": "3.0.0", @@ -55,6 +378,54 @@ }, "time": "2021-02-03T23:26:27+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "2.0.2", @@ -208,6 +579,382 @@ }, "time": "2024-09-11T13:17:53+00:00" }, + { + "name": "symfony/ai-bundle", + "version": "v0.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-bundle.git", + "reference": "77fd1b513174770acf49abd68effa995fa518f7c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-bundle/zipball/77fd1b513174770acf49abd68effa995fa518f7c", + "reference": "77fd1b513174770acf49abd68effa995fa518f7c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-platform": "^0.9", + "symfony/clock": "^7.3|^8.0", + "symfony/config": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dependency-injection": "^7.3|^8.0", + "symfony/framework-bundle": "^7.3|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.3|^8.0" + }, + "require-dev": { + "google/auth": "^1.47", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53", + "symfony/ai-agent": "^0.9", + "symfony/ai-ai-ml-api-platform": "^0.9", + "symfony/ai-albert-platform": "^0.9", + "symfony/ai-amazee-ai-platform": "^0.9", + "symfony/ai-anthropic-platform": "^0.9", + "symfony/ai-azure-platform": "^0.9", + "symfony/ai-azure-search-store": "^0.9", + "symfony/ai-bedrock-platform": "^0.9", + "symfony/ai-cache-message-store": "^0.9", + "symfony/ai-cache-platform": "^0.9", + "symfony/ai-cache-store": "^0.9", + "symfony/ai-cartesia-platform": "^0.9", + "symfony/ai-cerebras-platform": "^0.9", + "symfony/ai-chat": "^0.9", + "symfony/ai-chroma-db-store": "^0.9", + "symfony/ai-click-house-store": "^0.9", + "symfony/ai-cloudflare-message-store": "^0.9", + "symfony/ai-cloudflare-store": "^0.9", + "symfony/ai-cohere-platform": "^0.9", + "symfony/ai-decart-platform": "^0.9", + "symfony/ai-deep-seek-platform": "^0.9", + "symfony/ai-docker-model-runner-platform": "^0.9", + "symfony/ai-doctrine-message-store": "^0.9", + "symfony/ai-elasticsearch-store": "^0.9", + "symfony/ai-eleven-labs-platform": "^0.9", + "symfony/ai-failover-platform": "^0.9", + "symfony/ai-gemini-platform": "^0.9", + "symfony/ai-generic-platform": "^0.9", + "symfony/ai-hugging-face-platform": "^0.9", + "symfony/ai-lm-studio-platform": "^0.9", + "symfony/ai-manticore-search-store": "^0.9", + "symfony/ai-maria-db-store": "^0.9", + "symfony/ai-meilisearch-message-store": "^0.9", + "symfony/ai-meilisearch-store": "^0.9", + "symfony/ai-meta-platform": "^0.9", + "symfony/ai-milvus-store": "^0.9", + "symfony/ai-mistral-platform": "^0.9", + "symfony/ai-mongo-db-message-store": "^0.9", + "symfony/ai-mongo-db-store": "^0.9", + "symfony/ai-neo4j-store": "^0.9", + "symfony/ai-ollama-platform": "^0.9", + "symfony/ai-open-ai-platform": "^0.9", + "symfony/ai-open-responses-platform": "^0.9", + "symfony/ai-open-router-platform": "^0.9", + "symfony/ai-open-search-store": "^0.9", + "symfony/ai-ovh-platform": "^0.9", + "symfony/ai-perplexity-platform": "^0.9", + "symfony/ai-pinecone-store": "^0.9", + "symfony/ai-pogocache-message-store": "^0.9", + "symfony/ai-postgres-store": "^0.9", + "symfony/ai-qdrant-store": "^0.9", + "symfony/ai-redis-message-store": "^0.9", + "symfony/ai-redis-store": "^0.9", + "symfony/ai-replicate-platform": "^0.9", + "symfony/ai-s3vectors-store": "^0.9", + "symfony/ai-scaleway-platform": "^0.9", + "symfony/ai-session-message-store": "^0.9", + "symfony/ai-sqlite-store": "^0.9", + "symfony/ai-store": "^0.9", + "symfony/ai-supabase-store": "^0.9", + "symfony/ai-surreal-db-message-store": "^0.9", + "symfony/ai-surreal-db-store": "^0.9", + "symfony/ai-transformers-php-platform": "^0.9", + "symfony/ai-typesense-store": "^0.9", + "symfony/ai-vektor-store": "^0.9", + "symfony/ai-vertex-ai-platform": "^0.9", + "symfony/ai-voyage-platform": "^0.9", + "symfony/ai-weaviate-store": "^0.9", + "symfony/expression-language": "^7.3|^8.0", + "symfony/security-core": "^7.3|^8.0", + "symfony/translation": "^7.3|^8.0", + "symfony/validator": "^7.3|^8.0" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\AiBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Integration bundle for Symfony AI components", + "support": { + "source": "https://github.com/symfony/ai-bundle/tree/v0.9.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-16T08:40:45+00:00" + }, + { + "name": "symfony/ai-ollama-platform", + "version": "v0.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-ollama-platform.git", + "reference": "a9452227917c360fa28ad47d3ffb44adb8796af9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-ollama-platform/zipball/a9452227917c360fa28ad47d3ffb44adb8796af9", + "reference": "a9452227917c360fa28ad47d3ffb44adb8796af9", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/ai-platform": "^0.9", + "symfony/http-client": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53" + }, + "type": "symfony-ai-platform", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\Bridge\\Ollama\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Ollama platform bridge for Symfony AI", + "keywords": [ + "Bridge", + "ai", + "local", + "ollama", + "platform" + ], + "support": { + "source": "https://github.com/symfony/ai-ollama-platform/tree/v0.9.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-16T01:01:33+00:00" + }, + { + "name": "symfony/ai-platform", + "version": "v0.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ai-platform.git", + "reference": "fb55ebdf20bbe30af6752a0ce6a25abc56b2b625" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ai-platform/zipball/fb55ebdf20bbe30af6752a0ce6a25abc56b2b625", + "reference": "fb55ebdf20bbe30af6752a0ce6a25abc56b2b625", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "oskarstark/enum-helper": "^1.5", + "php": ">=8.2", + "phpdocumentor/reflection-docblock": "^5.4|^6.0", + "phpstan/phpdoc-parser": "^2.1", + "psr/log": "^3.0", + "symfony/clock": "^7.3|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/property-access": "^7.3|^8.0", + "symfony/property-info": "^7.3|^8.0", + "symfony/serializer": "^7.3|^8.0", + "symfony/type-info": "^7.3|^8.0", + "symfony/uid": "^7.3|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53", + "symfony/cache": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dotenv": "^7.3|^8.0", + "symfony/expression-language": "^7.3|^8.0", + "symfony/finder": "^7.3|^8.0", + "symfony/http-client": "^7.3|^8.0", + "symfony/http-client-contracts": "^3.5", + "symfony/intl": "^7.3|^8.0", + "symfony/process": "^7.3|^8.0", + "symfony/validator": "^7.3|^8.0", + "symfony/var-dumper": "^7.3|^8.0", + "symfony/yaml": "^7.3|^8.0" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\Platform\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Oskar Stark", + "email": "oskarstark@googlemail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "PHP library for interacting with AI platform provider.", + "keywords": [ + "Gemini", + "OpenRouter", + "ai", + "aimlapi", + "albert", + "amazeeai", + "anthropic", + "azure", + "bedrock", + "cerebras", + "dockermodelrunner", + "elevenlabs", + "huggingface", + "inference", + "litellm", + "llama", + "lmstudio", + "meta", + "mistral", + "nova", + "ollama", + "openai", + "ovh", + "perplexity", + "replicate", + "speech", + "transformers", + "vertexai", + "voyage" + ], + "support": { + "source": "https://github.com/symfony/ai-platform/tree/v0.9.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-15T19:15:50+00:00" + }, { "name": "symfony/cache", "version": "v8.1.0", @@ -387,6 +1134,83 @@ ], "time": "2026-05-05T15:33:14+00:00" }, + { + "name": "symfony/clock", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/701ef4de9705d6c32292ebee5e8044094a09fbf6", + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, { "name": "symfony/config", "version": "v8.1.0", @@ -1393,6 +2217,185 @@ ], "time": "2026-05-29T05:06:50+00:00" }, + { + "name": "symfony/http-client", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "68a48e4c31f63fcd1bdff997a85a09e55efe8cdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/68a48e4c31f63fcd1bdff997a85a09e55efe8cdb", + "reference": "68a48e4c31f63fcd1bdff997a85a09e55efe8cdb", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/http-client-contracts": "^3.7", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<3", + "php-http/discovery": "<1.15" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^5.3.2", + "amphp/http-tunnel": "^2.0", + "guzzlehttp/guzzle": "^7.10", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/cache": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/rate-limiter": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-06T13:17:50+00:00" + }, { "name": "symfony/http-foundation", "version": "v8.1.0", @@ -2002,6 +3005,256 @@ ], "time": "2026-05-26T02:25:22+00:00" }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/property-access", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/9261ef060f26cc7b728f67f141ba19b98a6209a9", + "reference": "9261ef060f26cc7b728f67f141ba19b98a6209a9", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/property-info": "^7.4.4|^8.0.4" + }, + "require-dev": { + "symfony/cache": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, + { + "name": "symfony/property-info", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/4721e8c56d0cd2378e0ef9a9899f810008b859f7", + "reference": "4721e8c56d0cd2378e0ef9a9899f810008b859f7", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/string": "^7.4|^8.0", + "symfony/type-info": "^7.4.7|^8.0.7" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, { "name": "symfony/routing", "version": "v8.1.0", @@ -2166,6 +3419,105 @@ ], "time": "2026-05-29T05:06:50+00:00" }, + { + "name": "symfony/serializer", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "d101886195c5f772cf7033641fe9c40c3e3969e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/d101886195c5f772cf7033641fe9c40c3e3969e1", + "reference": "d101886195c5f772cf7033641fe9c40c3e3969e1", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/property-access": "<8.1", + "symfony/property-info": "<7.4", + "symfony/type-info": "<7.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "seld/jsonlint": "^1.10", + "symfony/cache": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/form": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/property-access": "^8.1", + "symfony/property-info": "^7.4|^8.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/serializer/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, { "name": "symfony/service-contracts", "version": "v3.7.0", @@ -2343,6 +3695,166 @@ ], "time": "2026-05-29T05:06:50+00:00" }, + { + "name": "symfony/type-info", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", + "reference": "9f24df8a79781b9b9f030fea7dfd2f3bd1e7e7e7", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "phpstan/phpdoc-parser": "<1.30" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.30|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, + { + "name": "symfony/uid", + "version": "v8.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/7393f157a55f7e70a4de0334435c55a5a8fe749a", + "reference": "7393f157a55f7e70a4de0334435c55a5a8fe749a", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v8.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-29T05:06:50+00:00" + }, { "name": "symfony/var-dumper", "version": "v8.1.0", @@ -2588,12 +4100,78 @@ } ], "time": "2026-05-29T05:06:50+00:00" + }, + { + "name": "webmozart/assert", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9007ea6f45ecf352a9422b36644e4bfc039b9155", + "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^8.2" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "psalm": { + "pluginClass": "Webmozart\\Assert\\PsalmPlugin" + }, + "branch-alias": { + "dev-master": "2.0-dev", + "dev-feature/2-0": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/2.4.0" + }, + "time": "2026-05-20T13:07:01+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { @@ -2601,6 +4179,6 @@ "ext-ctype": "*", "ext-iconv": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.9.0" } diff --git a/config/bundles.php b/config/bundles.php index 49d3fb6..6316d6a 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -2,4 +2,5 @@ return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Symfony\AI\AiBundle\AiBundle::class => ['all' => true], ]; diff --git a/config/packages/ai.yaml b/config/packages/ai.yaml new file mode 100644 index 0000000..89f8e7a --- /dev/null +++ b/config/packages/ai.yaml @@ -0,0 +1,27 @@ +ai: + platform: + # Inference Platform configuration + # see https://github.com/symfony/ai/tree/main/src/platform#platform-bridges + + # openai: + # api_key: '%env(OPENAI_API_KEY)%' + + agent: + # Agent configuration + # see https://symfony.com/doc/current/ai/bundles/ai-bundle.html + + # default: + # platform: 'ai.platform.openai' + # model: 'gpt-5-mini' + # prompt: | + # You are a pirate and you write funny. + # tools: + # - 'Symfony\AI\Agent\Bridge\Clock\Clock' + + store: + # Store configuration + + # chromadb: + # default: + # client: 'client.service.id' + # collection: 'my_collection' diff --git a/config/packages/ai_ollama_platform.yaml b/config/packages/ai_ollama_platform.yaml new file mode 100644 index 0000000..e432397 --- /dev/null +++ b/config/packages/ai_ollama_platform.yaml @@ -0,0 +1,3 @@ +ai: + platform: + ollama: null diff --git a/config/packages/property_info.yaml b/config/packages/property_info.yaml new file mode 100644 index 0000000..dd31b9d --- /dev/null +++ b/config/packages/property_info.yaml @@ -0,0 +1,3 @@ +framework: + property_info: + with_constructor_extractor: true diff --git a/config/reference.php b/config/reference.php index 3f07cb0..65f8488 100644 --- a/config/reference.php +++ b/config/reference.php @@ -352,7 +352,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }>, * }, * serializer?: bool|array{ // Serializer configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * enable_attributes?: bool|Param, // Default: true * name_converter?: scalar|Param|null, * circular_reference_handler?: scalar|Param|null, @@ -369,7 +369,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }>, * }, * property_access?: bool|array{ // Property access configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * magic_call?: bool|Param, // Default: false * magic_get?: bool|Param, // Default: true * magic_set?: bool|Param, // Default: true @@ -377,11 +377,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * throw_exception_on_invalid_property_path?: bool|Param, // Default: true * }, * type_info?: bool|array{ // Type info configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * aliases?: array, * }, * property_info?: bool|array{ // Property info configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * with_constructor_extractor?: bool|Param, // Registers the constructor extractor. // Default: true * }, * cache?: array{ // Cache configuration @@ -471,7 +471,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * disallow_search_engine_index?: bool|Param, // Enabled by default when debug is enabled. // Default: true * http_client?: bool|array{ // HTTP Client configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * max_host_connections?: int|Param, // The maximum number of connections to a single host. * default_options?: array{ * headers?: array, @@ -646,7 +646,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }>, * }, * uid?: bool|array{ // Uid configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * default_uuid_version?: 7|6|4|1|Param, // Default: 7 * name_based_uuid_version?: 5|3|Param, // Default: 5 * name_based_uuid_namespace?: scalar|Param|null, @@ -701,28 +701,500 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * }, * } + * @psalm-type AiConfig = array{ + * platform?: array{ + * albert?: array{ + * api_key?: string|Param, + * base_url?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * amazeeai?: array{ + * base_url?: string|Param, + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * anthropic?: array{ + * api_key?: string|Param, + * version?: string|Param, // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * cache_retention?: "none"|"short"|"long"|Param, // Prompt cache retention policy for Anthropic models // Default: "short" + * }, + * azure?: array, + * bedrock?: array, + * cache?: array, + * cartesia?: array{ + * api_key?: string|Param, + * version?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * cerebras?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * cohere?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * decart?: array{ + * api_key?: string|Param, + * host?: string|Param, // Default: "https://api.decart.ai/v1" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * deepseek?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * dockermodelrunner?: array{ + * host_url?: string|Param, // Default: "http://127.0.0.1:12434" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * elevenlabs?: array{ + * api_key?: string|Param, + * endpoint?: string|Param, // Default: "https://api.elevenlabs.io/v1/" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * failover?: array, + * rate_limiter?: string|Param, + * }>, + * gemini?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * generic?: array, + * huggingface?: array{ + * api_key?: string|Param, + * provider?: string|Param, // Default: "hf-inference" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * lmstudio?: array{ + * host_url?: string|Param, // Default: "http://127.0.0.1:1234" + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * mistral?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * ollama?: array{ + * endpoint?: string|Param, // Endpoint for Ollama (e.g. "http://127.0.0.1:11434" for local, or a cloud endpoint). If null, the http_client is used as-is and must already be configured with a base URI. + * api_key?: string|Param, // API key for Ollama Cloud authentication (optional for local usage) + * http_client?: string|Param, // Service ID of the HTTP client to use. When "endpoint" is null, this client must be pre-configured (e.g. with a base_uri). // Default: "http_client" + * }, + * openai?: array{ + * api_key?: string|Param, + * region?: scalar|Param|null, // The region for OpenAI API (EU, US, or null for default) // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * openresponses?: array, + * openrouter?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * ovh?: array{ + * api_key?: scalar|Param|null, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * perplexity?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * scaleway?: array{ + * api_key?: scalar|Param|null, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * transformersphp?: array, + * vertexai?: array{ + * location?: string|Param, // Required for the project-scoped endpoint. Must be set together with "project_id". // Default: null + * project_id?: string|Param, // Required for the project-scoped endpoint. Must be set together with "location". // Default: null + * api_key?: string|Param, // When set without "location" and "project_id", uses the global endpoint. Note: API keys only identify the project for billing and do not provide identity-based access control. For production use with IAM, audit logging, or data residency, prefer the project-scoped endpoint with service account authentication. // Default: null + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * voyage?: array{ + * api_key?: string|Param, + * http_client?: string|Param, // Service ID of the HTTP client to use // Default: "http_client" + * }, + * }, + * model?: array|\Symfony\AI\Platform\Capability|Param>, + * }>>, + * agent?: array, + * }, + * keep_tool_messages?: bool|Param, // Keep tool messages in the conversation history // Default: false + * include_sources?: bool|Param, // Include sources exposed by tools as part of the tool result metadata // Default: false + * fault_tolerant_toolbox?: bool|Param, // Continue the agent run even if a tool call fails // Default: true + * speech?: bool|array{ // Speech (TTS/STT) decorator configuration + * enabled?: bool|Param, // Default: true + * text_to_speech_platform?: string|Param, // Service name of the TTS platform (e.g. ai.platform.elevenlabs). // Default: null + * speech_to_text_platform?: string|Param, // Service name of the STT platform (e.g. ai.platform.openai). // Default: null + * tts_model?: string|Param, // Text-to-speech model name // Default: null + * tts_options?: mixed, // Provider-specific TTS options // Default: [] + * stt_model?: string|Param, // Speech-to-text model name // Default: null + * stt_options?: mixed, // Provider-specific STT options // Default: [] + * }, + * }>, + * multi_agent?: array>, + * fallback?: string|Param, // Service ID of the fallback agent for unmatched requests + * }>, + * store?: array{ + * azuresearch?: array, + * cache?: array, + * chromadb?: array, + * clickhouse?: array, + * cloudflare?: array, + * elasticsearch?: array, + * manticoresearch?: array, + * mariadb?: array, + * meilisearch?: array, + * memory?: array, + * milvus?: array, + * mongodb?: array, + * neo4j?: array, + * opensearch?: array, + * pinecone?: array, + * top_k?: int|Param, + * }>, + * postgres?: array, + * qdrant?: array, + * redis?: array, + * s3vectors?: array, + * vector_bucket_name?: string|Param, + * index_name?: string|Param, + * filter?: array, + * top_k?: int|Param, // Default number of results to return // Default: 3 + * }>, + * sqlite?: array, + * supabase?: array, + * surrealdb?: array, + * typesense?: array, + * weaviate?: array, + * vektor?: array, + * }, + * message_store?: array{ + * cache?: array, + * cloudflare?: array, + * doctrine?: array{ + * dbal?: array, + * }, + * meilisearch?: array, + * memory?: array, + * mongodb?: array, + * pogocache?: array, + * redis?: array, + * session?: array, + * surrealdb?: array, + * }, + * chat?: array, + * vectorizer?: array, + * indexer?: array, + * filters?: list, + * vectorizer?: scalar|Param|null, // Service name of vectorizer // Default: "Symfony\\AI\\Store\\Document\\VectorizerInterface" + * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" + * }>, + * retriever?: array, + * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, * services?: ServicesConfig, * framework?: FrameworkConfig, + * ai?: AiConfig, * "when@dev"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, * services?: ServicesConfig, * framework?: FrameworkConfig, + * ai?: AiConfig, * }, * "when@prod"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, * services?: ServicesConfig, * framework?: FrameworkConfig, + * ai?: AiConfig, * }, * "when@test"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, * services?: ServicesConfig, * framework?: FrameworkConfig, + * ai?: AiConfig, * }, * ...