"""Lambda entrypoint.""" from lambdacommon.common_config import logger from src.logging_setup import setup_logging from src.logic.notifications import send_streams_updated_notification from src.logic.store_state import get_latest_store_states, get_updated_states, load_store_states, save_store_states from src.models.process_summary import ProcessSummary from src.models.store import Store from src.schemas import ProcessSummarySchema setup_logging() SUPPORTED_STORES = (Store.SPOTIFY,) def process_states() -> ProcessSummary: """Get latest store states, trigger notification, and save new states. The operation is designed to be idempotent. We treat the notification and state update as a single transaction; the state is only committed after the notification is successfully dispatched. This prevents state drift and guarantees that failed notifications will be retried. """ summary = ProcessSummary() latest_store_states = get_latest_store_states(SUPPORTED_STORES) saved_store_states = load_store_states(SUPPORTED_STORES) summary.updated = get_updated_states(latest_store_states, saved_store_states) if summary.updated: logger.info(f'Got {len(summary.updated)} new states') else: logger.info('No updated states.') return summary for store_state in summary.updated: try: send_streams_updated_notification(store_state) logger.info(f'Notification sent for {store_state.store.name}') summary.succeeded.append(store_state) except Exception: logger.exception('Something went wrong while sending streams updated notification') summary.failed.append(store_state) if summary.succeeded: save_store_states(summary.succeeded) logger.info(f'States saved for {len(summary.succeeded)} stores') return summary def handler(event, context) -> dict: """Lambda entrypoint.""" result = process_states() schema = ProcessSummarySchema() return schema.dump(result)