--- id: graph/flowgraph-class name: Implement FlowGraph class skeleton wrapping graphology DirectedGraph status: completed depends_on: - schema/enums - schema/node-attrs - schema/edge-attrs - schema/graph-schemas - error/hierarchy - setup/project-init scope: moderate risk: medium impact: phase level: implementation --- ## Description Create the `FlowGraph` class that wraps a graphology `DirectedGraph` and enforces DAG invariants. This is the core data class. At this stage, implement the constructor, generic type parameters, the `_graph` instance, the `graph` getter, `FlowGraphOptions`, and the `_edgeKey()` helper. Construction factory methods come in dependent tasks. ## Acceptance Criteria - [ ] `src/graph/construction.ts` exports `FlowGraph` class (or `src/graph/index.ts` if preferred, matching source structure) - [ ] Class has type parameters: `NodeAttrs extends TSchema`, `EdgeAttrs extends TSchema` - [ ] Constructor creates internal `graphology.DirectedGraph` with options `{ type: "directed", multi: false, allowSelfLoops: false }` - [ ] `FlowGraphOptions` interface: `type?: "directed"`, `multi?: false`, `allowSelfLoops?: false` - [ ] `get graph(): DirectedGraph` returns the underlying graphology instance - [ ] `_edgeKey(source, target): string` produces deterministic keys `${source}->${target}` - [ ] `addNode(key, attrs)` — adds node, throws `DuplicateNodeError` on duplicate - [ ] `removeNode(key)` — removes node and edges, throws `NodeNotFoundError` if missing - [ ] `updateNode(key, attrs)` — partial merge of attributes, throws `NodeNotFoundError` if missing - [ ] `hasNode(key): boolean` - [ ] `getNodeAttributes(key): NodeAttrs` — throws `NodeNotFoundError` if missing - [ ] `addEdge(source, target, attrs?)` — throws `NodeNotFoundError` for missing endpoints, `CycleError` if edge creates cycle, `DuplicateEdgeError` if edge exists - [ ] `removeEdge(source, target)` — no-op if edge doesn't exist - [ ] `hasEdge(source, target): boolean` - [ ] `getEdgeAttributes(source, target): EdgeAttrs` — throws if edge doesn't exist - [ ] `nodes(): string[]`, `edges(): string[]`, `order: number`, `size: number` - [ ] `forEachNode(callback)`, `forEachEdge(callback)` - [ ] `predecessors(nodeId)`, `successors(nodeId)` delegating to `graph.inNeighbors`/`graph.outNeighbors` - [ ] Static construction methods (`fromSpecs`, `fromCallEvents`, `fromJSON`) are stubs (throw "not implemented") - [ ] Re-exported from `src/graph/index.ts` and `src/index.ts` - [ ] Unit tests: constructor, node operations, edge operations, cycle detection on addEdge ## References - docs/architecture/flowgraph-api.md — FlowGraph class full API surface, delegation model - docs/architecture/schema.md — edge key convention - docs/architecture/error-handling.md — throwing contract for mutations ## Notes > To be filled by implementation agent ## Summary > To be filled on completion