first
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
"""Abstract issue / requirement tracker connector (Jira, Linear, etc.)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Protocol, AsyncIterator, Optional, Any, Sequence
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class IssueInfo:
|
||||
key: str
|
||||
title: str
|
||||
type: str # epic, story, bug, task, ...
|
||||
status: str
|
||||
description: Optional[str] = None
|
||||
assignee: Optional[str] = None
|
||||
labels: Sequence[str] = ()
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
parent_key: Optional[str] = None
|
||||
metadata: dict[str, Any] = None # type: ignore[assignment]
|
||||
|
||||
|
||||
class IssueTrackerConnector(Protocol):
|
||||
"""Provider interface for Jira / GitHub Issues / YouTrack / ..."""
|
||||
|
||||
async def search_issues(
|
||||
self, query: str, *, project_ref: Optional[str] = None, limit: int = 100
|
||||
) -> AsyncIterator[IssueInfo]: ...
|
||||
|
||||
async def get_issue(self, issue_key: str) -> Optional[IssueInfo]: ...
|
||||
|
||||
async def sync_project(self, project_ref: str) -> None: ...
|
||||
Reference in New Issue
Block a user