"""Blocklist response mappers. Convert domain models (from blocklist_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.blocklist import ( BlocklistSource, ImportLogEntry, ImportLogListResponse, ImportRunResult, ImportSourceResult, PreviewResponse, ScheduleConfig, ScheduleFrequency, ScheduleInfo, ) from app.models.blocklist_domain import ( DomainBlocklistSource, DomainImportLogEntry, DomainImportLogList, DomainImportRunResult, DomainImportSourceResult, DomainPreviewResult, DomainScheduleConfig, DomainScheduleFrequency, DomainScheduleInfo, ) from app.utils.pagination import create_pagination_metadata def map_domain_blocklist_source_to_response( domain: DomainBlocklistSource, ) -> BlocklistSource: """Convert domain blocklist source to response model.""" return BlocklistSource( id=domain.id, name=domain.name, url=domain.url, enabled=domain.enabled, created_at=domain.created_at, updated_at=domain.updated_at, ) def map_domain_import_log_entry_to_response( domain: DomainImportLogEntry, ) -> ImportLogEntry: """Convert domain import log entry to response model.""" return ImportLogEntry( id=domain.id, source_id=domain.source_id, source_url=domain.source_url, timestamp=domain.timestamp, ips_imported=domain.ips_imported, ips_skipped=domain.ips_skipped, errors=domain.errors, ) def map_domain_import_log_list_to_response( domain_list: DomainImportLogList, ) -> ImportLogListResponse: """Convert domain import log list to response model.""" return ImportLogListResponse( items=[map_domain_import_log_entry_to_response(i) for i in domain_list.items], pagination=create_pagination_metadata( domain_list.total, domain_list.page, domain_list.page_size ), ) def map_domain_schedule_frequency_to_response( domain: DomainScheduleFrequency, ) -> ScheduleFrequency: """Convert domain schedule frequency to response model.""" return ScheduleFrequency(domain.value) def map_domain_schedule_config_to_response( domain: DomainScheduleConfig, ) -> ScheduleConfig: """Convert domain schedule config to response model.""" return ScheduleConfig( frequency=map_domain_schedule_frequency_to_response(domain.frequency), interval_hours=domain.interval_hours, hour=domain.hour, minute=domain.minute, day_of_week=domain.day_of_week, ) def map_domain_schedule_info_to_response(domain: DomainScheduleInfo) -> ScheduleInfo: """Convert domain schedule info to response model.""" return ScheduleInfo( config=map_domain_schedule_config_to_response(domain.config), next_run_at=domain.next_run_at, last_run_at=domain.last_run_at, last_run_errors=domain.last_run_errors, ) def map_domain_preview_result_to_response(domain: DomainPreviewResult) -> PreviewResponse: """Convert domain preview result to response model.""" return PreviewResponse( entries=domain.entries, total_lines=domain.total_lines, valid_count=domain.valid_count, skipped_count=domain.skipped_count, ) def map_domain_import_source_result_to_response( domain: DomainImportSourceResult, ) -> ImportSourceResult: """Convert domain import source result to response model.""" return ImportSourceResult( source_id=domain.source_id, source_url=domain.source_url, ips_imported=domain.ips_imported, ips_skipped=domain.ips_skipped, error=domain.error, ) def map_domain_import_run_result_to_response( domain: DomainImportRunResult, ) -> ImportRunResult: """Convert domain import run result to response model.""" return ImportRunResult( results=[ map_domain_import_source_result_to_response(r) for r in domain.results ], total_imported=domain.total_imported, total_skipped=domain.total_skipped, errors_count=domain.errors_count, )