feat(espocrm): Implement automatic pagination for related records and enforce API max page size
This commit is contained in:
@@ -331,6 +331,9 @@ class EspoCRMAPI:
|
|||||||
params=self._flatten_params(search_params)
|
params=self._flatten_params(search_params)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# EspoCRM API-User limit: maxSize ≥ 500 → 403 Access forbidden
|
||||||
|
ESPOCRM_MAX_PAGE_SIZE = 200
|
||||||
|
|
||||||
async def list_related(
|
async def list_related(
|
||||||
self,
|
self,
|
||||||
entity_type: str,
|
entity_type: str,
|
||||||
@@ -343,9 +346,11 @@ class EspoCRMAPI:
|
|||||||
offset: int = 0,
|
offset: int = 0,
|
||||||
max_size: int = 50
|
max_size: int = 50
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
|
# Clamp max_size to avoid 403 from EspoCRM permission limit
|
||||||
|
safe_size = min(max_size, self.ESPOCRM_MAX_PAGE_SIZE)
|
||||||
search_params: Dict[str, Any] = {
|
search_params: Dict[str, Any] = {
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
'maxSize': max_size,
|
'maxSize': safe_size,
|
||||||
}
|
}
|
||||||
if where:
|
if where:
|
||||||
search_params['where'] = where
|
search_params['where'] = where
|
||||||
@@ -362,6 +367,39 @@ class EspoCRMAPI:
|
|||||||
params=self._flatten_params(search_params)
|
params=self._flatten_params(search_params)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def list_related_all(
|
||||||
|
self,
|
||||||
|
entity_type: str,
|
||||||
|
entity_id: str,
|
||||||
|
link: str,
|
||||||
|
where: Optional[List[Dict]] = None,
|
||||||
|
select: Optional[str] = None,
|
||||||
|
order_by: Optional[str] = None,
|
||||||
|
order: Optional[str] = None,
|
||||||
|
) -> List[Dict[str, Any]]:
|
||||||
|
"""Fetch ALL related records via automatic pagination (safe page size)."""
|
||||||
|
page_size = self.ESPOCRM_MAX_PAGE_SIZE
|
||||||
|
offset = 0
|
||||||
|
all_records: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
while True:
|
||||||
|
result = await self.list_related(
|
||||||
|
entity_type, entity_id, link,
|
||||||
|
where=where, select=select,
|
||||||
|
order_by=order_by, order=order,
|
||||||
|
offset=offset, max_size=page_size
|
||||||
|
)
|
||||||
|
page = result.get('list', [])
|
||||||
|
all_records.extend(page)
|
||||||
|
total = result.get('total', len(all_records))
|
||||||
|
|
||||||
|
if len(all_records) >= total or len(page) < page_size:
|
||||||
|
break
|
||||||
|
offset += page_size
|
||||||
|
|
||||||
|
self._log(f"list_related_all {entity_type}/{entity_id}/{link}: {len(all_records)}/{total} records")
|
||||||
|
return all_records
|
||||||
|
|
||||||
async def create_entity(
|
async def create_entity(
|
||||||
self,
|
self,
|
||||||
entity_type: str,
|
entity_type: str,
|
||||||
|
|||||||
@@ -96,8 +96,7 @@ async def handler(event_data: Dict[str, Any], ctx: FlowContext) -> None:
|
|||||||
# ── Load CDokumente once (shared by Advoware + xAI sync) ─────────────────
|
# ── Load CDokumente once (shared by Advoware + xAI sync) ─────────────────
|
||||||
espo_docs: list = []
|
espo_docs: list = []
|
||||||
if advoware_enabled or xai_enabled:
|
if advoware_enabled or xai_enabled:
|
||||||
docs_result = await espocrm.list_related('CAkten', akte_id, 'dokumentes', max_size=1000)
|
espo_docs = await espocrm.list_related_all('CAkten', akte_id, 'dokumentes')
|
||||||
espo_docs = docs_result.get('list', [])
|
|
||||||
|
|
||||||
# ── ADVOWARE SYNC ────────────────────────────────────────────
|
# ── ADVOWARE SYNC ────────────────────────────────────────────
|
||||||
advoware_results = None
|
advoware_results = None
|
||||||
|
|||||||
Reference in New Issue
Block a user