Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/design/dfd-store-clusters.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ Two views produce different stack sets from the same expanded graph. Both are co
```
per-process view (default):
for each process P, for each direction:
members = db stores P touches in that direction
members = stores P touches in that direction
if |members| ≥ 2 → one stack node, id stack:<sorted member ids>--<direction>
else → the plain store node, as today
two processes with the identical member set produce the same id and share the stack
Expand Down Expand Up @@ -219,6 +219,14 @@ collapse level (stores | clusters | groups), applied to the rows of every stack:

The two-member threshold governs implicit grouping only; a `cluster:` entry gets its cluster row even for one member, showing the member count in parentheses, because the author asked for it. A plain `db:` entry that is the only member of a cluster or group present gets a plain row, because it asked for that.

Store identity is row-local, not stack-local. Each concrete store row keeps its store kind,
uses that kind's theme color, and carries a kind-specific numbered cap (`D#` database,
`C#` cache, `Q#` queue, `F#` file, `Do#` document, `M#` manual, `O#` other). Numbering
is independent within each kind. A mixed stack therefore remains one routing/grouping
unit without allowing its first non-database member to recolor every sibling. Collapsed
cluster, subtype, and entity-group rows remain database-colored and use their unnumbered
`C`/`G` aggregate caps.

A stack edge aggregates its members' parsed edges. Its chip shows the members' authored labels one per line, then one column-preview line covering every unlabelled member, so a labelled cluster riding with two unlabelled tables reads `Tag junctions` over `tag_id, memory_id`; with no labelled member the chip is that single preview line. The hover tooltip lists one line per member with its columns, and the contract dialog lists every member's columns.

Stack ids are member sets plus direction, so saved drag positions survive reloads and two processes with the same set converge on one node. Positions are stored per view, keyed by the diagram's layout fingerprint plus the view name, so toggling views never applies one view's drag to the other. Fingerprints are computed on the expanded parsed edges, so a diagram authored with `cluster:` tokens and the same diagram authored with `db:` entries share a fingerprint.
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/flows.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Process flows


A model can carry data flow diagrams (DFDs) alongside its entities. A DFD shows what the business *does*: numbered processes transform data, external entities send it in and receive it out, and data stores hold what persists between steps. ignatius renders them in the SSADM style with Gane-Sarson notation — open-ended `D#` store boxes, numbered process hubs, green external boxes — in the **Flows** view of the app.
A model can carry data flow diagrams (DFDs) alongside its entities. A DFD shows what the business *does*: numbered processes transform data, external entities send it in and receive it out, and data stores hold what persists between steps. ignatius renders them in the SSADM style with Gane-Sarson notation — open-ended store boxes with kind-specific numbered caps, numbered process hubs, green external boxes — in the **Flows** view of the app.

The same markdown-first rule applies: flows live as `.md` files with YAML frontmatter, the diagram is generated, and a `db:` store in a flow is the *same entity* you modeled in the ERD — clicking it opens the full entity dialog with columns, relationships, and examples.

Expand Down Expand Up @@ -156,7 +156,7 @@ Append-only log of raw gateway responses. Used for reconciliation and dispute
resolution; never read back during normal processing. Retained for 7 years.
```

Store kinds also drive each node's color in the diagram — theme-aware and overridable under `theme.flowKinds` in `ignatius.yml` (see [Themes and branding](themes-and-branding.md)). The full kind vocabulary is in the [glossary](../glossary.md).
Store kinds drive both the numbered cap and the color of each concrete store row: `D#` database, `C#` cache, `Q#` queue, `F#` file, `Do#` document, `M#` manual, and `O#` other. Each kind has its own number sequence. In a mixed stack, every row keeps its own kind color rather than tinting the whole stack; collapsed entity cluster/group rows remain database-colored with their unnumbered `C`/`G` caps. Colors are theme-aware and overridable under `theme.flowKinds` in `ignatius.yml` (see [Themes and branding](themes-and-branding.md)). The full kind vocabulary is in the [glossary](../glossary.md).


## Sub-DFDs
Expand Down Expand Up @@ -251,7 +251,7 @@ A lone table is a table row at every level.
### Stacks and the stack dialog


