from datetime import datetime, timezone from sqlalchemy import select from sqlalchemy.orm import Session from app.config import settings from app.core.security import create_access_token, hash_phone, mask_phone from app.db.models import Tenant, User from app.schemas.models import LoginRequest, LoginType def authenticate(db: Session, body: LoginRequest) -> tuple[User, str]: if body.login_type == LoginType.phone_code: if body.code != settings.demo_sms_code: raise ValueError("invalid_code") phone = body.credential phone_hash = hash_phone(phone) user = db.scalar(select(User).where(User.phone_hash == phone_hash)) if not user: tenant = db.scalar(select(Tenant).where(Tenant.name == "Demo Organization")) if not tenant: tenant = Tenant(name="Demo Organization", type="organization", status="active") db.add(tenant) db.flush() user = User( tenant_id=tenant.id, phone=phone, phone_hash=phone_hash, role="parent", status="active", consent_signed=True, ) db.add(user) db.flush() user.last_login_at = datetime.now(timezone.utc) db.commit() db.refresh(user) token = create_access_token(user.id, user.role) return user, token raise ValueError("unsupported_login_type") def user_to_dict(user: User) -> dict: return { "id": user.id, "phoneMasked": mask_phone(user.phone or ""), "role": user.role, }