mobiledev/taskflow

TaskFlow, a team task board you run from the web or from Claude and ChatGPT. FastAPI + DataK3 + appid + Models + MCP.

A remix template · 0 remixes · Remix mobiledev/taskflow

README.md

TaskFlow

A team task board you can run from a web page or from Claude and ChatGPT. Remix it into your own Dodil organization and it comes up live with its tables, sign-in and AI.

"What's on my plate this week?" · "Add a card 'Send invoice' to Doing on the Ops board" · "Move card 12 to Done" · "What's overdue?" · "What is blocking the launch?"

Built for the Dodil Boards Challenge. MIT licence.

What it does

AreaWhat you get
PeopleThe owner invites people as member (can edit) or viewer (read only), changes roles and removes people. Removed people's cards become unassigned.
BoardsBoards → lists → cards. Default lists are To do, Doing, Done; the owner can add more (new lists go before Done). The list called Done means finished.
CardsNumbered per board (#12), with title, description, assignee, due date, labels, a checklist and "blocked by" links. Drag and drop between and within lists.
HistoryEvery change is recorded: who, when, and exactly what changed ({"list_name": ["To do", "Done"]}). Per card and per board.
MCP26 tools for Claude/ChatGPT, all actions, no table access. The assistant sees only the boards its signed-in person can see.
AI (Dodil Models)"Turn this card into a checklist", "find cards like this one" (embeddings), and a daily board summary.
OverdueCards past their due date and not in Done are flagged on the board and listed under Overdue.
Dependencies"Blocked by" links with loop protection, and "what is blocking X?" walks the whole chain.
Tidy upDelete cards (they stay in the history), rename lists, delete empty lists. The owner deletes a board from the web page only, by typing its name: no assistant can wipe a board.

Remix it

dodil update                                          # CLI 0.1.89 or later
dodil git remix <org>/taskflow --to-org <your-org> --name <your-repo>   # repo name: 18 chars max

The remix creates the repo, a DataK3 bucket <repo>-data with the tables from schema.sql, a user pool <repo>-users, and a service account with access to the bucket and Dodil Models. CI then tests, builds and deploys it to Ignite.

After the remix: let people sign in

  1. Callback URL. The deploy registers https://<app host>/.dodil/auth/callback on the pool itself; its log says "already lists the sign-in callback". If it says "not registered", run the command that line prints, once (dodil guide remix, "After the remix: let people sign in").

  2. Recommended: verified emails. Boards are shared by inviting an email address, so make people prove they own the address they sign up with. Otherwise someone could register an invited address before its owner does:

    dodil appid settings set <repo>-users --require-email-verification
    

Then open the app URL, sign up, and create your first board.

Use it from Claude or ChatGPT

Tested end to end with Claude.ai (custom connector). ChatGPT speaks the same MCP and OAuth standards, but I haven't been able to test it.

The app serves MCP at https://<your-app-host>/mcp. Add it as a custom connector. It asks you to sign in through the pool; approve the client once:

dodil appid client list <repo>-users
dodil appid client approve <repo>-users <client-id>

If Claude.ai says "Couldn't register with TaskFlow's sign-in service" (we hit this while testing; the self-registration request never reached the pool), skip self-registration: register Claude as a first-party client once, then in the connector pick Use your own OAuth client with client ID claude-ai and no secret.

dodil appid client register <repo>-users --client-id claude-ai --name Claude \
  --redirect-uri https://claude.ai/api/mcp/auth_callback \
  --redirect-uri https://claude.com/api/mcp/auth_callback --yes

Then just talk to it. Boards can be named by title ("the Ops board") and cards by number ("card 12"). If two of your boards both have a #12, it asks which board you mean.

AskTool it uses
What's on my plate this week?my_cards(due_within_days=7)
Add a card 'Send invoice' to Doing on the Ops boardadd_card
Move card 12 to Donemove_card
What's overdue?overdue
Give #4 to bo@example.com, due Fridayassign_card, update_card
What is blocking the launch?what_blocks
Turn card 7 into a checklistchecklist_from_ai
Anything similar to #9?similar_cards
Summarise the Ops board for todayboard_summary
Who changed card 3?card_history

Run it locally

cd app
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt pytest
cd .. && python -m pytest -q tests        # no Dodil account needed: in-memory data and AI

To run the server against your remixed bucket, set BUCKET, DODIL_SERVICE_ACCOUNT_ID, DODIL_SERVICE_ACCOUNT_SECRET and DEV_USER=you@example.com (acts as that person without the gateway; local only), then from app/:

uvicorn taskflow.main:production_app --factory --port 8080

How it's built

app/taskflow/
  domain/model.py            Board, Card, Role and every rule (plain Python, no I/O)
  application/use_cases.py   every action; the only thing the doors call
  application/ports.py       what the use cases need: a repository and an AI assistant
  infrastructure/            DataK3 repository, service-account token, Dodil Models client
  doors/web.py, page.html    JSON routes and the board page   -> use cases
  doors/mcp.py               MCP tools for Claude and ChatGPT  -> the same use cases
  doors/identity.py          who is calling (the gateway's X-Dodil-User header)
  main.py                    wires it together: /mcp, sign-in metadata, /healthz
tests/                       the rules, through the use cases and through both doors
schema.sql                   the tables, created by the remix
.dodil/remix.yaml            what a remix creates
.dodil/deploy.yaml           how CI deploys every copy

Design decisions are in DESIGN.md.

What I'd improve next

  • Edit conflicts: if two people edit the same card at the same moment, the last save wins. A version number on each card (409 "changed since you opened it") would catch that.
  • Real-time updates on the page (today it refreshes after each action).
  • Store embeddings in DataK3's vector search instead of computing them per request, so "find similar" scales past a few hundred cards.
  • Comments on cards and @mentions.
  • Archive instead of delete, and a board-level "archived cards" view.