Skip to content
Raja9964Public

About

Task dependency manager with cycle detection, recursive status propagation and an interactive dependency graph. Django REST + React.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

TaskWeave

Plan work as a dependency graph: TaskWeave blocks circular dependencies, keeps task statuses in sync with their prerequisites, and draws the whole plan as an interactive graph.

CI

▶ Live demo: the full UI running on an in-browser port of the API, preloaded with a sample project. Your changes stay in your browser.

Dependency graph

Task list Cycle rejected with the full path
Task list Cycle error

Board

Features

  • Create, edit and delete tasks from a list view, a status board or the graph.
  • Add and remove dependencies. A dependency that would create a cycle is rejected, and the UI shows the exact loop, for example Model staging layer in dbt -> Build customer 360 dashboard -> Add data quality checks -> Model staging layer in dbt.
  • Automatic status updates: a task is blocked while any dependency is unfinished and returns to pending when the last one completes. Completed tasks are never downgraded automatically.
  • Interactive dependency graph (React Flow with dagre auto-layout), nodes colored by status and animated edges where a prerequisite is still open.
  • REST API with clear 400/404/409 errors, a demo data seeder and the Django admin.
  • A live demo that needs no server: the GitHub Pages build runs a TypeScript port of the service layer and API validation in the browser and keeps its data in localStorage.

Tech stack

Layer Tools
Backend Python 3.10+, Django 5.2 LTS, Django REST Framework, SQLite or MySQL
Frontend React 19, TypeScript, Vite, Tailwind CSS 4, TanStack Query, React Flow, dagre
Quality Django test runner, Vitest and Testing Library, Ruff, Oxlint, GitHub Actions
Demo GitHub Pages, in-browser TypeScript port of the API, localStorage

Architecture

flowchart LR
    subgraph Browser
        UI["React app<br/>list / board / graph"] --> RQ["TanStack Query cache"]
        RQ -. "live demo build" .-> DEMO["In-browser API<br/>TypeScript port + localStorage"]
    end
    RQ -- "JSON over HTTP" --> API["DRF TaskViewSet"]
    API --> SVC["services.py<br/>cycle check, status cascade"]
    SVC --> ORM["Django ORM"]
    ORM --> DB[("SQLite or MySQL")]
Loading

Views only validate input and shape responses. All rules live in backend/tasks/services.py, and every write that can affect readiness runs inside a transaction.

How cycle detection works

Adding "A depends on B" is only safe if B cannot already reach A. The service loads all edges in one query, runs a breadth-first search from B and records each node's parent. If the search reaches A, the parent chain gives the existing path from B to A; adding A in front closes the loop A -> B -> ... -> A. The API returns that path with task titles, and the database enforces unique, non-self-referencing edges as a second line of defense.

How the live demo works

GitHub Pages only serves static files, so the demo build (npm run build:demo, which sets VITE_DEMO=true) swaps the HTTP client for an in-browser implementation of the same API interface. frontend/src/demo/ ports services.py (the BFS cycle check, derived statuses and the downstream cascade) and the viewset's validation, so the UI gets the same responses and the same 400, 404 and 409 errors. Each write is applied to a copy and saved to localStorage only if it succeeds, and Reset demo data reloads the seed_demo project. The backend test cases are ported to Vitest and run against this port to keep the two in step.

More detail, including the status rules and trade-offs, is in docs/design-decisions.md.

Project structure

.
├── .github/workflows/      CI, plus the GitHub Pages deployment of the demo
├── backend/
│   ├── backend/            Django project settings and root URLs
│   └── tasks/
│       ├── models.py       Task and TaskDependency (with DB constraints)
│       ├── services.py     Cycle detection and status propagation
│       ├── serializers.py
│       ├── views.py        TaskViewSet, graph and health endpoints
│       ├── management/commands/seed_demo.py
│       └── tests/          Service and API tests
├── frontend/
│   └── src/
│       ├── api/            Fetch client and TanStack Query hooks
│       ├── components/     List, board, graph, task panel, dependency editor
│       ├── demo/           In-browser port of the API for the live demo
│       └── lib/            Status metadata and graph layout
├── docs/                   Design decisions and screenshots
├── requirements.txt        Runtime dependencies (pinned)
├── requirements-dev.txt    Adds Ruff
└── requirements-mysql.txt  Adds the MySQL driver