A stack draws visible rows: store rows carry their own D# cap; cluster and subtype rows cap with `C`, group rows with `G` (never a D#, since only a store row is one) alongside the label, a `(N)` count, and a peek marker meaning more sit inside. A subtype row reads the basetype name when the basetype is among the touched stores, or `<Basetype> subtypes` when it is not. An adjacency stack is labelled `N stores`, never a member's name. Every stack carries one ⓘ badge.
A stack draws visible rows: concrete stores carry their kind-specific numbered cap and color; cluster and subtype rows cap with unnumbered `C`, group rows with unnumbered `G`, alongside the label, a `(N)` count, and a peek marker meaning more sit inside. A subtype row reads the basetype name when the basetype is among the touched stores, or `<Basetype> subtypes` when it is not. An adjacency stack is labelled `N stores`, never a member's name. Every stack carries one ⓘ badge.

Clicking a stack opens the stack dialog. Its title depends on the stack's source (a cluster's `label:`, the basetype name, the group's `label:`, `N stores` for adjacency, or `Read stack` / `Write stack` for a plain per-process stack), followed by the feeding processes and the rows at the current collapse level. A row's chevron expands and collapses its member rows; opening a member opens its entity or doc dialog. An author cluster row also shows the `clusters/<slug>.md` file's body; a subtype row links the basetype; a group row shows its description; an adjacency stack lists its shared readers and writers.

Expand Down
24 changes: 14 additions & 10 deletions docs/spec/dfd-store-clusters.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,17 @@ src/flow-view/elk-flow-layout.ts
threads view/collapseLevel/clusters/subtypeClusters/groups opts into buildFlowData

src/flow-view/FlowDiagramSvg.tsx
StoreNode
stacked variant — visible rows; a cluster or subtype row caps `C`, a group row caps `G`, store
rows cap `D#`; a C or G row draws the stacked-paper marker (two filled sheets behind it offset
3px and 6px down-right showing bottom edges, left stair segments, and the top-right mark, no
cap divider on the sheets, the stack's left border and cap divider drawn per row, a reserve
of offset plus stroke plus two pixels after the row, none after the last row, whose box ends
on the back sheet with no closing line); the duplicate marker is drawn in the connected view
only
StoreNode / stacked variant
every concrete store row retains its endpoint kind and resolves its own theme color; mixed
stacks never inherit one member's color across every row; kind-local numbered caps are
`D#` db, `C#` cache, `Q#` queue, `F#` file, `Do#` document, `M#` manual, `O#` other
(each kind has an independent sequence); a cluster or subtype row caps unnumbered `C`, a
group row caps unnumbered `G`, and those aggregate entity rows use db colors; a C or G row
draws the stacked-paper marker (two filled sheets behind it offset 3px and 6px down-right
showing bottom edges, left stair segments, and the top-right mark, no cap divider on the
sheets, the stack's left border and cap divider drawn per row, a reserve of offset plus
stroke plus two pixels after the row, none after the last row, whose box ends on the back
sheet with no closing line); the duplicate marker is drawn in the connected view only
StackDialog trigger — click on a stack node opens the row-list dialog
EdgeContractDialog trigger — click on any data-carrying edge chip opens the contract dialog
chip rendering — label only; no member or column count suffix
Expand All @@ -206,8 +209,9 @@ src/app/components/flow-node/StackDialog.tsx
StackDialog — titled by source (cluster label, basetype, group label, "N stores", or
"Read stack" / "Write stack"), with the feeding processes as dotted-number links in the
header; rows at the current collapse level; opening a cluster/subtype/group row shows
its members with D#s; a member opens its entity dialog; an author-cluster row also renders
the file's markdown body, a subtype row links the basetype (or reads "<Basetype> subtypes"
its members with their kind-specific numbered caps; a member opens its entity or store
dialog; an author-cluster row also renders the file's markdown body, a subtype row links
the basetype (or reads "<Basetype> subtypes"
when the basetype itself isn't a member), a group row shows the group's description, and
an adjacency row lists the shared reader and writer processes instead of any body

Expand Down
Loading
Loading