# Copyright (c) 2026 Patrick Motsch # All rights reserved. """Workflow action: read a single Redmine ticket from the mirror. Returns ``ActionResult.data`` with a single ``ticket`` key so downstream nodes (e.g. ``ai.prompt``) can reference the ticket fields through ``DataRef``s. """ import logging from typing import Any, Dict from modules.datamodels.datamodelChat import ActionResult from modules.features.redmine.serviceRedmine import getTicket from ._shared import resolveInstanceContext, ticketToDict logger = logging.getLogger(__name__) async def readTicket(self, parameters: Dict[str, Any]) -> ActionResult: """Read ``parameters['ticketId']`` from the local Redmine mirror.""" try: user, mandateId, featureInstanceId = resolveInstanceContext(self.services, parameters) except ValueError as exc: return ActionResult.isFailure(error=str(exc)) raw_id = parameters.get("ticketId") or parameters.get("issueId") if raw_id is None: return ActionResult.isFailure(error="ticketId is required") try: ticketId = int(raw_id) except (TypeError, ValueError): return ActionResult.isFailure(error=f"ticketId must be an int, got {raw_id!r}") try: ticket = getTicket(user, mandateId, featureInstanceId, ticketId, includeRaw=False) except Exception as exc: logger.exception("redmine.readTicket failed for ticket %s", ticketId) return ActionResult.isFailure(error=f"Read ticket failed: {exc}") if ticket is None: return ActionResult.isFailure( error=f"Ticket #{ticketId} not found in mirror. Run redmine.runSync first?", ) return ActionResult.isSuccess(data={"ticket": ticketToDict(ticket)})