import uuid from repositories.pocketbase_client import pb_client from repositories.repo_config import USE_MOCK_REPOSITORIES COLLECTION = 'price_history' class PriceHistoryRepository: """Data access for the `price_history` collection.""" def create(self, data): return pb_client.create(COLLECTION, data) def list_for_product(self, product_id, limit=50): return pb_client.list( COLLECTION, filter_str=f'product_id = "{product_id}"', sort='-scraped_at', per_page=limit ) def list_for_tenant(self, tenant_id): """Used for GDPR erasure — every price_history row for a tenant, not just one product's.""" return pb_client.list(COLLECTION, filter_str=f'tenant_id = "{tenant_id}"', per_page=500) def list_older_than(self, cutoff_iso): """Used by the weekly data-cleanup job — CLAUDE.md §22 DATA_RETENTION (365 days for price_history).""" return pb_client.list(COLLECTION, filter_str=f'scraped_at < "{cutoff_iso}"', per_page=500) def delete(self, record_id): return pb_client.delete(COLLECTION, record_id) class MockPriceHistoryRepository: """In-memory stand-in for PriceHistoryRepository.""" def __init__(self): self._records = {} def create(self, data): record_id = data.get('id') or str(uuid.uuid4()) record = {'id': record_id, **data} self._records[record_id] = record return record def list_for_product(self, product_id, limit=50): items = [r for r in self._records.values() if r.get('product_id') == product_id] items.sort(key=lambda r: r.get('scraped_at') or '', reverse=True) return items[:limit] def list_for_tenant(self, tenant_id): return [r for r in self._records.values() if r.get('tenant_id') == tenant_id] def list_older_than(self, cutoff_iso): return [r for r in self._records.values() if (r.get('scraped_at') or '') < cutoff_iso] def delete(self, record_id): return self._records.pop(record_id, None) is not None price_history_repository = MockPriceHistoryRepository() if USE_MOCK_REPOSITORIES else PriceHistoryRepository()