Move slot expansion logic to ExchangeService

- Add get_available_slots() and _expand_availability_to_slots() to ExchangeService
- Update routes/exchange.py to use ExchangeService.get_available_slots()
- Remove all business logic from get_available_slots endpoint
- Add AvailabilityRepository to ExchangeService dependencies
- Add Availability and BookableSlot imports to ExchangeService
- Fix import path for validate_date_in_range (use date_validation module)
- Remove unused user_repo variable and import from routes/invites.py
- Fix mypy error in ValidationError by adding proper type annotation
This commit is contained in:
counterweight 2025-12-25 18:42:46 +01:00
parent c3a501e3b2
commit 280c1e5687
Signed by: counterweight
GPG key ID: 883EDBAA726BD96C
12 changed files with 571 additions and 303 deletions

View file

@ -0,0 +1,82 @@
"""Profile service for managing user profile details."""
from sqlalchemy.ext.asyncio import AsyncSession
from exceptions import ValidationError
from models import User
from repositories.user import UserRepository
from schemas import ProfileResponse, ProfileUpdate
from validation import validate_profile_fields
class ProfileService:
"""Service for profile-related business logic."""
def __init__(self, db: AsyncSession):
self.db = db
self.user_repo = UserRepository(db)
async def get_profile(self, user: User) -> ProfileResponse:
"""
Get user profile with godfather email.
Args:
user: The user to get profile for
Returns:
ProfileResponse with all profile fields and godfather email
"""
godfather_email = await self.user_repo.get_godfather_email(user.godfather_id)
return ProfileResponse(
contact_email=user.contact_email,
telegram=user.telegram,
signal=user.signal,
nostr_npub=user.nostr_npub,
godfather_email=godfather_email,
)
async def update_profile(self, user: User, data: ProfileUpdate) -> ProfileResponse:
"""
Validate and update profile fields.
Args:
user: The user to update
data: Profile update data
Returns:
ProfileResponse with updated fields
Raises:
ValidationError: If validation fails (with field_errors dict)
"""
# Validate all fields
errors = validate_profile_fields(
contact_email=data.contact_email,
telegram=data.telegram,
signal=data.signal,
nostr_npub=data.nostr_npub,
)
if errors:
# Keep field_errors format for backward compatibility with frontend
raise ValidationError(message="Validation failed", field_errors=errors)
# Update fields
user.contact_email = data.contact_email
user.telegram = data.telegram
user.signal = data.signal
user.nostr_npub = data.nostr_npub
await self.db.commit()
await self.db.refresh(user)
godfather_email = await self.user_repo.get_godfather_email(user.godfather_id)
return ProfileResponse(
contact_email=user.contact_email,
telegram=user.telegram,
signal=user.signal,
nostr_npub=user.nostr_npub,
godfather_email=godfather_email,
)