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

README.md

KanvaFlow — Remixable Team Task Boards on Dodil

KanvaFlow is a clean, remixable team task board built natively on the Dodil cloud (DataK3, appid, Ignite, and Dodil Models), operable seamlessly from both a drag-and-drop web UI and Claude / ChatGPT over MCP.

Built for the Dodil Boards Challenge (dodil-challenge, dodil-challenge-boards) under the MIT Licence.


1. Remix into Your Own Dodil Organization in One Command

dodil update   # CLI 0.1.89 or later
dodil git remix dachdigitalwerksorg/kanvaflow --to-org <your-org> --name kanvaflow

Name budget note: Keep --name to 18 characters or less (e.g. kanvaflow, team-boards) so the provisioned DataK3 bucket <repo>-data stays within K3's 25-character limit.

What the Remix Provisions Automatically (.dodil/remix.yaml)

  1. DataK3 Bucket (<repo>-data) initialized with schema.sql (boards, memberships, board_lists, cards, card_dependencies, activity — natural primary keys only).
  2. AppID User Pool (<repo>-users) fronting the Ignite gateway so end-users sign in without custom auth code.
  3. Service Account (<repo>-app) granted k3.editor on <repo>-data and ignite.model-user for Dodil Models (kimi-k2.6 + jina-embeddings-v4), wired into CI secrets automatically.
  4. Dodil Git CI/CD (.github/workflows/ci.yml + .dodil/deploy.yaml) running pytest, building the container image, and deploying live to Dodil Ignite.

Post-Remix Sign-In Step (Required Once After Remix)

Dodil Git CD (>= 1.6.11) registers https://<your-app-host>/.dodil/auth/callback on <repo>-users automatically during deploy:

  1. Check your deploy log (or dodil ignite app get <repo>): if the callback line reports "not registered", run the one-line dodil appid command printed in the deploy log to add https://<public_url>/.dodil/auth/callback to the pool's allowlist.
  2. Open your live Ignite URL in a browser and sign up / sign in (new pools allow signup by default; if you set --allow-signup=false, invite teammates via dodil appid user create <repo>-users <email> --roles member).
  3. Connecting Claude.ai or ChatGPT via MCP: Add https://<public_url>/mcp as a custom MCP connector, complete the browser sign-in prompt, and approve the dynamically registered OAuth client once:
    dodil appid client list <repo>-users
    dodil appid client approve <repo>-users <client-id>
    

2. Features & Capabilities

Core Capabilities

  • People & Strict RBAC (owner, member, viewer): Owners invite/remove members and viewers. Viewers have strictly enforced read-only access across both Web and MCP. Non-members cannot discover or inspect boards they are not on (404 Not Found).
  • Boards → Custom Lists → Rich Cards: Every board starts with To do, Doing, and Done and supports custom columns (Review, QA, etc.). Cards carry title, description, assignee, due_date, labels, checklist, and position, with HTML5 Drag-and-Drop on the web UI.
  • Full Audit Activity Log: Every board, list, membership, dependency, and field-level card change records actor, event_at, and action (viewable per board and per card).
  • Claude & ChatGPT MCP Door (/mcp): 20 high-level action tools (never raw table access) sharing the exact same use cases and gateway identity as the web UI:
    • "What's on my plate this week?" → my_agenda
    • "Add a card 'Send invoice' to Doing on the Ops board" → add_card (accepts board_id or exact board title!)
    • "Move card 9a3f to Done" → move_card (supports full ID or unambiguous short prefix + case-insensitive list matching)
    • "What's overdue?" → list_overdue

Scored Extras Included

  1. Dodil Models AI (kimi-k2.6 + jina-embeddings-v4):
    • "Turn this card into a checklist" → suggest_checklist (preview or apply=True straight onto the card).
    • "Find cards like this one" → search_similar_cards (hybrid semantic cosine similarity via jina-embeddings-v4 + lexical fallback, strictly scoped to boards the caller can view).
    • "Give me a daily summary of this board" → summarize_board (concise daily standup highlighting momentum, overdue items, and blockers).
  2. Card Dependencies & Cycle Detection:
    • Link "blocked by" cards (add_blocker / remove_blocker) with DFS cycle prevention in the domain model, and ask "What is blocking the launch?" (what_is_blocking) to trace both direct and transitive unfinished upstream blockers.
  3. Automatic Overdue Flagging:
    • Any card with due_date < today not in a Done list is flagged automatically in API payloads, MCP responses, and with red OVERDUE badges + one-click filtering in the web UI.

3. Architecture & Main Design Decisions

KanvaFlow uses Light Domain-Driven Design (Hexagonal Ports & Adapters):

app/boards/
  domain/model.py            Pure Python entities & invariants (Board, Card, Role, cycle DFS, similarity)
  application/ports.py       Repository & AI Assistant protocols
  application/use_cases.py   Single source of truth for all actions (Boards service)
  infrastructure/dodil.py    Service-account token cache, DataK3 pg-wire, Dodil Models (chat + embeddings)
  infrastructure/repository.py  Idempotent natural-key SQL upserts on DataK3
  doors/identity.py          Gateway X-Dodil-User parser (DEV_USER fallback for local dev only)
  doors/web.py               FastAPI JSON routes + responsive Drag-and-Drop Kanban SPA + POST / self-check
  doors/mcp.py               Streamable-HTTP MCP action tools calling application/use_cases.py
  main.py                    FastAPI lifespan, RFC 9728 OAuth resource metadata, /healthz, /mcp gate
tests/test_boards.py         Fast in-memory pytest suite covering domain rules & both doors

Key Design Decisions:

  1. Two Thin Doors, One Application Core: Neither doors/web.py nor doors/mcp.py touches SQL or checks roles directly — both translate HTTP/MCP calls into Boards use cases, making it structurally impossible for an MCP tool call to bypass an RBAC check.
  2. Zero Custom Auth Code: Authentication relies 100% on the Dodil gateway's appid pool and X-Dodil-User header, plus RFC 9728 /.well-known/oauth-protected-resource discovery so Claude.ai and ChatGPT trigger user sign-in automatically.
  3. Fault-Tolerant AI Enrichment: Card creation computes semantic embeddings via jina-embeddings-v4 opportunistically; if the model call ever times out, core task persistence still succeeds and search_similar_cards blends vector and lexical similarity gracefully.
  4. Ignite POST / Self-Check: In addition to /healthz, POST / executes a live DataK3 table count check using the app's own service-account credential so dodil ignite invoke <app> verifies real database connectivity immediately.

4. Run & Test Locally

cd app
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt pytest
python -m pytest -q ../tests

To run locally against a remixed DataK3 bucket:

export BUCKET=<your-repo>-data
export DODIL_SERVICE_ACCOUNT_ID=<client-id>
export DODIL_SERVICE_ACCOUNT_SECRET=<client-secret>
export DEV_USER=you@example.com
uvicorn boards.main:app --port 8080

What We Would Improve Next

  • Native K3 pgvector KNN (data_vsearch / vector column): Move embeddings from JSON-in-TEXT to a typed DataK3 vector column once boards scale past thousands of cards per workspace.
  • Real-Time Multi-User Presence: Add Server-Sent Events (SSE) notifications so concurrent card moves animate live across teammates' browsers without refreshing.
  • Board Templates & Webhooks: One-click sprint/launch board presets and outbound webhook triggers on list transitions.

5. Licence

MIT — see LICENSE.