doctrine:
    dbal:
        # Deux connexions pointant sur le meme DSN : l'ORM utilise `default`,
        # l'AuditLogWriter utilise `audit` pour ecrire hors de la transaction
        # Doctrine et eviter tout entanglement transactionnel en batch.
        default_connection: default
        connections:
            default:
                url: '%env(resolve:DATABASE_URL)%'
                profiling_collect_backtrace: '%kernel.debug%'
                # Exclut certaines tables de toute operation de comparaison de
                # schema (doctrine:schema:update, schema:validate, diff de
                # migrations...). Ces tables n'ont volontairement aucune entite
                # mappee :
                #  - `audit_log` : append-only via DBAL brut (AuditLogWriter) pour
                #    eviter la recursion du listener Doctrine.
                #  - `qualimat_sync_log` : journal de synchro transporteurs
                #    QUALIMAT, ecrit en DBAL brut par `app:qualimat:sync`, hors ORM.
                #    NB : `qualimat_carrier` n'est PLUS filtree depuis M4 (ERP-155) :
                #    elle est desormais mappee en LECTURE SEULE par l'entite
                #    App\Module\Transport\Domain\Entity\QualimatCarrier (cible de la
                #    FK editable carrier.qualimat_carrier_id). Son mapping reproduit
                #    a l'identique le DDL de la migration ERP-39 (unique siret, index
                #    is_active, TIMESTAMP(6)) -> schema:update reste un no-op.
                #  - `idtf_product` / `idtf_sync_log` : referentiel codes IDTF
                #    synchronise en DBAL brut par `app:idtf:sync`, hors ORM.
                # Sans ce filtre, schema:update les considere comme "orphelines" et
                # genere un `DROP TABLE` qui casse la base de test apres chaque
                # `make test-db-setup` (la migration les a creees, schema:update les
                # supprime juste apres). Creation / suppression restent pilotees par
                # les migrations (audit_log : Version20260420202749 ; qualimat :
                # Version20260612150000 ; idtf : Version20260612160000).
                schema_filter: '~^(?!(?:audit_log|qualimat_sync_log|idtf_product|idtf_sync_log)$).+~'
            audit:
                url: '%env(resolve:DATABASE_URL)%'
    orm:
        validate_xml_mapping: true
        naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
        identity_generation_preferences:
            Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
        auto_mapping: true
        # Mapping contrat DDD → classe concrete. Permet au module Core de
        # referencer `SiteInterface` dans ses ORM mappings (User) sans importer
        # la classe concrete du module Sites. Pattern officiel Doctrine pour
        # les bounded contexts, remplace l'ancien import direct
        # `App\Module\Sites\Domain\Entity\Site` dans User.php.
        resolve_target_entities:
            App\Shared\Domain\Contract\SiteInterface: App\Module\Sites\Domain\Entity\Site
            # Cible des ManyToOne created_by / updated_by du TimestampableBlamableTrait.
            # Permet a Shared de referencer UserInterface dans ses ORM mappings sans
            # importer la classe concrete du module Core (cf. spec-back M0 § 2.8).
            Symfony\Component\Security\Core\User\UserInterface: App\Module\Core\Domain\Entity\User
            # Cible des ManyToMany Client.categories / ClientAddress.categories (M1).
            # Permet au module Commercial de referencer une Category via le contrat
            # Shared sans importer la classe concrete du module Catalog (regle n°1).
            App\Shared\Domain\Contract\CategoryInterface: App\Module\Catalog\Domain\Entity\Category
            # Cibles des ManyToOne de CarrierPrice (M4 Transport, onglet Prix) :
            # permet au module Transport de referencer Client / Supplier et leurs
            # adresses (M1/M2 Commercial) via des contrats Shared sans importer les
            # classes concretes (regle n°1). L'embed JSON passe par les read-groups
            # des entites concretes (client:read / supplier:read / ...).
            App\Shared\Domain\Contract\ClientInterface: App\Module\Commercial\Domain\Entity\Client
            App\Shared\Domain\Contract\ClientAddressInterface: App\Module\Commercial\Domain\Entity\ClientAddress
            App\Shared\Domain\Contract\SupplierInterface: App\Module\Commercial\Domain\Entity\Supplier
            App\Shared\Domain\Contract\SupplierAddressInterface: App\Module\Commercial\Domain\Entity\SupplierAddress
        mappings:
            # Mapping des entites techniques partagees (src/Shared/Domain/Entity).
            # Premier occupant : UploadedDocument (infra upload generique ERP-154).
            # Necessaire car les entites Shared ne sont pas couvertes par
            # l'auto_mapping (qui ne cible que les bundles).
            Shared:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Shared/Domain/Entity'
                prefix: 'App\Shared\Domain\Entity'
                alias: Shared
            Core:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Core/Domain/Entity'
                prefix: 'App\Module\Core\Domain\Entity'
                alias: Core
            # Mapping inconditionnelle du module Sites : la structure DB
            # existe meme si SitesModule::class est retire de config/modules.php.
            # L'activation fonctionnelle (ex: exposition des permissions, futurs
            # endpoints API) passe exclusivement par config/modules.php.
            Sites:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Sites/Domain/Entity'
                prefix: 'App\Module\Sites\Domain\Entity'
                alias: Sites
            # Mapping inconditionnel du module Catalog (meme logique que Sites) :
            # la structure DB (category, category_type) existe meme si
            # CatalogModule::class n'est pas encore wire dans config/modules.php
            # (declaration du module = ticket 0.5 / ERP-47). L'ORM doit connaitre
            # les entites pour que le schema soit en phase ; l'activation
            # fonctionnelle passe exclusivement par config/modules.php.
            Catalog:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Catalog/Domain/Entity'
                prefix: 'App\Module\Catalog\Domain\Entity'
                alias: Catalog
            # Mapping inconditionnel du module Commercial (meme logique que Catalog) :
            # les tables (client, sous-collections, referentiels comptables) creees
            # par la migration M1 (Version20260601000000) doivent etre connues de
            # l'ORM. L'activation fonctionnelle passe par config/modules.php.
            Commercial:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Commercial/Domain/Entity'
                prefix: 'App\Module\Commercial\Domain\Entity'
                alias: Commercial
            # Mapping inconditionnel du module Technique (meme logique que Commercial) :
            # les tables prestataires (provider + sous-collections + jointures M2M)
            # creees par la migration M3 (Version20260612100000) doivent etre connues
            # de l'ORM. L'activation fonctionnelle passe par config/modules.php.
            Technique:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Technique/Domain/Entity'
                prefix: 'App\Module\Technique\Domain\Entity'
                alias: Technique
            # Mapping inconditionnel du module Transport (meme logique que Technique) :
            # les tables transporteurs (carrier + sous-collections) creees par la
            # migration M4 (Version20260615150000) et le mapping lecture-seule de
            # qualimat_carrier (referentiel ERP-39) doivent etre connus de l'ORM.
            # L'activation fonctionnelle passe par config/modules.php.
            Transport:
                type: attribute
                is_bundle: false
                dir: '%kernel.project_dir%/src/Module/Transport/Domain/Entity'
                prefix: 'App\Module\Transport\Domain\Entity'
                alias: Transport
        controller_resolver:
            auto_mapping: false

