mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
feat(core): add domain/flow/step node types and domain edge types for business domain knowledge
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ae00f58824
commit
37e56d62b3
@@ -0,0 +1,141 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { validateGraph } from "../schema.js";
|
||||
import type { KnowledgeGraph } from "../types.js";
|
||||
|
||||
const domainGraph: KnowledgeGraph = {
|
||||
version: "1.0.0",
|
||||
project: {
|
||||
name: "test-project",
|
||||
languages: ["typescript"],
|
||||
frameworks: [],
|
||||
description: "A test project",
|
||||
analyzedAt: "2026-04-01T00:00:00.000Z",
|
||||
gitCommitHash: "abc123",
|
||||
},
|
||||
nodes: [
|
||||
{
|
||||
id: "domain:order-management",
|
||||
type: "domain",
|
||||
name: "Order Management",
|
||||
summary: "Handles order lifecycle",
|
||||
tags: ["core"],
|
||||
complexity: "complex",
|
||||
},
|
||||
{
|
||||
id: "flow:create-order",
|
||||
type: "flow",
|
||||
name: "Create Order",
|
||||
summary: "Customer submits a new order",
|
||||
tags: ["write-path"],
|
||||
complexity: "moderate",
|
||||
domainMeta: {
|
||||
entryPoint: "POST /api/orders",
|
||||
entryType: "http",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "step:create-order:validate",
|
||||
type: "step",
|
||||
name: "Validate Input",
|
||||
summary: "Checks request body",
|
||||
tags: ["validation"],
|
||||
complexity: "simple",
|
||||
filePath: "src/validators/order.ts",
|
||||
lineRange: [10, 30],
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
source: "domain:order-management",
|
||||
target: "flow:create-order",
|
||||
type: "contains_flow",
|
||||
direction: "forward",
|
||||
weight: 1.0,
|
||||
},
|
||||
{
|
||||
source: "flow:create-order",
|
||||
target: "step:create-order:validate",
|
||||
type: "flow_step",
|
||||
direction: "forward",
|
||||
weight: 0.1,
|
||||
},
|
||||
],
|
||||
layers: [],
|
||||
tour: [],
|
||||
};
|
||||
|
||||
describe("domain graph types", () => {
|
||||
it("validates a domain graph with domain/flow/step node types", () => {
|
||||
const result = validateGraph(domainGraph);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data).toBeDefined();
|
||||
expect(result.data!.nodes).toHaveLength(3);
|
||||
expect(result.data!.edges).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("validates contains_flow edge type", () => {
|
||||
const result = validateGraph(domainGraph);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data!.edges[0].type).toBe("contains_flow");
|
||||
});
|
||||
|
||||
it("validates flow_step edge type", () => {
|
||||
const result = validateGraph(domainGraph);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data!.edges[1].type).toBe("flow_step");
|
||||
});
|
||||
|
||||
it("validates cross_domain edge type", () => {
|
||||
const graph = structuredClone(domainGraph);
|
||||
graph.nodes.push({
|
||||
id: "domain:logistics",
|
||||
type: "domain",
|
||||
name: "Logistics",
|
||||
summary: "Handles shipping",
|
||||
tags: [],
|
||||
complexity: "moderate",
|
||||
});
|
||||
graph.edges.push({
|
||||
source: "domain:order-management",
|
||||
target: "domain:logistics",
|
||||
type: "cross_domain",
|
||||
direction: "forward",
|
||||
description: "Triggers on order confirmed",
|
||||
weight: 0.6,
|
||||
});
|
||||
const result = validateGraph(graph);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it("normalizes domain type aliases", () => {
|
||||
const graph = structuredClone(domainGraph);
|
||||
(graph.nodes[0] as any).type = "business_domain";
|
||||
(graph.nodes[1] as any).type = "workflow";
|
||||
(graph.nodes[2] as any).type = "action";
|
||||
const result = validateGraph(graph);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data!.nodes[0].type).toBe("domain");
|
||||
expect(result.data!.nodes[1].type).toBe("flow");
|
||||
expect(result.data!.nodes[2].type).toBe("step");
|
||||
});
|
||||
|
||||
it("normalizes domain edge type aliases", () => {
|
||||
const graph = structuredClone(domainGraph);
|
||||
(graph.edges[0] as any).type = "has_flow";
|
||||
(graph.edges[1] as any).type = "next_step";
|
||||
const result = validateGraph(graph);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data!.edges[0].type).toBe("contains_flow");
|
||||
expect(result.data!.edges[1].type).toBe("flow_step");
|
||||
});
|
||||
|
||||
it("preserves domainMeta on nodes through validation", () => {
|
||||
const result = validateGraph(domainGraph);
|
||||
expect(result.success).toBe(true);
|
||||
const flowNode = result.data!.nodes.find((n) => n.id === "flow:create-order");
|
||||
expect((flowNode as any).domainMeta).toEqual({
|
||||
entryPoint: "POST /api/orders",
|
||||
entryType: "http",
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -686,11 +686,11 @@ describe("Extended node/edge types", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("auto-fixes new node type aliases: container->service, doc->document, workflow->pipeline, etc.", () => {
|
||||
it("auto-fixes new node type aliases: container->service, doc->document, workflow->flow, etc.", () => {
|
||||
const aliases: Record<string, string> = {
|
||||
container: "service",
|
||||
doc: "document",
|
||||
workflow: "pipeline",
|
||||
workflow: "flow",
|
||||
route: "endpoint",
|
||||
setting: "config",
|
||||
infra: "resource",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// Edge types (26 values across 6 categories)
|
||||
// Edge types (29 values across 7 categories)
|
||||
export const EdgeTypeSchema = z.enum([
|
||||
"imports", "exports", "contains", "inherits", "implements", // Structural
|
||||
"calls", "subscribes", "publishes", "middleware", // Behavioral
|
||||
@@ -9,6 +9,7 @@ export const EdgeTypeSchema = z.enum([
|
||||
"related", "similar_to", // Semantic
|
||||
"deploys", "serves", "provisions", "triggers", // Infrastructure
|
||||
"migrates", "documents", "routes", "defines_schema", // Schema/Data
|
||||
"contains_flow", "flow_step", "cross_domain", // Domain
|
||||
]);
|
||||
|
||||
// Aliases that LLMs commonly generate instead of canonical node types
|
||||
@@ -28,10 +29,8 @@ export const NODE_TYPE_ALIASES: Record<string, string> = {
|
||||
doc: "document",
|
||||
readme: "document",
|
||||
docs: "document",
|
||||
workflow: "pipeline",
|
||||
job: "pipeline",
|
||||
ci: "pipeline",
|
||||
action: "pipeline",
|
||||
route: "endpoint",
|
||||
api: "endpoint",
|
||||
query: "endpoint",
|
||||
@@ -50,6 +49,12 @@ export const NODE_TYPE_ALIASES: Record<string, string> = {
|
||||
protobuf: "schema",
|
||||
definition: "schema",
|
||||
typedef: "schema",
|
||||
// Domain aliases
|
||||
business_domain: "domain",
|
||||
process: "flow",
|
||||
workflow: "flow",
|
||||
action: "step",
|
||||
task: "step",
|
||||
};
|
||||
|
||||
// Aliases that LLMs commonly generate instead of canonical edge types
|
||||
@@ -79,6 +84,11 @@ export const EDGE_TYPE_ALIASES: Record<string, string> = {
|
||||
triggers_on: "triggers",
|
||||
fires: "triggers",
|
||||
defines: "defines_schema",
|
||||
// Domain aliases
|
||||
has_flow: "contains_flow",
|
||||
next_step: "flow_step",
|
||||
interacts_with: "cross_domain",
|
||||
implemented_by: "implements",
|
||||
};
|
||||
|
||||
// Aliases for complexity values LLMs commonly generate
|
||||
@@ -313,6 +323,7 @@ export const GraphNodeSchema = z.object({
|
||||
"file", "function", "class", "module", "concept",
|
||||
"config", "document", "service", "table", "endpoint",
|
||||
"pipeline", "schema", "resource",
|
||||
"domain", "flow", "step",
|
||||
]),
|
||||
name: z.string(),
|
||||
filePath: z.string().optional(),
|
||||
@@ -321,7 +332,7 @@ export const GraphNodeSchema = z.object({
|
||||
tags: z.array(z.string()),
|
||||
complexity: z.enum(["simple", "moderate", "complex"]),
|
||||
languageNotes: z.string().optional(),
|
||||
});
|
||||
}).passthrough();
|
||||
|
||||
export const GraphEdgeSchema = z.object({
|
||||
source: z.string(),
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Node types (13 total: 5 code + 8 non-code)
|
||||
// Node types (16 total: 5 code + 8 non-code + 3 domain)
|
||||
export type NodeType =
|
||||
| "file" | "function" | "class" | "module" | "concept"
|
||||
| "config" | "document" | "service" | "table" | "endpoint"
|
||||
| "pipeline" | "schema" | "resource";
|
||||
| "pipeline" | "schema" | "resource"
|
||||
| "domain" | "flow" | "step";
|
||||
|
||||
// Edge types (26 total in 6 categories: Structural, Behavioral, Data flow, Dependencies, Semantic, Infrastructure/Schema)
|
||||
// Edge types (29 total in 7 categories: Structural, Behavioral, Data flow, Dependencies, Semantic, Infrastructure/Schema, Domain)
|
||||
export type EdgeType =
|
||||
| "imports" | "exports" | "contains" | "inherits" | "implements" // Structural
|
||||
| "calls" | "subscribes" | "publishes" | "middleware" // Behavioral
|
||||
@@ -12,9 +13,19 @@ export type EdgeType =
|
||||
| "depends_on" | "tested_by" | "configures" // Dependencies
|
||||
| "related" | "similar_to" // Semantic
|
||||
| "deploys" | "serves" | "provisions" | "triggers" // Infrastructure
|
||||
| "migrates" | "documents" | "routes" | "defines_schema"; // Schema/Data
|
||||
| "migrates" | "documents" | "routes" | "defines_schema" // Schema/Data
|
||||
| "contains_flow" | "flow_step" | "cross_domain"; // Domain
|
||||
|
||||
// GraphNode with 13 types: 5 code + 8 non-code
|
||||
// Optional domain metadata for domain/flow/step nodes
|
||||
export interface DomainMeta {
|
||||
entities?: string[];
|
||||
businessRules?: string[];
|
||||
crossDomainInteractions?: string[];
|
||||
entryPoint?: string;
|
||||
entryType?: "http" | "cli" | "event" | "cron" | "manual";
|
||||
}
|
||||
|
||||
// GraphNode with 16 types: 5 code + 8 non-code + 3 domain
|
||||
export interface GraphNode {
|
||||
id: string;
|
||||
type: NodeType;
|
||||
@@ -25,6 +36,7 @@ export interface GraphNode {
|
||||
tags: string[];
|
||||
complexity: "simple" | "moderate" | "complex";
|
||||
languageNotes?: string;
|
||||
domainMeta?: DomainMeta;
|
||||
}
|
||||
|
||||
// GraphEdge with rich relationship modeling
|
||||
|
||||
Reference in New Issue
Block a user