# Copyright (c) 2026 Patrick Motsch # All rights reserved. """Workflow action: list Redmine relations from the mirror.""" import logging from typing import Any, Dict, List, Optional from modules.datamodels.datamodelChat import ActionResult from modules.features.redmine.interfaceFeatureRedmine import getInterface from ._shared import resolveInstanceContext logger = logging.getLogger(__name__) async def listRelationsAction(self, parameters: Dict[str, Any]) -> ActionResult: """List all mirrored relations, optionally filtered by issueId or relationType.""" try: user, mandateId, featureInstanceId = resolveInstanceContext(self.services, parameters) except ValueError as exc: return ActionResult.isFailure(error=str(exc)) iface = getInterface(user, mandateId=mandateId, featureInstanceId=featureInstanceId) rows = iface.listMirroredRelations(featureInstanceId) issueId: Optional[int] = None rawIssueId = parameters.get("issueId") if rawIssueId not in (None, ""): try: issueId = int(rawIssueId) except (TypeError, ValueError): return ActionResult.isFailure(error="issueId must be an int") relationType = parameters.get("relationType") or None if issueId is not None: rows = [ r for r in rows if int(r.get("issueId") or 0) == issueId or int(r.get("issueToId") or 0) == issueId ] if relationType: rows = [r for r in rows if r.get("relationType") == relationType] limit = 1000 try: limit = max(1, min(5000, int(parameters.get("limit") or 1000))) except (TypeError, ValueError): limit = 1000 offset = 0 try: offset = max(0, int(parameters.get("offset") or 0)) except (TypeError, ValueError): offset = 0 page = rows[offset:offset + limit] return ActionResult.isSuccess(data={ "count": len(page), "totalMatched": len(rows), "offset": offset, "hasMore": (offset + limit) < len(rows), "relations": [ { "redmineRelationId": r.get("redmineRelationId"), "issueId": r.get("issueId"), "issueToId": r.get("issueToId"), "relationType": r.get("relationType"), "delay": r.get("delay"), } for r in page ], })