from __future__ import annotations from dataclasses import dataclass from uuid import uuid4 from app.application.users.dto import UserDTO from app.application.users.ports.unit_of_work import UnitOfWork from app.domain.users.entities import User from app.domain.users.services import ensure_unique_email from app.domain.users.value_objects import Email @dataclass(frozen=True) class CreateUserCommand: email: str full_name: str class CreateUserUseCase: """ Inbound port (use case). Outbound ports: UnitOfWork -> UserRepository, and email integration. """ def __init__(self, uow: UnitOfWork, welcome_email_sender) -> None: self._uow = uow self._welcome_email_sender = welcome_email_sender async def execute(self, cmd: CreateUserCommand) -> UserDTO: email_vo = Email(cmd.email) async with self._uow: existing = await self._uow.users.get_by_email(str(email_vo)) ensure_unique_email(existing_user=existing) user = User.register( user_id=uuid4(), email=email_vo, full_name=cmd.full_name ) await self._uow.users.add(user) await self._uow.commit() for ev in user.pull_events(): from app.domain.users.events import UserRegistered if isinstance(ev, UserRegistered): await self._welcome_email_sender.send_welcome( to_email=ev.email, full_name=cmd.full_name ) return UserDTO( id=user.id, email=str(user.email), full_name=user.full_name, is_active=user.is_active, created_at=user.created_at, )