"""Pack a Modelling Run's resolved properties into SQS-message-sized batches. Batches stay postcode-grouped — properties sharing a postcode ride the same message so the workers' prediction cohort cache keeps paying (ADR-0055), the same packing the trigger script has been running. """ from backend.app.modelling.property_filters import FilteredProperty from utilities.grouped_batching import iter_grouped_batches BATCH_SIZE = 50 def pack_postcode_batches( properties: list[FilteredProperty], batch_size: int = BATCH_SIZE ) -> list[list[FilteredProperty]]: """Pack *properties* into batches of ~*batch_size*, never splitting a postcode across batches. A single postcode larger than *batch_size* becomes its own oversized batch.""" return list( iter_grouped_batches( properties, key=lambda p: p.postcode or "", max_batch_size=batch_size ) )