Livre l'infrastructure permettant aux modules metier de declarer leurs entites comme "scopees par site" via SiteAwareInterface. Strictement opt-in : aucune entite metier touchee, aucune migration sur tables existantes. Composants : - SiteAwareInterface (Shared/Domain/Contract) : getSite/setSite - CurrentSiteProvider + interface (Module/Sites/Application) : resolve ?Site selon 3 conditions (module actif, user authentifie, currentSite). Interface extraite pour mockabilite en tests (implementation reste final). - SiteScopedQueryExtension : QueryCollection + QueryItem API Platform, ajoute WHERE site = :currentSite si resource SiteAware + provider non-null + pas sites.bypass_scope. - SiteAwareInjectionProcessor : decorator de api_platform.doctrine.orm. state.persist_processor (#[AsDecorator]). Injecte currentSite sur entites SiteAware sans site ; throw 400 si provider null. - Permission sites.bypass_scope declaree dans SitesModule::permissions(). Tests : - FakeSiteAwareEntity dans tests/Fixtures/ + mapping when@test dans doctrine.yaml. Table creee a la volee via SchemaTool dans setUp. schema:update --force ajoute dans test-db-setup pour que fixtures:load ne crashe pas au purger. - 17 tests dedies au ticket 4 (CurrentSiteProvider unitaire, Injection Processor unitaire, Extension integration avec 7 cas couvrant filtrage collection + item, bypass, no-op, resource non SiteAware). - SitesModuleTest : verifie le set de 3 permissions + que le decorator est bien enregistre sur le persist processor. Documentation docs/modules/site-aware.md : guide developpeur 8 sections (quand/ne pas adopter, comment, migration, mode degrade, anti-patterns, exemple d'adoption Supplier, cascade delete). Upgrade @malio/layer-ui 1.4.0 → 1.4.2 (bug 1.4.0 : tailwind.config.ts oublie dans les files publies npm → classe rounded-malio manquante sur les DataTables). Simplification tailwind.config.ts Coltura : retrait des colors/fontFamily/borderRadius dupliques, seule la specifique projet (primary, secondary, tertiary, m.secondary, m.tertiary) est conservee. Tests : 201/201 avec et sans SitesModule actif (2 skipped en disabled). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
70 lines
1.7 KiB
PHP
70 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Fixtures\SiteAware;
|
|
|
|
use App\Module\Sites\Domain\Entity\Site;
|
|
use App\Shared\Domain\Contract\SiteAwareInterface;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
|
|
/**
|
|
* Entite fictive utilisee UNIQUEMENT en tests (ticket 4 module Sites).
|
|
*
|
|
* Implemente SiteAwareInterface pour valider que l'outillage
|
|
* (SiteScopedQueryExtension + SiteAwareInjectionProcessor) se comporte
|
|
* correctement sans avoir a adopter le pattern sur une entite metier
|
|
* reelle. Le mapping Doctrine n'est charge qu'en environnement `test`
|
|
* via un bloc `when@test` dans `config/packages/doctrine.yaml`, donc
|
|
* cette classe n'existe jamais dans un schema prod.
|
|
*
|
|
* Le nom de table `fake_site_aware_entity` est volontairement verbeux
|
|
* pour reduire le risque de collision avec une future table metier.
|
|
*/
|
|
#[ORM\Entity]
|
|
#[ORM\Table(name: 'fake_site_aware_entity')]
|
|
class FakeSiteAwareEntity implements SiteAwareInterface
|
|
{
|
|
#[ORM\Id]
|
|
#[ORM\GeneratedValue]
|
|
#[ORM\Column]
|
|
private ?int $id = null;
|
|
|
|
#[ORM\Column(length: 100)]
|
|
private string $name;
|
|
|
|
#[ORM\ManyToOne(targetEntity: Site::class)]
|
|
#[ORM\JoinColumn(name: 'site_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
|
private ?Site $site = null;
|
|
|
|
public function __construct(string $name)
|
|
{
|
|
$this->name = $name;
|
|
}
|
|
|
|
public function getId(): ?int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getName(): string
|
|
{
|
|
return $this->name;
|
|
}
|
|
|
|
public function setName(string $name): void
|
|
{
|
|
$this->name = $name;
|
|
}
|
|
|
|
public function getSite(): ?Site
|
|
{
|
|
return $this->site;
|
|
}
|
|
|
|
public function setSite(Site $site): void
|
|
{
|
|
$this->site = $site;
|
|
}
|
|
}
|