from typing import List from models import Ticket class TrackDAG: def __init__(self, tickets: List[Ticket]): self.tickets = tickets self.ticket_map = {t.id: t for t in tickets} def get_ready_tasks(self) -> List[Ticket]: """Returns tickets that are 'todo' and whose dependencies are all 'completed'.""" ready = [] for ticket in self.tickets: if ticket.status == 'todo': # Check if all dependencies exist and are completed all_done = True for dep_id in ticket.depends_on: dep = self.ticket_map.get(dep_id) if not dep or dep.status != 'completed': all_done = False break if all_done: ready.append(ticket) return ready def has_cycle(self) -> bool: """Returns True if there's a dependency cycle.""" visited = set() rec_stack = set() def is_cyclic(ticket_id): if ticket_id in rec_stack: return True if ticket_id in visited: return False visited.add(ticket_id) rec_stack.add(ticket_id) ticket = self.ticket_map.get(ticket_id) if ticket: for neighbor in ticket.depends_on: if is_cyclic(neighbor): return True rec_stack.remove(ticket_id) return False for ticket in self.tickets: if ticket.id not in visited: if is_cyclic(ticket.id): return True return False