dachdigitalwerksorg/kanvaflow

KanvaFlow — Remixable team task board with RBAC, drag-and-drop Kanban, dependencies, Dodil Models AI, and MCP tools.

A remix template · 0 remixes · Remix dachdigitalwerksorg/kanvaflow

app/boards/application/ports.py

"""Ports required by the application use cases.

`infrastructure/` implements these against Dodil DataK3 and Dodil Models;
`tests/` supplies fast in-memory fakes so every rule runs in milliseconds without network calls.
"""
from typing import Optional, Protocol

from boards.domain.model import Board, Card


class BoardRepository(Protocol):
    def get(self, board_id: str) -> Optional[Board]: ...
    def boards_for(self, email: str) -> list[Board]: ...
    def save_board(self, board: Board) -> None: ...
    def remove_member_row(self, board_id: str, email: str) -> None: ...
    def get_card(self, card_id: str) -> Optional[Card]: ...
    def cards_on(self, board_id: str) -> list[Card]: ...
    def save_card(self, card: Card) -> None: ...
    def delete_card(self, card_id: str) -> None: ...
    def dependencies_on(self, board_id: str) -> dict[str, list[str]]: ...
    def add_dependency(self, board_id: str, card_id: str, blocked_by_id: str) -> None: ...
    def remove_dependency(self, card_id: str, blocked_by_id: str) -> None: ...
    def log(self, board_id: str, card_id: Optional[str], actor: str, action: str) -> None: ...
    def activity_for_board(self, board_id: str, limit: int = 40) -> list[dict]: ...
    def activity_for_card(self, card_id: str, limit: int = 40) -> list[dict]: ...
    def health_counts(self) -> dict[str, int]: ...


class Assistant(Protocol):
    def checklist(self, card_title: str, description: str = "") -> list[str]: ...
    def summarize_board(self, board_title: str, snapshot: str) -> str: ...
    def embed(self, text: str) -> Optional[list[float]]: ...