when@test:
    doctrine:
        dbal:
            # Le suffixe "_test" doit etre propage aux deux connexions : l'ORM
            # l'herite via `default`, l'AuditLogWriter via `audit`. Sans cela,
            # la connexion `audit` ecrirait dans la base dev pendant que l'ORM
            # ecrit dans la base test — divergence invisible en apparence mais
            # fatale pour les tests du journal d'audit.
            #
            # `idle_connection_ttl: 1` (au lieu du defaut 600s) : en test on
            # reboote le kernel a chaque test. Sans TTL court, les connexions
            # orphelines s'accumulent dans PG et on finit par saturer le pool
            # (max_connections=100) sur une suite de 200+ tests qui utilisent
            # 2 connexions chacun (default + audit).
            connections:
                default:
                    dbname_suffix: '_test%env(default::TEST_TOKEN)%'
                    idle_connection_ttl: 1
                audit:
                    dbname_suffix: '_test%env(default::TEST_TOKEN)%'
                    idle_connection_ttl: 1
        orm:
            mappings:
                # Entite fictive SiteAware utilisee uniquement en tests du
                # module Sites (ticket 4). Le mapping n'est charge qu'en
                # environnement test, donc aucun impact sur les schemas
                # dev/prod. La table est creee a la volee par les tests
                # d'integration (via `SchemaTool::createSchema`) dans le
                # setUp de SiteScopedQueryExtensionTest.
                TestFixtures:
                    type: attribute
                    is_bundle: false
                    dir: '%kernel.project_dir%/tests/Fixtures/SiteAware'
                    prefix: 'App\Tests\Fixtures\SiteAware'
                    alias: TestFixtures

when@prod:
    doctrine:
        orm:
            query_cache_driver:
                type: pool
                pool: doctrine.system_cache_pool
            result_cache_driver:
                type: pool
                pool: doctrine.result_cache_pool

    framework:
        cache:
            pools:
                doctrine.result_cache_pool:
                    adapter: cache.app
                doctrine.system_cache_pool:
                    adapter: cache.system
