"""User service. Account creation here is a temporary, open dev bootstrap so we can create tree owners before the auth slice exists; the auth slice replaces it with the AuthProvider (password/OIDC/social) and proper verification. """ import uuid from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.user import User from app.repositories.base import BaseRepository from app.services.audit import record_audit from app.services.exceptions import Conflict async def create_user( session: AsyncSession, *, email: str, display_name: str | None = None ) -> User: email = email.strip().lower() existing = ( await session.execute(select(User).where(User.email == email)) ).scalar_one_or_none() if existing is not None: raise Conflict("email already registered") user = User(email=email, display_name=display_name) session.add(user) await session.flush() # assign user.id record_audit( session, action="create", entity_type="User", entity_id=user.id, actor_user_id=user.id, after={"email": email}, ) await session.commit() await session.refresh(user) return user async def get_user(session: AsyncSession, user_id: uuid.UUID) -> User | None: return await BaseRepository(session, User).get(user_id)