Files
graph-requirements-planner/README.md
2026-03-18 06:40:53 -05:00

12 KiB

req-planner

A standalone requirements management tool with interactive graph visualization, hierarchical decomposition, quality gates, and code traceability. Designed as a general-purpose planning tool that can connect to any repository.

What It Does

req-planner lets you decompose high-level project goals into traceable, testable requirements organized as a directed acyclic graph (DAG). Each requirement is a card that can be drilled down from abstract pillars to code-level leaf nodes, with quality validation at every level.

Core Concepts

  • Pillars — Top-level project goals (e.g., "MIDI Signal Path")
  • Requirements — Functional requirements under a pillar
  • Sub-requirements — Decomposed pieces of a requirement
  • Leaves — Code-level items with test specs and implementation
  • Planning — Planning-phase nodes (larger green-tinted cards)

Each node carries:

  • Acceptance criteria (what it must do)
  • Test specification (GIVEN/WHEN/THEN format)
  • Test and implementation code snippets
  • Target file paths for code export
  • Quality gate status
  • Gitea issue integration fields

Quality Gates (TMCS)

Every requirement is validated against four gates:

Gate Type Rule
Traceable Auto Has a parent requirement and description
Measurable Toggle Forced false without test specification; user can toggle when test spec exists
Consistent Toggle User asserts no contradictions with sibling requirements
Single-purpose Toggle User asserts requirement serves exactly one concern

T is auto-calculated from the requirement's structure. M, C, and S are user-set toggles — click the badge in the detail panel to flip them. M is enforced: if a node has no test specification, measurable is always false regardless of the toggle.

Visual indicators on graph nodes:

  • Red dot — Fewer than 2 quality gates pass
  • Orange dot — 2 of 3 gates pass
  • Green dot — All quality gates pass

Requirement Status Flow

Requirements follow a lifecycle: ideadrafttodoin_progressdone

  • idea (purple) — ideas backlog; things you're thinking about but haven't committed to building
  • draft (gray) — being defined, not yet ready for work
  • todo (blue) — defined and ready to implement
  • in_progress (yellow) — actively being worked on
  • done (green) — completed

Requirements can declare they "also satisfy" other requirements beyond their parent. This creates cross-cutting traceability:

  • Also Satisfies — outgoing links: "this requirement also contributes to requirement X"
  • Satisfied By — incoming links: "requirement Y also contributes to this one"

These appear as purple dashed edges in the graph.

Features

Interactive Graph View (/graph)

The main view renders the requirement tree as a Cytoscape.js DAG with dagre layout.

Semantic zoom — node detail changes continuously with zoom level:

Zoom Range What You See
0 - 0.3 Dots with ID only
0.3 - 0.6 Cards with ID, title, child count
0.6 - 1.0 Cards with TMCS quality badges
1.0+ Expanded cards with AC count and status

Mouse interactions:

Action Behavior
Click node Select node, open detail panel, highlight paths to root (parent-child + satisfaction links)
Shift+Click Highlight parent-child path to root only (no satisfaction links)
Alt+Click (Win) / Option+Click (Mac) Highlight only "also satisfies" links for a node
Ctrl+Click (Win) / Cmd+Click (Mac) Focus mode: show node, direct children, and paths to roots
Ctrl+Shift+Click (Win) / Cmd+Shift+Click (Mac) Deep focus: show node, all descendants to leaves, and paths to roots
Right-click Highlight entire subtree downward
Click background Exit focus mode or close detail panel
Drag node Reposition (saved across sessions)

Keyboard shortcuts:

Key Action
+ / = Zoom in
- Zoom out
0 Fit graph to screen
Ctrl+Z (Win) / Cmd+Z (Mac) Undo last canvas action
Esc Exit focus mode

Canvas undo tracks all interactions: node clicks, focus/exit, right-click highlights, and node drags. Up to 20 states are kept in the undo stack.

Persistence:

  • Node positions saved to localStorage — drag nodes to rearrange and they stay put across reloads
  • Viewport (zoom + pan) persisted across sessions
  • Selected node and panel state restored on reload
  • Re-layout button resets to auto-calculated dagre positions

Named layouts:

  • Save the current graph layout (node positions + viewport) with a name and description
  • Load any saved layout from the toolbar dropdown
  • Set a default layout that auto-loads on startup
  • Manage layouts: load, set default, or delete

Edge rendering:

  • Parent-child edges: solid gray lines, width scales up when zoomed out
  • Satisfaction links: purple dashed lines with directional arrows
  • Path highlight: blue for parent-child, purple for satisfaction links

Detail Panel

A 420px side panel for viewing and editing a requirement:

  • Inline editing for title, description, priority, status, phase, node type
  • Acceptance criteria and test spec (GIVEN/WHEN/THEN) editors
  • Test code and implementation code blocks (monospace)
  • Quality gate badges — click M/C/S to toggle, T is auto-calculated
  • Quality validation with error/warning display
  • Child requirements list with add-child form (auto-generates IDs)
  • Parent card link — click to navigate to parent
  • Also Satisfies section — manage outgoing satisfaction links with typeahead search
  • Satisfied By section — view incoming links, click to navigate
  • Edit history — collapsible section showing all versions with timestamps and change summaries
    • Click a version to see field-level diffs (changed fields highlighted)
    • Restore any previous version (creates a new version with "Restored from version N" note)
  • Gitea issue badge with link (when issue number is set)
  • Delete with cascade confirmation

