ghpsolutions/quadro
Quadro: team boards with roles, history and an MCP endpoint for Claude and ChatGPT
A remix template · 0 remixes · Remix ghpsolutions/quadro
app/boards/application/ports.py
"""What the use cases need from the outside world. Infrastructure provides these."""
from __future__ import annotations
from typing import Optional, Protocol, Sequence
from boards.domain.model import Board, BoardList, Card, Role
class NumberTaken(Exception):
"""The card number was claimed by a concurrent insert; pick the next one."""
class BoardRepository(Protocol):
# boards and people
def save_board(self, board: Board) -> None: ...
def get_board(self, board_id: str) -> Optional[Board]: ...
def boards_for(self, email: str) -> list[Board]: ...
def save_member(self, board_id: str, email: str, role: Role) -> None: ...
def remove_member(self, board_id: str, email: str) -> None: ...
# lists
def save_list(self, lst: BoardList) -> None: ...
def lists_on(self, board_id: str) -> list[BoardList]: ...
def delete_list(self, list_id: str) -> None: ...
# cards
def next_number(self, board_id: str) -> int: ...
def insert_card(self, card: Card) -> None:
"""Plain insert; raises NumberTaken if the id already exists."""
def update_card(self, card: Card, expected_version: int) -> bool:
"""Write `card` only if the stored version is still `expected_version`."""
def get_card(self, card_id: str) -> Optional[Card]: ...
def cards_on(self, board_ids: Sequence[str]) -> list[Card]: ...
def delete_card(self, card_id: str) -> None: ...
# comments and history
def add_comment(self, comment: dict) -> None: ...
def comments_for(self, card_id: str) -> list[dict]: ...
def comment_counts(self, board_id: str) -> dict: ...
def record(self, event: dict) -> None: ...
def activity(self, board_id: str, card_id: Optional[str] = None, limit: int = 50) -> list[dict]: ...
# similarity index
def save_embedding(self, card_id: str, board_id: str, digest: str, vector: list) -> None: ...
def embeddings_on(self, board_id: str) -> dict: ... # card_id -> (digest, vector)
class Assistant(Protocol):
"""Language features backed by Dodil Models."""
def checklist(self, title: str, description: str) -> list[str]: ...
def summary(self, facts: str) -> str: ...
def embed(self, texts: list[str]) -> list[list[float]]: ...