feat: add Doctrine repository implementations and wire interfaces in services.yaml

This commit is contained in:
Simon Kuehn 2026-05-14 04:31:33 +00:00
parent 047c3e2588
commit a9c377789e
6 changed files with 239 additions and 0 deletions

View file

@ -10,3 +10,18 @@ services:
exclude:
- '../src/Domain/'
- '../src/Kernel.php'
App\Domain\Article\Repository\ArticleRepositoryInterface:
alias: App\Infrastructure\Persistence\Repository\DoctrineArticleRepository
App\Domain\Article\Repository\ArticleTypeRepositoryInterface:
alias: App\Infrastructure\Persistence\Repository\DoctrineArticleTypeRepository
App\Domain\Channel\Repository\PlatformRepositoryInterface:
alias: App\Infrastructure\Persistence\Repository\DoctrinePlatformRepository
App\Domain\Order\Repository\CustomerRepositoryInterface:
alias: App\Infrastructure\Persistence\Repository\DoctrineCustomerRepository
App\Domain\Order\Repository\OrderRepositoryInterface:
alias: App\Infrastructure\Persistence\Repository\DoctrineOrderRepository

View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace App\Infrastructure\Persistence\Repository;
use App\Domain\Article\Article;
use App\Domain\Article\ArticleStatus;
use App\Domain\Article\Repository\ArticleRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrineArticleRepository implements ArticleRepositoryInterface
{
public function __construct(private readonly EntityManagerInterface $em) {}
public function findById(Uuid $id): ?Article
{
return $this->em->find(Article::class, $id);
}
public function findBySku(string $sku): ?Article
{
return $this->em->getRepository(Article::class)->findOneBy(['sku' => $sku]);
}
public function findByInventoryNumber(string $inventoryNumber): ?Article
{
return $this->em->getRepository(Article::class)->findOneBy(['inventoryNumber' => $inventoryNumber]);
}
/** @return list<Article> */
public function findByStatus(ArticleStatus $status): array
{
/** @var list<Article> */
return $this->em->getRepository(Article::class)->findBy(['status' => $status]);
}
public function decrementStockAtomic(Uuid $articleId): bool
{
$affected = $this->em->getConnection()->executeStatement(
'UPDATE app.articles SET stock = stock - 1 WHERE id = :id AND stock > 0',
['id' => $articleId->toRfc4122()],
);
if ($affected > 0) {
$article = $this->em->find(Article::class, $articleId);
if (null !== $article) {
$this->em->refresh($article);
}
}
return $affected > 0;
}
public function save(Article $article): void
{
$this->em->persist($article);
$this->em->flush();
}
public function remove(Article $article): void
{
$this->em->remove($article);
$this->em->flush();
}
}

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Infrastructure\Persistence\Repository;
use App\Domain\Article\ArticleType;
use App\Domain\Article\Repository\ArticleTypeRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrineArticleTypeRepository implements ArticleTypeRepositoryInterface
{
public function __construct(private readonly EntityManagerInterface $em) {}
public function findById(Uuid $id): ?ArticleType
{
return $this->em->find(ArticleType::class, $id);
}
public function findByName(string $name): ?ArticleType
{
return $this->em->getRepository(ArticleType::class)->findOneBy(['name' => $name]);
}
/** @return list<ArticleType> */
public function findAll(): array
{
/** @var list<ArticleType> */
return $this->em->getRepository(ArticleType::class)->findAll();
}
public function save(ArticleType $articleType): void
{
$this->em->persist($articleType);
$this->em->flush();
}
}

View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace App\Infrastructure\Persistence\Repository;
use App\Domain\Order\Customer;
use App\Domain\Order\Repository\CustomerRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrineCustomerRepository implements CustomerRepositoryInterface
{
public function __construct(private readonly EntityManagerInterface $em) {}
public function findById(Uuid $id): ?Customer
{
return $this->em->find(Customer::class, $id);
}
public function findByPlatformId(string $platform, string $platformUserId): ?Customer
{
return $this->em->getRepository(Customer::class)
->createQueryBuilder('c')
->where("JSON_UNQUOTE(JSON_EXTRACT(c.platformIds, :path)) = :id")
->setParameter('path', '$."'.$platform.'"')
->setParameter('id', $platformUserId)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
public function findByMatchingKey(string $matchingKey): ?Customer
{
$customers = $this->em->getRepository(Customer::class)->findAll();
foreach ($customers as $customer) {
if ($customer->getMatchingKey() === $matchingKey) {
return $customer;
}
}
return null;
}
public function save(Customer $customer): void
{
$this->em->persist($customer);
$this->em->flush();
}
}

View file

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Infrastructure\Persistence\Repository;
use App\Domain\Order\Order;
use App\Domain\Order\Repository\OrderRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrineOrderRepository implements OrderRepositoryInterface
{
public function __construct(private readonly EntityManagerInterface $em) {}
public function findById(Uuid $id): ?Order
{
return $this->em->find(Order::class, $id);
}
public function findByPlatformOrderId(string $platformOrderId): ?Order
{
return $this->em->getRepository(Order::class)->findOneBy(['platformOrderId' => $platformOrderId]);
}
public function save(Order $order): void
{
$this->em->persist($order);
$this->em->flush();
}
}

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Infrastructure\Persistence\Repository;
use App\Domain\Channel\Platform;
use App\Domain\Channel\Repository\PlatformRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrinePlatformRepository implements PlatformRepositoryInterface
{
public function __construct(private readonly EntityManagerInterface $em) {}
public function findById(Uuid $id): ?Platform
{
return $this->em->find(Platform::class, $id);
}
public function findByType(string $type): ?Platform
{
return $this->em->getRepository(Platform::class)->findOneBy(['type' => $type]);
}
/** @return list<Platform> */
public function findAll(): array
{
/** @var list<Platform> */
return $this->em->getRepository(Platform::class)->findAll();
}
public function save(Platform $platform): void
{
$this->em->persist($platform);
$this->em->flush();
}
}