Dashboard (/dashboard)

Statistics overview with:

  • Node counts by type (pillars, requirements, sub-requirements, leaves, planning)
  • Test coverage percentage
  • Breakdown by status and priority
  • Quality gates pass/fail ratio

Authentication

  • Password-based login with JWT tokens (24-hour expiry)
  • Protected routes with auth guard
  • Token auto-injected into API requests via HTTP interceptor
  • Configurable password via REQ_PLANNER_PASSWORD environment variable

Architecture

req-planner/
├── backend/          FastAPI + SQLAlchemy + SQLite
│   └── app/
│       ├── main.py           App entry, CORS config, router registration
│       ├── auth.py           JWT authentication
│       ├── database.py       SQLite connection (data/planner.db)
│       ├── models.py         ORM models (RequirementNode, CrossPillarLink,
│       │                       Project, RequirementHistory, GraphLayout)
│       ├── schemas.py        Pydantic request/response schemas
│       ├── quality.py        TMCS validation logic
│       └── routers/
│           ├── requirements.py   CRUD + tree + validation + history endpoints
│           ├── links.py          Cross-pillar link management
│           ├── projects.py       Project CRUD
│           ├── stats.py          Aggregated statistics
│           └── layouts.py        Named graph layout CRUD
├── frontend/         Angular 17 + Cytoscape.js
│   └── src/app/
│       ├── core/
│       │   ├── guards/           Auth route guard
│       │   ├── interceptors/     JWT token interceptor
│       │   ├── models/           TypeScript interfaces
│       │   └── services/         HTTP API client (requirements, auth)
│       └── features/
│           ├── graph/            Interactive DAG visualization
│           ├── detail/           Side panel editor with history
│           ├── dashboard/        Statistics overview
│           └── login/            Password login
├── data/
│   └── planner.db    SQLite database (auto-created)
└── docs/
    └── MARKET-RESEARCH.md   Competitive analysis

API Endpoints

Requirements

Method Endpoint Description
GET /api/requirements List requirements (filter by project_id, parent_id)
GET /api/requirements/tree Tree structure for graph rendering
GET /api/requirements/{id} Single requirement with children
POST /api/requirements Create requirement
PUT /api/requirements/{id} Update requirement
DELETE /api/requirements/{id} Delete requirement (cascades to children)
PATCH /api/requirements/{id}/status Update status only
POST /api/requirements/{id}/validate Run TMCS quality gates
GET /api/requirements/{id}/children List direct children

Edit History

Method Endpoint Description
GET /api/requirements/{id}/history List all versions (newest first)
GET /api/requirements/{id}/history/{version} Get specific version snapshot
POST /api/requirements/{id}/history/{version}/restore Restore to previous version
Method Endpoint Description
GET /api/links List links (optional node_id filter)
POST /api/links Create satisfaction link
DELETE /api/links/{source_id}/{target_id} Delete link

Graph Layouts

Method Endpoint Description
GET /api/layouts List saved layouts (optional project_id filter)
GET /api/layouts/{id} Get layout with positions and viewport
POST /api/layouts Save current layout
PUT /api/layouts/{id} Update layout
DELETE /api/layouts/{id} Delete layout

Other

Method Endpoint Description
GET /api/health Health check
POST /api/auth/login Login, returns JWT token
GET/POST/DELETE /api/projects Project management
GET /api/stats Aggregated statistics

Interactive API docs available at http://localhost:8100/docs (Swagger UI).

Tech Stack

Backend:

  • Python 3.12+, FastAPI, SQLAlchemy 2.0, SQLite
  • Pydantic 2.10+ for validation
  • python-jose for JWT tokens
  • Uvicorn ASGI server

Frontend:

  • Angular 17 (standalone components, new control flow syntax)
  • Cytoscape.js + cytoscape-dagre for graph rendering
  • RxJS for reactive data flow
  • SCSS with dark theme (GitHub-inspired palette)
  • OnPush change detection, lazy-loaded routes

Running Locally

Backend

cd backend
uv sync              # or: pip install -e ".[dev]"
uvicorn app.main:app --reload --port 8100

Frontend

cd frontend
npm install
ng serve             # runs on http://localhost:4200

The frontend proxies API requests to http://localhost:8100/api via proxy.conf.json.

Database

SQLite database at data/planner.db, auto-created on first backend startup. Five tables:

  • requirement_nodes — hierarchical requirements with quality flags, code metadata, and timestamps
  • cross_pillar_links — many-to-many satisfaction links between requirements
  • projects — project containers with optional repo path/URL
  • requirement_history — versioned snapshots of requirement edits
  • graph_layouts — named layout snapshots with node positions and viewport state