Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
90
90%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
project/
├── config/
│ ├── packages/
│ │ ├── doctrine.yaml
│ │ └── messenger.yaml
│ └── services.yaml
├── src/
│ ├── Domain/
│ ├── Application/
│ ├── Adapter/
│ ├── Infrastructure/
│ └── Kernel.php
├── tests/
│ ├── Unit/
│ ├── Integration/
│ └── Infrastructure/
└── composer.json{
"require": {
"php": ">=8.3",
"symfony/framework-bundle": "^7.0",
"symfony/dependency-injection": "^7.0",
"symfony/messenger": "^7.0",
"symfony/serializer": "^7.0",
"symfony/property-access": "^7.0",
"symfony/uid": "^7.0",
"doctrine/orm": "^3.0",
"doctrine/dbal": "^4.0"
},
"require-dev": {
"phpunit/phpunit": "^11.0",
"symfony/test-pack": "^1.0"
}
}# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/Domain/Entity/'
- '../src/Kernel.php'
# Bind interface to implementation
App\Domain\Repository\UserRepositoryInterface:
class: App\Adapter\Persistence\Doctrine\Repository\DoctrineUserRepository
App\Domain\Repository\OrderRepositoryInterface:
class: App\Adapter\Persistence\Doctrine\Repository\DoctrineOrderRepository# config/services.yaml
services:
# Primary: Doctrine implementation
App\Domain\Repository\UserRepositoryInterface:
alias: App\Adapter\Persistence\Doctrine\Repository\DoctrineUserRepository
# Alternative: In-memory for testing
App\Infrastructure\Repository\InMemoryUserRepository:
class: App\Infrastructure\Repository\InMemoryUserRepository
# Use named autowiring
App\Application\Handler\CreateUserHandler:
arguments:
$userRepository: '@App\Domain\Repository\UserRepositoryInterface'<?php
// src/Infrastructure/Service/SendgridEmailService.php
namespace App\Infrastructure\Service;
use App\Application\Service\EmailServiceInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
readonly class SendgridEmailService implements EmailServiceInterface
{
public function __construct(
#[Autowire('%env(SENDGRID_API_KEY)%')]
private string $apiKey,
#[Autowire('%env(SENDGRID_FROM_EMAIL)%')]
private string $fromEmail
) {
}
public function send(string $to, string $subject, string $body): void
{
// Sendgrid implementation
}
}<!-- config/doctrine/User.orm.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="App\Domain\Entity\User" table="users">
<id name="id" type="string" length="36">
<generator strategy="NONE"/>
</id>
<embedded name="email" class="App\Domain\ValueObject\Email"/>
<field name="name" type="string" length="100"/>
<field name="createdAt" type="datetime_immutable"/>
<field name="isActive" type="boolean"/>
</entity>
</doctrine-mapping><!-- config/doctrine/Email.orm.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping">
<embeddable name="App\Domain\ValueObject\Email">
<field name="value" type="string" column="email" length="255"/>
</embeddable>
</doctrine-mapping><?php
// src/Domain/Entity/User.php
namespace App\Domain\Entity;
use App\Domain\ValueObject\Email;
use App\Domain\ValueObject\UserId;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
#[ORM\Id]
#[ORM\Column(type: 'string', length: 36)]
private string $id;
#[ORM\Embedded(class: Email::class)]
private Email $email;
#[ORM\Column(type: 'string', length: 100)]
private string $name;
#[ORM\Column(type: 'datetime_immutable')]
private DateTimeImmutable $createdAt;
#[ORM\Column(type: 'boolean')]
private bool $isActive = true;
// ... methods
}<?php
// src/Adapter/Http/Controller/Api/UserController.php
namespace App\Adapter\Http\Controller\Api;
use App\Adapter\Http\Request\CreateUserRequest;
use App\Adapter\Http\Request\UpdateUserRequest;
use App\Application\Command\CreateUserCommand;
use App\Application\Command\UpdateUserCommand;
use App\Application\Handler\CreateUserHandler;
use App\Application\Handler\UpdateUserHandler;
use App\Application\Query\GetUserQuery;
use App\Domain\ValueObject\UserId;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Uid\Uuid;
#[AsController]
#[Route('/api/users')]
class UserController
{
public function __construct(
private CreateUserHandler $createHandler,
private UpdateUserHandler $updateHandler,
private GetUserQuery $getUserQuery
) {
}
#[Route('', methods: ['POST'])]
public function create(
#[MapRequestPayload] CreateUserRequest $request
): JsonResponse {
$id = Uuid::v4()->toRfc4122();
$command = new CreateUserCommand(
id: $id,
email: $request->email,
name: $request->name
);
($this->createHandler)($command);
return new JsonResponse(
['id' => $id, 'message' => 'User created'],
Response::HTTP_CREATED
);
}
#[Route('/{id}', methods: ['GET'])]
public function get(string $id): JsonResponse
{
$user = $this->getUserQuery->execute(new UserId($id));
if ($user === null) {
return new JsonResponse(
['error' => 'User not found'],
Response::HTTP_NOT_FOUND
);
}
return new JsonResponse($user);
}
#[Route('/{id}', methods: ['PUT'])]
public function update(
string $id,
#[MapRequestPayload] UpdateUserRequest $request
): JsonResponse {
$command = new UpdateUserCommand(
id: $id,
name: $request->name
);
($this->updateHandler)($command);
return new JsonResponse(['message' => 'User updated']);
}
}<?php
// src/Adapter/Http/Request/CreateUserRequest.php
namespace App\Adapter\Http\Request;
use Symfony\Component\Validator\Constraints as Assert;
class CreateUserRequest
{
#[Assert\NotBlank(message: 'Email is required')]
#[Assert\Email(message: 'Invalid email format')]
public string $email;
#[Assert\NotBlank(message: 'Name is required')]
#[Assert\Length(
min: 2,
max: 100,
minMessage: 'Name must be at least {{ limit }} characters',
maxMessage: 'Name cannot exceed {{ limit }} characters'
)]
public string $name;
}# config/packages/messenger.yaml
framework:
messenger:
default_bus: command.bus
buses:
command.bus:
middleware:
- doctrine_transaction_middleware
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
App\Application\Command\SendNotificationCommand: async<?php
// src/Application/Handler/CreateUserHandler.php
namespace App\Application\Handler;
use App\Application\Command\CreateUserCommand;
use App\Domain\Entity\User;
use App\Domain\Repository\UserRepositoryInterface;
use App\Domain\ValueObject\Email;
use App\Domain\ValueObject\UserId;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler(bus: 'command.bus')]
readonly class CreateUserHandler
{
public function __construct(
private UserRepositoryInterface $userRepository
) {
}
public function __invoke(CreateUserCommand $command): void
{
$user = User::create(
new UserId($command->id),
new Email($command->email),
$command->name
);
$this->userRepository->save($user);
}
}<?php
// src/Adapter/Http/Controller/UserController.php
use Symfony\Component\Messenger\MessageBusInterface;
class UserController
{
public function __construct(
private MessageBusInterface $commandBus
) {
}
#[Route('/api/users', methods: ['POST'])]
public function create(Request $request): JsonResponse
{
$data = json_decode($request->getContent(), true);
$command = new CreateUserCommand(
id: Uuid::v4()->toRfc4122(),
email: $data['email'],
name: $data['name']
);
$this->commandBus->dispatch($command);
return new JsonResponse(['id' => $command->id], 201);
}
}<?php
// src/Infrastructure/Event/DomainEventDispatcher.php
namespace App\Infrastructure\Event;
use App\Domain\Event\UserCreatedEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: UserCreatedEvent::class, method: 'onUserCreated')]
readonly class UserCreatedListener
{
public function __construct(
private LoggerInterface $logger,
private EmailServiceInterface $emailService
) {
}
public function onUserCreated(UserCreatedEvent $event): void
{
$this->logger->info('User created', ['user_id' => $event->userId]);
// Send welcome email
$this->emailService->sendWelcomeEmail($event->userId);
}
}<?php
// src/Adapter/Persistence/Doctrine/Repository/DoctrineUserRepository.php
namespace App\Adapter\Persistence\Doctrine\Repository;
use App\Domain\Entity\User;
use App\Domain\Repository\UserRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
readonly class DoctrineUserRepository implements UserRepositoryInterface
{
public function __construct(
private EntityManagerInterface $entityManager,
private EventDispatcherInterface $eventDispatcher
) {
}
public function save(User $user): void
{
$this->entityManager->persist($user);
$this->entityManager->flush();
// Dispatch domain events
foreach ($user->domainEvents() as $event) {
$this->eventDispatcher->dispatch($event);
}
$user->clearDomainEvents();
}
}<?php
// tests/Integration/Controller/UserControllerTest.php
namespace App\Tests\Integration\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class UserControllerTest extends WebTestCase
{
public function testCanCreateUser(): void
{
$client = static::createClient();
$client->request(
'POST',
'/api/users',
[],
[],
['CONTENT_TYPE' => 'application/json'],
json_encode([
'email' => 'test@example.com',
'name' => 'John Doe'
])
);
$this->assertResponseStatusCodeSame(201);
$response = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $response);
}
public function testReturns404ForNonExistentUser(): void
{
$client = static::createClient();
$client->request('GET', '/api/users/non-existent-id');
$this->assertResponseStatusCodeSame(404);
}
}<?php
// tests/Integration/Repository/UserRepositoryTest.php
namespace App\Tests\Integration\Repository;
use App\Domain\Entity\User;
use App\Domain\Repository\UserRepositoryInterface;
use App\Domain\ValueObject\Email;
use App\Domain\ValueObject\UserId;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class UserRepositoryTest extends KernelTestCase
{
private UserRepositoryInterface $repository;
protected function setUp(): void
{
self::bootKernel();
$this->repository = self::getContainer()->get(UserRepositoryInterface::class);
}
public function testCanSaveAndRetrieveUser(): void
{
$user = User::create(
UserId::generate(),
new Email('test@example.com'),
'John Doe'
);
$this->repository->save($user);
$retrieved = $this->repository->findById($user->id());
$this->assertNotNull($retrieved);
$this->assertTrue($user->email()->equals($retrieved->email()));
}
}<?php
// src/Infrastructure/Http/Exception/DomainExceptionHandler.php
namespace App\Infrastructure\Http\Exception;
use InvalidArgumentException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
class DomainExceptionHandler
{
public function onKernelException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
if ($exception instanceof InvalidArgumentException) {
$response = new JsonResponse([
'error' => 'Validation failed',
'message' => $exception->getMessage()
], Response::HTTP_BAD_REQUEST);
$event->setResponse($response);
return;
}
// Handle other domain exceptions
if ($exception instanceof DomainException) {
$response = new JsonResponse([
'error' => 'Domain error',
'message' => $exception->getMessage()
], Response::HTTP_UNPROCESSABLE_ENTITY);
$event->setResponse($response);
}
}
}# config/services.yaml
services:
App\Infrastructure\Http\Exception\DomainExceptionHandler:
tags:
- { name: kernel.event_listener, event: kernel.exception }<?php
// src/Application/Query/QueryInterface.php
namespace App\Application\Query;
interface QueryInterface
{
}<?php
// src/Application/Query/GetUserQuery.php
namespace App\Application\Query;
use App\Domain\Repository\UserRepositoryInterface;
use App\Domain\ValueObject\UserId;
readonly class GetUserQuery
{
public function __construct(
private UserRepositoryInterface $userRepository
) {
}
public function execute(UserId $id): ?array
{
$user = $this->userRepository->findById($id);
if ($user === null) {
return null;
}
return [
'id' => $user->id()->value(),
'email' => $user->email()->value(),
'name' => $user->name(),
'createdAt' => $user->createdAt()->format('c'),
'isActive' => $user->isActive()
];
}
}Use Attributes: Leverage PHP 8 attributes for routing, validation, DI, and event listening.
Keep Controllers Thin: Controllers should only handle HTTP concerns and delegate to application layer.
Use DTOs: Separate request/response DTOs from domain entities.
Validation at Boundaries: Validate input at the adapter layer (controllers), not in domain.
Messenger for Async: Use Symfony Messenger for commands that need async processing.
XML/Attribute Mapping: Prefer XML or PHP 8 attributes for Doctrine mapping over annotations.
Service Autoconfiguration: Let Symfony autoconfigure your services, only override when necessary.
Test with Real Container: Use KernelTestCase for integration tests with real DI container.
Environment Variables: Use %env()% for configuration that changes per environment.
Monolog for Logging: Use PSR-3 logger interface in domain, Monolog implementation in infrastructure.
docs
plugins
developer-kit-ai
developer-kit-aws
agents
docs
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
aws-cloudformation-bedrock
aws-cloudformation-cloudfront
aws-cloudformation-cloudwatch
aws-cloudformation-dynamodb
aws-cloudformation-ec2
aws-cloudformation-ecs
aws-cloudformation-elasticache
references
aws-cloudformation-iam
references
aws-cloudformation-lambda
aws-cloudformation-rds
aws-cloudformation-s3
aws-cloudformation-security
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
references
developer-kit-core
agents
commands
skills
developer-kit-devops
developer-kit-java
agents
commands
docs
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
clean-architecture
graalvm-native-image
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
references
unit-test-controller-layer
unit-test-exception-handler
references
unit-test-json-serialization
unit-test-mapper-converter
references
unit-test-parameterized
unit-test-scheduled-async
references
unit-test-service-layer
references
unit-test-utility-methods
unit-test-wiremock-rest-api
references
developer-kit-php
developer-kit-project-management
developer-kit-python
developer-kit-specs
commands
docs
hooks
test-templates
tests
skills
developer-kit-tools
developer-kit-typescript
agents
docs
hooks
rules
skills
aws-cdk
aws-lambda-typescript-integration
better-auth
clean-architecture
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
shadcn-ui
tailwind-css-patterns
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities
references
github-spec-kit