# How Prompt Connections Create Workflows in prompts.chat

> Discover how prompt connections in prompts.chat build powerful workflows. Learn about directed graphs, database storage, API endpoints, and D3.js visualizations.

- Repository: [Fatih Kadir Akın/prompts.chat](https://github.com/f/prompts.chat)
- Tags: how-to-guide
- Published: 2026-04-02

---

**Prompt connections in prompts.chat form directed workflow graphs by storing edges in a PostgreSQL database via Prisma, traversing connected prompts using BFS in a cached API endpoint, and rendering the results as interactive D3.js visualizations.**

Prompt workflows allow users to chain individual prompts into multi-step automation sequences. In the **f/prompts.chat** repository, these workflows are built using a graph data model where nodes represent prompts and edges represent directional **prompt connections**. The implementation spans the database schema, REST API endpoints, and React frontend components that handle visualization and user interaction.

## Database Schema for Prompt Connections

At the foundation of every workflow lies the `PromptConnection` model defined in `prisma/schema.prisma` around line 80. This table stores directed edges linking two prompts together.

```prisma
model PromptConnection {
  id        String @id @default(cuid())
  sourceId  String
  targetId  String
  label     String
  order     Int    @default(0)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  source Prompt @relation("ConnectionSource", fields: [sourceId], references: [id], onDelete: Cascade)
  target Prompt @relation("ConnectionTarget", fields: [targetId], references: [id], onDelete: Cascade)

  @@unique([sourceId, targetId])
  @@index([sourceId])
  @@index([targetId])
}

```

Each row represents a directed edge from `sourceId` to `targetId`. The schema enforces referential integrity with `onDelete: Cascade` and prevents duplicate relationships through the `@@unique([sourceId, targetId])` constraint. The `label` field stores human-readable edge descriptions, while `order` controls the visual positioning of multiple outgoing connections.

## API Architecture for Workflow Management

The system exposes two primary API surfaces: individual connection management and complete graph traversal.

### Managing Direct Connections

The `src/app/api/prompts/[id]/connections/route.ts` file implements CRUD operations for prompt connections.

**GET** requests return two arrays—`outgoing` and `incoming`—filtered to exclude AI-suggested connections (where `label: { not: "related" }`). The endpoint also filters out private prompts unless the requester is the author.

**POST** requests create new workflow edges. The handler validates that the authenticated user owns both the source and target prompts, prevents self-connections, and ensures uniqueness. Upon successful creation, it calls `revalidateTag("prompt-flow")` to invalidate cached graph data.

**DELETE** requests remove specific connections after confirming ownership via the `src/app/api/prompts/[id]/connections/[connectionId]` route.

### Traversing Complete Workflow Graphs

The `src/app/api/prompts/[id]/flow/route.ts` endpoint computes the transitive closure of a prompt's workflow using breadth-first search (BFS). The implementation uses `unstable_cache` tagged with `"prompt-flow"` for performance.

The algorithm:
1. Collects all reachable prompt IDs via BFS while tracking visited nodes to prevent infinite loops
2. Performs a single batch query (`db.prompt.findMany`) to fetch all node data
3. Filters out private prompts where `isPrivate && authorId !== userId`
4. Returns a minimal graph structure with `nodes` and `edges` arrays

## Frontend Implementation

### Data Fetching with PromptConnections

The `PromptConnections` component in [`src/components/prompts/prompt-connections.tsx`](https://github.com/f/prompts.chat/blob/main/src/components/prompts/prompt-connections.tsx) orchestrates data fetching by parallelizing requests to both endpoints:

```tsx
const [connRes, flowRes] = await Promise.all([
  fetch(`/api/prompts/${promptId}/connections`),
  fetch(`/api/prompts/${promptId}/flow`),
]);

```

This approach retrieves both the direct connection list (for editing) and the complete workflow graph (for visualization) simultaneously.

### Interactive Visualization with FlowGraph

Inside the same file, the `FlowGraph` subcomponent consumes the graph data to render an interactive SVG. The D3-based implementation performs topological sorting to assign vertical levels, ensuring a left-to-right, top-to-bottom flow layout. It generates virtual input/output nodes for prompts requiring media uploads and draws curved edges with arrowheads and labels.

### Creating Connections via AddConnectionDialog

The `AddConnectionDialog` component in [`src/components/prompts/add-connection-dialog.tsx`](https://github.com/f/prompts.chat/blob/main/src/components/prompts/add-connection-dialog.tsx) provides the search interface for finding target prompts. When users submit the form, the component constructs the appropriate directional edge:

```tsx
const sourceId = connectionType === "previous" 
  ? selectedPrompt.id 
  : promptId;
const targetId = connectionType === "previous" 
  ? promptId 
  : selectedPrompt.id;

await fetch(`/api/prompts/${sourceId}/connections`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ targetId, label: label.trim() }),
});

```

## Implementing Workflow Connections

To programmatically create a workflow link between two prompts, send an authenticated POST request:

```typescript
// Creating a "next" connection
await fetch(`/api/prompts/${sourcePromptId}/connections`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    targetId: targetPromptId,
    label: "Generate image",
  }),
});

```

After creation, the `revalidateTag("prompt-flow")` call ensures the next request to the flow endpoint rebuilds the graph including the new edge.

## Privacy and Visibility Controls

The workflow system respects prompt privacy settings by filtering private prompts from graph results when the requester is not the author. This filtering occurs in the database queries within the flow endpoint and in the connection list endpoint, ensuring private prompts never appear in other users' workflow visualizations.

## Summary

- **PromptConnection model**: Stores directed edges with `sourceId`, `targetId`, labels, and ordering in PostgreSQL via Prisma at `prisma/schema.prisma`
- **API endpoints**: Separate handlers for individual connections (`[id]/connections`) and complete graph traversal (`[id]/flow`) using BFS with `unstable_cache`
- **Caching strategy**: `revalidateTag("prompt-flow")` invalidates cached graphs immediately after connection mutations
- **Frontend components**: `PromptConnections` fetches data, `FlowGraph` renders D3 visualizations with topological sorting, and `AddConnectionDialog` handles the creation UI
- **Security model**: Ownership validation on all mutations and visibility filtering on all reads protect private prompt workflows

## Frequently Asked Questions

### What database structure enables prompt connections in prompts.chat?

Prompt connections rely on the `PromptConnection` model in `prisma/schema.prisma`, which defines a directed edge with `sourceId` and `targetId` foreign keys referencing the `Prompt` table. The model includes fields for `label` (edge description), `order` (UI positioning), and unique constraints preventing duplicate relationships between the same prompts.

### How does the flow API handle circular references in workflows?

The flow endpoint in `src/app/api/prompts/[id]/flow/route.ts` implements a breadth-first search algorithm that tracks visited prompt IDs in a `Set` data structure. This ensures each prompt is processed only once, preventing infinite recursion in circular workflow configurations while still capturing all unique nodes and edges.

### Can users create connections between prompts they don't own?

No. The POST handler in `src/app/api/prompts/[id]/connections/route.ts` validates that the authenticated user owns both the source and target prompts by checking `authorId` against the session user ID. The API returns an authorization error if ownership validation fails, ensuring users can only connect prompts within their own workflow pipelines.

### What triggers updates to the cached workflow visualization?

The system uses Next.js `unstable_cache` tagged with `"prompt-flow"`. When mutations occur—such as creating or deleting connections via POST or DELETE requests—the handlers call `revalidateTag("prompt-flow")`, which invalidates the cached graph data. Subsequent requests to the flow endpoint regenerate the workflow graph from the database.