"""Ban response mappers. Convert domain models (from ban_service) to response models (for HTTP API). This is the mapping layer at the router boundary, ensuring the service layer remains independent of HTTP response shapes. """ from __future__ import annotations from app.models.ban import ( ActiveBan, ActiveBanListResponse, BansByCountryResponse, BansByJailResponse, BanTrendBucket, BanTrendResponse, DashboardBanItem, DashboardBanListResponse, JailBanCount, ) from app.models.ban_domain import ( DomainActiveBan, DomainActiveBanList, DomainBansByCountry, DomainBansByJail, DomainBanTrend, DomainDashboardBanItem, DomainDashboardBanList, ) from app.utils.pagination import create_pagination_metadata def map_domain_active_ban_to_response(domain_ban: DomainActiveBan) -> ActiveBan: """Convert a domain active ban to a response model.""" return ActiveBan( ip=domain_ban.ip, jail=domain_ban.jail, banned_at=domain_ban.banned_at, expires_at=domain_ban.expires_at, ban_count=domain_ban.ban_count, country=domain_ban.country, ) def map_domain_active_ban_list_to_response( domain_list: DomainActiveBanList, ) -> ActiveBanListResponse: """Convert a domain active ban list to a response model.""" return ActiveBanListResponse( items=[map_domain_active_ban_to_response(ban) for ban in domain_list.bans], total=domain_list.total, ) def map_domain_dashboard_ban_item_to_response( domain_item: DomainDashboardBanItem, ) -> DashboardBanItem: """Convert a domain dashboard ban item to a response model.""" return DashboardBanItem( ip=domain_item.ip, jail=domain_item.jail, banned_at=domain_item.banned_at, service=domain_item.service, country_code=domain_item.country_code, country_name=domain_item.country_name, asn=domain_item.asn, org=domain_item.org, ban_count=domain_item.ban_count, origin=domain_item.origin, ) def map_domain_dashboard_ban_list_to_response( domain_list: DomainDashboardBanList, ) -> DashboardBanListResponse: """Convert a domain dashboard ban list to a response model.""" return DashboardBanListResponse( items=[ map_domain_dashboard_ban_item_to_response(item) for item in domain_list.items ], pagination=create_pagination_metadata(domain_list.total, domain_list.page, domain_list.page_size), ) def map_domain_bans_by_country_to_response( domain_data: DomainBansByCountry, ) -> BansByCountryResponse: """Convert domain bans-by-country data to a response model.""" return BansByCountryResponse( countries=domain_data.countries, country_names=domain_data.country_names, bans=[map_domain_dashboard_ban_item_to_response(item) for item in domain_data.items], total=domain_data.total, ) def map_domain_ban_trend_to_response(domain_trend: DomainBanTrend) -> BanTrendResponse: """Convert domain ban trend data to a response model.""" return BanTrendResponse( buckets=[ BanTrendBucket(timestamp=bucket.timestamp, count=bucket.count) for bucket in domain_trend.buckets ], bucket_size=domain_trend.bucket_size, ) def map_domain_bans_by_jail_to_response( domain_data: DomainBansByJail, ) -> BansByJailResponse: """Convert domain bans-by-jail data to a response model.""" return BansByJailResponse( jails=[ JailBanCount(jail=jail_count.jail, count=jail_count.count) for jail_count in domain_data.jails ], total=domain_data.total, )