Lorsqu'un super-admin crée un établissement via l'interface, le système doit automatiquement créer la base tenant, exécuter les migrations, créer le premier utilisateur admin et envoyer l'invitation — le tout de manière asynchrone pour ne pas bloquer la réponse HTTP. Ce mécanisme rend chaque établissement opérationnel dès sa création sans intervention manuelle sur l'infrastructure.
587 lines
27 KiB
YAML
587 lines
27 KiB
YAML
# This file is the entry point to configure your own services.
|
|
# Files in the packages/ subdirectory configure your dependencies.
|
|
|
|
# Put parameters here that don't need to change on each machine where the app is deployed
|
|
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
|
parameters:
|
|
tenant.base_domain: '%env(TENANT_BASE_DOMAIN)%'
|
|
app.url: '%env(APP_URL)%'
|
|
|
|
services:
|
|
# default configuration for services in this file
|
|
_defaults:
|
|
autowire: true # Automatically injects dependencies in your services.
|
|
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
|
bind:
|
|
# Bind activation tokens cache pool (7-day TTL)
|
|
Psr\Cache\CacheItemPoolInterface $activationTokensCache: '@activation_tokens.cache'
|
|
# Bind users cache pool (no TTL - persistent data)
|
|
Psr\Cache\CacheItemPoolInterface $usersCache: '@users.cache'
|
|
# Bind refresh tokens cache pool (7-day TTL)
|
|
Psr\Cache\CacheItemPoolInterface $refreshTokensCache: '@refresh_tokens.cache'
|
|
# Bind password reset tokens cache pool (1-hour TTL)
|
|
Psr\Cache\CacheItemPoolInterface $passwordResetTokensCache: '@password_reset_tokens.cache'
|
|
# Bind sessions cache pool (7-day TTL)
|
|
Psr\Cache\CacheItemPoolInterface $sessionsCache: '@sessions.cache'
|
|
# Bind student guardians cache pool (no TTL - persistent data)
|
|
Psr\Cache\CacheItemPoolInterface $studentGuardiansCache: '@student_guardians.cache'
|
|
# Bind paginated queries cache pool (1h TTL, tag-aware)
|
|
Symfony\Contracts\Cache\TagAwareCacheInterface $paginatedQueriesCache: '@paginated_queries.cache'
|
|
# Bind named message buses
|
|
Symfony\Component\Messenger\MessageBusInterface $eventBus: '@event.bus'
|
|
Symfony\Component\Messenger\MessageBusInterface $commandBus: '@command.bus'
|
|
Symfony\Component\Messenger\MessageBusInterface $queryBus: '@query.bus'
|
|
|
|
# makes classes in src/ available to be used as services
|
|
# this creates a service per class whose id is the fully-qualified class name
|
|
App\:
|
|
resource: '../src/'
|
|
exclude:
|
|
- '../src/DependencyInjection/'
|
|
- '../src/Entity/'
|
|
- '../src/Kernel.php'
|
|
# Exclude Domain layers - they should be pure PHP with no framework deps
|
|
- '../src/*/Domain/'
|
|
|
|
# Domain services need to be registered explicitly to avoid framework coupling
|
|
# Example: App\Administration\Application\Command\:
|
|
# resource: '../src/Administration/Application/Command/'
|
|
|
|
# Tenant services
|
|
App\Shared\Infrastructure\Tenant\TenantResolver:
|
|
arguments:
|
|
$baseDomain: '%tenant.base_domain%'
|
|
|
|
App\Shared\Infrastructure\Persistence\Doctrine\TenantAwareConnection:
|
|
alias: doctrine.dbal.default_connection
|
|
|
|
App\Shared\Infrastructure\Tenant\TenantDatabaseSwitcher:
|
|
alias: doctrine.dbal.default_connection
|
|
|
|
# TenantRegistry est configuré par environnement :
|
|
# - dev: config/packages/dev/tenant.yaml (tenants de test)
|
|
# - prod: à configurer via admin ou env vars
|
|
|
|
App\Shared\Infrastructure\Tenant\Command\CreateTenantDatabaseCommand:
|
|
arguments:
|
|
$masterDatabaseUrl: '%env(DATABASE_URL)%'
|
|
|
|
App\Shared\Infrastructure\Tenant\Command\TenantMigrateCommand:
|
|
arguments:
|
|
$projectDir: '%kernel.project_dir%'
|
|
|
|
# Administration services
|
|
# Bind Repository interfaces to their implementations
|
|
App\Administration\Domain\Repository\ActivationTokenRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Redis\RedisActivationTokenRepository
|
|
|
|
App\Administration\Infrastructure\Persistence\Cache\CachedUserRepository:
|
|
arguments:
|
|
$inner: '@App\Administration\Infrastructure\Persistence\Doctrine\DoctrineUserRepository'
|
|
|
|
App\Administration\Domain\Repository\UserRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Cache\CachedUserRepository
|
|
|
|
App\Administration\Infrastructure\Console\MigrateUsersToPostgresCommand:
|
|
arguments:
|
|
$source: '@App\Administration\Infrastructure\Persistence\Cache\CacheUserRepository'
|
|
$target: '@App\Administration\Infrastructure\Persistence\Doctrine\DoctrineUserRepository'
|
|
|
|
App\Administration\Application\Port\PasswordHasher:
|
|
alias: App\Administration\Infrastructure\Security\SymfonyPasswordHasher
|
|
|
|
# Clock interface binding
|
|
App\Shared\Domain\Clock:
|
|
alias: App\Shared\Infrastructure\Clock\SystemClock
|
|
|
|
# Domain policies (need explicit registration as Domain is excluded from autowiring)
|
|
App\Administration\Domain\Policy\ConsentementParentalPolicy:
|
|
autowire: true
|
|
|
|
App\Scolarite\Domain\Policy\VisibiliteNotesPolicy:
|
|
autowire: true
|
|
|
|
# Ports
|
|
App\Scolarite\Application\Port\ParentGradeDelayReader:
|
|
alias: App\Scolarite\Infrastructure\Service\DatabaseParentGradeDelayReader
|
|
|
|
# Email handlers
|
|
App\Administration\Infrastructure\Messaging\SendActivationConfirmationHandler:
|
|
arguments:
|
|
$appUrl: '%app.url%'
|
|
|
|
App\Administration\Infrastructure\Messaging\SendPasswordResetEmailHandler:
|
|
arguments:
|
|
$appUrl: '%app.url%'
|
|
|
|
App\Administration\Infrastructure\Messaging\SendPasswordResetConfirmationHandler:
|
|
arguments:
|
|
$appUrl: '%app.url%'
|
|
|
|
App\Shared\Infrastructure\Tenant\TenantUrlBuilder:
|
|
arguments:
|
|
$appUrl: '%app.url%'
|
|
$baseDomain: '%tenant.base_domain%'
|
|
|
|
# Audit Logger Service (writes to append-only audit_log table)
|
|
App\Shared\Application\Port\AuditLogger:
|
|
alias: App\Shared\Infrastructure\Audit\AuditLogger
|
|
|
|
App\Shared\Infrastructure\Audit\AuditLogger:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
$appSecret: '%env(APP_SECRET)%'
|
|
|
|
App\Shared\Infrastructure\Audit\AuditLogRepository:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
App\Shared\Infrastructure\Console\ArchiveAuditLogsCommand:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
App\Shared\Infrastructure\Console\ReviewFailedMessagesCommand:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
# Audit log handlers (use AuditLogger to write to database)
|
|
App\Shared\Infrastructure\Audit\Handler\AuditAuthenticationHandler:
|
|
arguments:
|
|
$appSecret: '%env(APP_SECRET)%'
|
|
|
|
# JWT Authentication
|
|
App\Administration\Infrastructure\Security\JwtPayloadEnricher:
|
|
tags:
|
|
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_jwt_created, method: onJWTCreated }
|
|
|
|
App\Administration\Infrastructure\Security\DatabaseUserProvider:
|
|
arguments:
|
|
$userRepository: '@App\Administration\Domain\Repository\UserRepository'
|
|
|
|
App\SuperAdmin\Infrastructure\Persistence\Doctrine\DoctrineSuperAdminRepository:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
App\SuperAdmin\Infrastructure\Persistence\Doctrine\DoctrineEstablishmentRepository:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
App\SuperAdmin\Application\Query\GetEstablishmentsMetrics\GetEstablishmentsMetricsHandler:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
# Refresh Token Repository
|
|
App\Administration\Domain\Repository\RefreshTokenRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Redis\RedisRefreshTokenRepository
|
|
|
|
# Password Reset Token Repository
|
|
App\Administration\Domain\Repository\PasswordResetTokenRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Redis\RedisPasswordResetTokenRepository
|
|
|
|
# Session Repository
|
|
App\Administration\Domain\Repository\SessionRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Redis\RedisSessionRepository
|
|
|
|
# Class Repository (Story 2.1 - Gestion des classes)
|
|
App\Administration\Domain\Repository\ClassRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineClassRepository
|
|
|
|
# Subject Repository (Story 2.2 - Gestion des matières)
|
|
App\Administration\Domain\Repository\SubjectRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineSubjectRepository
|
|
|
|
# Period Configuration Repository (Story 2.3 - Gestion des périodes)
|
|
App\Administration\Domain\Repository\PeriodConfigurationRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrinePeriodConfigurationRepository
|
|
|
|
# Grading Configuration Repository (Story 2.4 - Mode de notation)
|
|
App\Administration\Domain\Repository\GradingConfigurationRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineGradingConfigurationRepository
|
|
|
|
# Class Assignment (Story 3.0 - Affectation élèves aux classes)
|
|
App\Administration\Domain\Repository\ClassAssignmentRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineClassAssignmentRepository
|
|
|
|
# Teacher Assignment (Story 2.8 - Affectation enseignants)
|
|
App\Administration\Domain\Repository\TeacherAssignmentRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineTeacherAssignmentRepository
|
|
|
|
App\Administration\Application\Port\TeacherAssignmentChecker:
|
|
alias: App\Administration\Infrastructure\Service\RepositoryTeacherAssignmentChecker
|
|
|
|
# Teacher Replacement Repository (Story 2.9 - Remplaçants temporaires)
|
|
App\Scolarite\Domain\Repository\TeacherReplacementRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineTeacherReplacementRepository
|
|
|
|
# Homework (Story 5.1 - Création de devoirs)
|
|
App\Scolarite\Domain\Repository\HomeworkRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineHomeworkRepository
|
|
|
|
App\Scolarite\Domain\Repository\HomeworkRuleExceptionRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineHomeworkRuleExceptionRepository
|
|
|
|
App\Scolarite\Domain\Repository\HomeworkAttachmentRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineHomeworkAttachmentRepository
|
|
|
|
# Homework Submissions (Story 5.10 - Rendu de devoir par l'élève)
|
|
App\Scolarite\Domain\Repository\HomeworkSubmissionRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineHomeworkSubmissionRepository
|
|
|
|
App\Scolarite\Domain\Repository\SubmissionAttachmentRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineSubmissionAttachmentRepository
|
|
|
|
App\Scolarite\Application\Port\ClassStudentsReader:
|
|
alias: App\Scolarite\Infrastructure\Service\DoctrineClassStudentsReader
|
|
|
|
App\Scolarite\Domain\Service\DueDateValidator:
|
|
autowire: true
|
|
|
|
App\Scolarite\Domain\Service\HomeworkDuplicator:
|
|
autowire: true
|
|
|
|
App\Scolarite\Application\Port\HtmlSanitizer:
|
|
alias: App\Scolarite\Infrastructure\Service\HomeworkHtmlSanitizer
|
|
|
|
App\Scolarite\Infrastructure\Service\HomeworkHtmlSanitizer:
|
|
arguments:
|
|
$homeworkSanitizer: '@html_sanitizer.sanitizer.homework_sanitizer'
|
|
|
|
App\Scolarite\Application\Port\FileStorage:
|
|
alias: App\Scolarite\Infrastructure\Storage\S3FileStorage
|
|
|
|
App\Scolarite\Infrastructure\Storage\LocalFileStorage:
|
|
arguments:
|
|
$storagePath: '%kernel.project_dir%/var/storage'
|
|
|
|
App\Scolarite\Infrastructure\Storage\S3FileStorage:
|
|
arguments:
|
|
$endpoint: '%env(S3_ENDPOINT)%'
|
|
$bucket: '%env(S3_BUCKET)%'
|
|
$key: '%env(S3_KEY)%'
|
|
$secret: '%env(S3_SECRET)%'
|
|
$region: '%env(S3_REGION)%'
|
|
|
|
# Schedule (Story 4.1 - Emploi du temps)
|
|
App\Scolarite\Domain\Repository\ScheduleSlotRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineScheduleSlotRepository
|
|
|
|
App\Scolarite\Domain\Repository\ScheduleExceptionRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineScheduleExceptionRepository
|
|
|
|
App\Scolarite\Domain\Service\ScheduleConflictDetector:
|
|
autowire: true
|
|
|
|
App\Scolarite\Application\Port\EnseignantAffectationChecker:
|
|
alias: App\Scolarite\Infrastructure\Service\CurrentYearEnseignantAffectationChecker
|
|
|
|
App\Scolarite\Domain\Repository\EvaluationRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineEvaluationRepository
|
|
|
|
App\Scolarite\Domain\Repository\GradeRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineGradeRepository
|
|
|
|
App\Scolarite\Domain\Repository\AppreciationTemplateRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineAppreciationTemplateRepository
|
|
|
|
App\Scolarite\Application\Port\EvaluationGradesChecker:
|
|
alias: App\Scolarite\Infrastructure\Service\NoGradesEvaluationGradesChecker
|
|
|
|
# Competency repositories (Story 6.5 - Mode compétences)
|
|
App\Scolarite\Domain\Repository\CompetencyFrameworkRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineCompetencyFrameworkRepository
|
|
|
|
App\Scolarite\Domain\Repository\CompetencyRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineCompetencyRepository
|
|
|
|
App\Scolarite\Domain\Repository\CompetencyEvaluationRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineCompetencyEvaluationRepository
|
|
|
|
App\Scolarite\Domain\Repository\StudentCompetencyResultRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineStudentCompetencyResultRepository
|
|
|
|
App\Scolarite\Domain\Repository\CustomCompetencyLevelRepository:
|
|
alias: App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineCustomCompetencyLevelRepository
|
|
|
|
# Averages (Story 6.3 - Calcul automatique des moyennes)
|
|
App\Scolarite\Domain\Service\AverageCalculator:
|
|
autowire: true
|
|
|
|
App\Scolarite\Application\Service\RecalculerMoyennesService:
|
|
autowire: true
|
|
|
|
App\Scolarite\Application\Port\PeriodFinder:
|
|
alias: App\Scolarite\Infrastructure\Service\DoctrinePeriodFinder
|
|
|
|
App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineEvaluationStatisticsRepository:
|
|
autowire: true
|
|
|
|
App\Scolarite\Infrastructure\Cache\CachingEvaluationStatisticsRepository:
|
|
arguments:
|
|
$inner: '@App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineEvaluationStatisticsRepository'
|
|
$cache: '@student_averages.cache'
|
|
|
|
App\Scolarite\Domain\Repository\EvaluationStatisticsRepository:
|
|
alias: App\Scolarite\Infrastructure\Cache\CachingEvaluationStatisticsRepository
|
|
|
|
App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineStudentAverageRepository:
|
|
autowire: true
|
|
|
|
App\Scolarite\Infrastructure\Cache\CachingStudentAverageRepository:
|
|
arguments:
|
|
$inner: '@App\Scolarite\Infrastructure\Persistence\Doctrine\DoctrineStudentAverageRepository'
|
|
$cache: '@student_averages.cache'
|
|
|
|
App\Scolarite\Domain\Repository\StudentAverageRepository:
|
|
alias: App\Scolarite\Infrastructure\Cache\CachingStudentAverageRepository
|
|
|
|
# Super Admin Repositories (Story 2.10 - Multi-établissements)
|
|
App\SuperAdmin\Domain\Repository\SuperAdminRepository:
|
|
alias: App\SuperAdmin\Infrastructure\Persistence\Doctrine\DoctrineSuperAdminRepository
|
|
|
|
App\SuperAdmin\Domain\Repository\EstablishmentRepository:
|
|
alias: App\SuperAdmin\Infrastructure\Persistence\Doctrine\DoctrineEstablishmentRepository
|
|
|
|
# Provisioning (Story 2.17 - Provisioning automatique)
|
|
App\SuperAdmin\Infrastructure\Provisioning\TenantDatabaseCreator:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
|
|
App\SuperAdmin\Infrastructure\Provisioning\TenantMigrator:
|
|
arguments:
|
|
$projectDir: '%kernel.project_dir%'
|
|
$masterDatabaseUrl: '%env(DATABASE_URL)%'
|
|
|
|
App\SuperAdmin\Application\Port\TenantProvisioner:
|
|
alias: App\SuperAdmin\Infrastructure\Provisioning\DatabaseTenantProvisioner
|
|
|
|
App\SuperAdmin\Infrastructure\Provisioning\ProvisionEstablishmentHandler:
|
|
arguments:
|
|
$masterDatabaseUrl: '%env(DATABASE_URL)%'
|
|
|
|
# School Calendar Repository (Story 2.11 - Calendrier scolaire)
|
|
App\Administration\Domain\Model\SchoolCalendar\SchoolCalendarRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineSchoolCalendarRepository
|
|
|
|
App\Administration\Application\Port\OfficialCalendarProvider:
|
|
alias: App\Administration\Infrastructure\Service\JsonOfficialCalendarProvider
|
|
|
|
App\Administration\Infrastructure\Service\JsonOfficialCalendarProvider:
|
|
arguments:
|
|
$dataDirectory: '%kernel.project_dir%/var/data/calendar'
|
|
|
|
# School Branding (Story 2.13 - Personnalisation visuelle)
|
|
App\Administration\Domain\Model\SchoolBranding\ContrastValidator:
|
|
autowire: true
|
|
|
|
App\Administration\Domain\Repository\SchoolBrandingRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineSchoolBrandingRepository
|
|
|
|
# Homework Rules Repository
|
|
App\Administration\Domain\Repository\HomeworkRulesRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineHomeworkRulesRepository
|
|
|
|
App\Administration\Domain\Repository\HomeworkRulesHistoryRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineHomeworkRulesHistoryRepository
|
|
|
|
App\Administration\Application\Port\LogoStorage:
|
|
alias: App\Administration\Infrastructure\Storage\LocalLogoStorage
|
|
|
|
App\Administration\Infrastructure\Storage\LocalLogoStorage:
|
|
arguments:
|
|
$uploadDir: '%kernel.project_dir%/public/uploads'
|
|
$publicPath: '/uploads'
|
|
|
|
App\Administration\Application\Port\ImageProcessor:
|
|
alias: App\Administration\Infrastructure\Storage\ImagickImageProcessor
|
|
|
|
# Import Batch Repository (Story 3.1 - Import élèves via CSV)
|
|
App\Administration\Domain\Repository\ImportBatchRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineImportBatchRepository
|
|
|
|
# Saved Column Mapping Repository (Story 3.1 - T3.3 Réutilisation des mappings)
|
|
App\Administration\Domain\Repository\SavedColumnMappingRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineSavedColumnMappingRepository
|
|
|
|
# Teacher Import Batch Repository (Story 3.2 - Import enseignants via CSV)
|
|
App\Administration\Domain\Repository\TeacherImportBatchRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineTeacherImportBatchRepository
|
|
|
|
# Saved Teacher Column Mapping Repository (Story 3.2 - Réutilisation des mappings enseignants)
|
|
App\Administration\Domain\Repository\SavedTeacherColumnMappingRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineSavedTeacherColumnMappingRepository
|
|
|
|
# Parent Invitation Repository (Story 3.3 - Invitation parents)
|
|
App\Administration\Domain\Repository\ParentInvitationRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Doctrine\DoctrineParentInvitationRepository
|
|
|
|
# Student Guardian Repository (Story 2.7 - Liaison parents-enfants)
|
|
App\Administration\Infrastructure\Persistence\Cache\CacheStudentGuardianRepository:
|
|
arguments:
|
|
$inner: '@App\Administration\Infrastructure\Persistence\Doctrine\DoctrineStudentGuardianRepository'
|
|
|
|
App\Administration\Domain\Repository\StudentGuardianRepository:
|
|
alias: App\Administration\Infrastructure\Persistence\Cache\CacheStudentGuardianRepository
|
|
|
|
# Paginated Read Model Ports
|
|
App\Administration\Application\Port\PaginatedUsersReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedUsersReader
|
|
|
|
App\Administration\Application\Port\PaginatedClassesReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedClassesReader
|
|
|
|
App\Administration\Application\Port\PaginatedSubjectsReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedSubjectsReader
|
|
|
|
App\Administration\Application\Port\PaginatedAssignmentsReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedAssignmentsReader
|
|
|
|
App\Administration\Application\Port\PaginatedParentInvitationsReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedParentInvitationsReader
|
|
|
|
App\Administration\Application\Port\PaginatedStudentImageRightsReader:
|
|
alias: App\Administration\Infrastructure\ReadModel\DbalPaginatedStudentImageRightsReader
|
|
|
|
# GradeExistenceChecker (stub until Notes module exists)
|
|
App\Administration\Application\Port\GradeExistenceChecker:
|
|
alias: App\Administration\Infrastructure\Service\NoOpGradeExistenceChecker
|
|
|
|
# ActiveRoleStore (session-scoped cache for active role switching)
|
|
App\Administration\Application\Port\ActiveRoleStore:
|
|
alias: App\Administration\Infrastructure\Service\CacheActiveRoleStore
|
|
|
|
# GeoLocation Service (null implementation - no geolocation)
|
|
App\Administration\Application\Port\GeoLocationService:
|
|
alias: App\Administration\Infrastructure\Service\NullGeoLocationService
|
|
|
|
# Password Reset Processor with rate limiters
|
|
App\Administration\Infrastructure\Api\Processor\RequestPasswordResetProcessor:
|
|
arguments:
|
|
$passwordResetByEmailLimiter: '@limiter.password_reset_by_email'
|
|
$passwordResetByIpLimiter: '@limiter.password_reset_by_ip'
|
|
|
|
# Parent Activation Processor with rate limiter
|
|
App\Administration\Infrastructure\Api\Processor\ActivateParentInvitationProcessor:
|
|
arguments:
|
|
$parentActivationByIpLimiter: '@limiter.parent_activation_by_ip'
|
|
|
|
# Login handlers
|
|
App\Administration\Infrastructure\Security\LoginSuccessHandler:
|
|
tags:
|
|
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccess }
|
|
|
|
App\Administration\Infrastructure\Security\LoginFailureHandler:
|
|
tags:
|
|
- { name: security.authentication_failure_handler, firewall: api_login }
|
|
|
|
# Rate Limiter (délai Fibonacci + CAPTCHA + blocage IP)
|
|
App\Shared\Infrastructure\RateLimit\LoginRateLimiter:
|
|
arguments:
|
|
$cache: '@cache.rate_limiter'
|
|
|
|
App\Shared\Infrastructure\RateLimit\LoginRateLimiterInterface:
|
|
alias: App\Shared\Infrastructure\RateLimit\LoginRateLimiter
|
|
|
|
# Rate Limit Listener (vérifie le rate limit AVANT authentification)
|
|
App\Shared\Infrastructure\RateLimit\LoginRateLimitListener:
|
|
arguments:
|
|
$rateLimiterCache: '@cache.rate_limiter'
|
|
|
|
# Turnstile CAPTCHA Validator
|
|
# failOpen: true en dev (ne pas bloquer si API down), false en prod (sécurité)
|
|
App\Shared\Infrastructure\Captcha\TurnstileValidator:
|
|
arguments:
|
|
$secretKey: '%env(TURNSTILE_SECRET_KEY)%'
|
|
$failOpen: '%env(bool:default::TURNSTILE_FAIL_OPEN)%'
|
|
|
|
App\Shared\Infrastructure\Captcha\TurnstileValidatorInterface:
|
|
alias: App\Shared\Infrastructure\Captcha\TurnstileValidator
|
|
|
|
# =============================================================================
|
|
# Monitoring & Observability (Story 1.8)
|
|
# =============================================================================
|
|
|
|
# Prometheus CollectorRegistry - uses Redis for persistence between requests
|
|
Prometheus\Storage\Redis:
|
|
factory: ['App\Shared\Infrastructure\Monitoring\PrometheusStorageFactory', 'createRedisStorage']
|
|
arguments:
|
|
$redisUrl: '%env(REDIS_URL)%'
|
|
|
|
Prometheus\CollectorRegistry:
|
|
arguments:
|
|
$storageAdapter: '@Prometheus\Storage\Redis'
|
|
|
|
# Sentry/GlitchTip PII scrubber callback
|
|
App\Shared\Infrastructure\Monitoring\SentryBeforeSendCallback: ~
|
|
|
|
# Infrastructure Health Checker - shared service for health checks (DRY)
|
|
App\Shared\Infrastructure\Monitoring\InfrastructureHealthChecker:
|
|
arguments:
|
|
$connection: '@doctrine.dbal.master_connection'
|
|
$redisUrl: '%env(REDIS_URL)%'
|
|
|
|
# Interface alias for InfrastructureHealthChecker (allows testing with stubs)
|
|
App\Shared\Infrastructure\Monitoring\InfrastructureHealthCheckerInterface:
|
|
alias: App\Shared\Infrastructure\Monitoring\InfrastructureHealthChecker
|
|
|
|
# Health Check Controller - uses shared InfrastructureHealthChecker
|
|
App\Shared\Infrastructure\Monitoring\HealthCheckController: ~
|
|
|
|
# Metrics Controller - restricted to internal networks in production
|
|
App\Shared\Infrastructure\Monitoring\MetricsController:
|
|
arguments:
|
|
$appEnv: '%kernel.environment%'
|
|
|
|
# Health Metrics Collector - exposes health_check_status gauge
|
|
App\Shared\Infrastructure\Monitoring\HealthMetricsCollector: ~
|
|
|
|
# Interface alias for HealthMetricsCollector (allows testing with stubs)
|
|
App\Shared\Infrastructure\Monitoring\HealthMetricsCollectorInterface:
|
|
alias: App\Shared\Infrastructure\Monitoring\HealthMetricsCollector
|
|
|
|
# Sentry context enricher - adds tenant/user/correlation_id to error reports
|
|
# Explicitly registered to ensure HubInterface dependency is resolved
|
|
App\Shared\Infrastructure\Monitoring\SentryContextEnricher:
|
|
arguments:
|
|
$sentryHub: '@Sentry\State\HubInterface'
|
|
|
|
# Monolog processors for structured logging
|
|
App\Shared\Infrastructure\Monitoring\CorrelationIdLogProcessor:
|
|
tags:
|
|
- { name: monolog.processor }
|
|
|
|
App\Shared\Infrastructure\Monitoring\PiiScrubberLogProcessor:
|
|
tags:
|
|
- { name: monolog.processor }
|
|
|
|
# =============================================================================
|
|
# Messenger & Async (Story 2.5b)
|
|
# =============================================================================
|
|
|
|
# Fibonacci retry strategy for async transport
|
|
App\Shared\Infrastructure\Messenger\FibonacciRetryStrategy: ~
|
|
|
|
# Dead-letter alert: sends admin email when message exhausts all retries
|
|
App\Shared\Infrastructure\Messenger\DeadLetterAlertHandler:
|
|
arguments:
|
|
$adminEmail: '%env(ADMIN_ALERT_EMAIL)%'
|
|
tags:
|
|
- { name: kernel.event_listener, event: Symfony\Component\Messenger\Event\WorkerMessageFailedEvent }
|
|
|
|
# Messenger metrics middleware (handled/failed counters)
|
|
App\Shared\Infrastructure\Messenger\MessengerMetricsMiddleware: ~
|
|
|
|
# Messenger queue metrics collector (messages waiting gauge)
|
|
App\Shared\Infrastructure\Monitoring\MessengerMetricsCollector: ~
|
|
|
|
# =============================================================================
|
|
# Test environment overrides
|
|
# =============================================================================
|
|
when@test:
|
|
services:
|
|
# Use null rate limiter in test environment to avoid IP blocking during E2E tests
|
|
App\Shared\Infrastructure\RateLimit\LoginRateLimiterInterface:
|
|
alias: App\Shared\Infrastructure\RateLimit\NullLoginRateLimiter
|
|
|
|
App\Shared\Infrastructure\RateLimit\NullLoginRateLimiter:
|
|
autowire: true
|