Run it locally

Prerequisites: Python 3.10 or newer and Node.js 20.19 or newer (CI uses Node 24).

Backend

The API listens on port 8101.

macOS / Linux:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
cp backend/.env.example backend/.env
cd backend
python manage.py migrate
python manage.py seed_demo        # optional sample project
python manage.py runserver 8101

Windows (PowerShell):

python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements-dev.txt
Copy-Item backend\.env.example backend\.env
cd backend
python manage.py migrate
python manage.py seed_demo
python manage.py runserver 8101

To use MySQL instead of SQLite, install requirements-mysql.txt, create the database and set DB_ENGINE=mysql plus the DB_* values in backend/.env.

Frontend

Run this in a second terminal. The dev server uses port 5101 and calls the API on port 8101; open the address Vite prints.

cd frontend
npm install
cp .env.example .env              # Windows: Copy-Item .env.example .env
npm run dev

Without the backend

To try the frontend on its own, run it on the in-browser API used by the live demo:

cd frontend
npm install
npm run dev:demo

Configuration

Backend variables are read from the environment or backend/.env. The defaults suit local development; backend/.env.example and frontend/.env.example list the exact values.

Variable Default Description
DEBUG false Enables debug mode and the browsable API
SECRET_KEY none Required when DEBUG is off
ALLOWED_HOSTS the local machine Comma-separated host names
CORS_ALLOWED_ORIGINS the dev server on port 5101 Origins allowed to call the API
DB_ENGINE sqlite sqlite or mysql
DB_NAME backend/db.sqlite3 / taskweave SQLite file path or MySQL database name
DB_USER, DB_PASSWORD root, empty MySQL credentials
DB_HOST, DB_PORT the local machine, 3306 MySQL server
VITE_API_URL (frontend) the API on port 8101 API base URL used by the React app, including /api
VITE_DEMO (frontend) not set true runs the app on the in-browser API; npm run build:demo sets it

API reference

All endpoints are under /api/ and exchange JSON.

Method Path Description
GET /health/ Liveness check
GET /tasks/ List tasks with dependencies and dependents ids
POST /tasks/ Create a task (title, description, status)
GET /tasks/{id}/ Retrieve a task
PUT / PATCH /tasks/{id}/ Update a task; status changes cascade to dependents
DELETE /tasks/{id}/ Delete a task and re-evaluate its dependents
POST /tasks/{id}/dependencies/ Add a dependency: {"depends_on_id": 3}
DELETE /tasks/{id}/dependencies/{depends_on_id}/ Remove a dependency
GET /graph/ Nodes (id, title, status) and edges (task, depends_on)

A rejected cycle returns 400:

{
  "detail": "Adding this dependency would create a cycle: Extract → Load → Transform → Extract",
  "cycle": [
    {"id": 1, "title": "Extract"},
    {"id": 3, "title": "Load"},
    {"id": 2, "title": "Transform"},
    {"id": 1, "title": "Extract"}
  ]
}

Other errors: 404 for unknown or malformed ids, 409 for a duplicate dependency, 400 with field messages for invalid input (for example completing a task whose dependencies are unfinished).

Testing

cd backend && python manage.py test        # 52 tests: cycles, status rules, API, seeding
ruff check backend                         # from the repository root

cd frontend
npm run lint
npm test                                   # includes the backend cases ported to the demo
npm run build
npm run build:demo                         # the GitHub Pages build

GitHub Actions runs the backend suite on Python 3.10 and 3.12 and lints, tests and builds the frontend on every push and pull request. Every push to main also tests and publishes the demo build to GitHub Pages.

License

MIT

About

Task dependency manager with cycle detection, recursive status propagation and an interactive dependency graph. Django REST + React.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages