feat: component-kind-aware spec attachment with four new parsers#56
Conversation
Generalize "attach spec" beyond OpenAPI. The FlowSpec → Flow → FlowRoute
data model was already kind-agnostic; the OpenAPI-specificity lived only in
the parser and the picker.
- Parser registry: split flow-parser.ts into flow-parser/{index,shared}.ts +
parsers/*.ts. An exhaustive Record<FlowSpecKind, SpecParser|null> is the
compile guard; adding a routable format is a parser module + one line.
- Four new bounded, never-throw parsers: AsyncAPI (v2+v3), GraphQL SDL,
SQL DDL (node-sql-parser), TypeScript signatures (syntax-only).
Interaction is owner-relative — notably AsyncAPI v2 publish→SUBSCRIBE /
subscribe→PUSH per the 2.x spec.
- Enums in lockstep: FlowSpecKind += SQL_DDL, FlowKind += DB_TABLE,
GRAPHQL_FIELD (Prisma + Zod + parity guards + migration).
- Kind-aware picker: src/lib/spec-kinds.ts maps NodeKind → relevant spec
kinds (presentation-only, ADR-0019); the Attach-spec section hides where
no spec fits.
- Deps: add graphql, node-sql-parser; promote typescript to a runtime dep
(used only by the server-only TS-signature parser).
- Docs: CONTEXT.md Flow/FlowSpec entries + ADR-0025.
Verified: pnpm check, pnpm build, 266 tests, and a dev-browser walkthrough
routing SQL tables onto a connection (2/2 routed, derived arrowhead).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (18)
📝 WalkthroughWalkthroughThis PR implements a modular FlowSpec parser registry supporting five spec kinds (OpenAPI, AsyncAPI, GraphQL, SQL DDL, TypeScript) with shared safety primitives. It expands the data model, introduces kind-aware client UI affinity rules, and documents the architecture via ADR-0025. ChangesFlowSpec Parser Registry Refactor and Type System
Client-Side Spec Kind Affinity and Component UI
Architecture Documentation
Sequence Diagram(s)sequenceDiagram
participant User
participant AttachSpec as Attach Spec Panel
participant specKindsFor
participant parseFlowSpec
participant SpecParser as Parser (kind-specific)
User->>AttachSpec: Select Component kind
AttachSpec->>specKindsFor: specKindsFor(currentKind)
specKindsFor-->>AttachSpec: [OPENAPI, ASYNCAPI, ...] + CUSTOM
AttachSpec->>AttachSpec: Render kind-aware <select>
User->>AttachSpec: Paste spec source, Submit
AttachSpec->>parseFlowSpec: parseFlowSpec(selectedKind, source)
parseFlowSpec->>parseFlowSpec: Check byte cap (1MB)
alt Parser exists for kind
parseFlowSpec->>SpecParser: Dispatch to parser
SpecParser->>SpecParser: Load YAML/JSON, validate depth
SpecParser->>SpecParser: Extract flows (kind-specific logic)
SpecParser-->>parseFlowSpec: { flows } or { parseError }
else No parser (CUSTOM)
parseFlowSpec-->>AttachSpec: { parseError: "no parser" }
end
parseFlowSpec-->>AttachSpec: ParseFlowSpecResult
AttachSpec->>AttachSpec: Display flows or error
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Summary
Generalizes "attach spec" beyond OpenAPI. The
FlowSpec → Flow → FlowRoutedata model was already kind-agnostic; the OpenAPI-specificity lived only in the parser and the picker. This PR turns the parser into a registry and the picker into a kind-aware affordance, then ships four new parsers — so a database accepts SQL DDL whose tables route through the diagram exactly like API endpoints.flow-parser.tssplit intoflow-parser/{index,shared}.ts+parsers/*.ts. An exhaustiveRecord<FlowSpecKind, SpecParser | null>is the compile guard; adding a routable format is one parser module + one line.ts.createSourceFile, syntax-only). All bounded, never-throw, no$ref/import resolution. Interaction is owner-relative — notably AsyncAPI v2publish → SUBSCRIBE/subscribe → PUSHper the 2.x spec, which inverts the intuitive reading.src/lib/spec-kinds.tsmapsNodeKind → FlowSpecKind[](mirroringKIND_AFFINITY). The Attach-spec section hides entirely on kinds with no sensible spec (infra/structural). Presentation-only per ADR-0019 — the service still accepts any spec kind on any kind.FlowSpecKind += SQL_DDL;FlowKind += DB_TABLE, GRAPHQL_FIELD. Migrated across Prisma + Zod + the parity guards (flow.service.ts). Migration applied viapnpm db:author/pnpm db:migrateper ADR-0010.graphql,node-sql-parser; promotestypescriptfromdevDependenciestodependencies(used only by the server-only TS-signature parser).CONTEXT.md(Flow / FlowSpec / Flow kind / Flow spec kind) + new ADR-0025 (parser registry + spec-kind affinity).See
docs/adr/0025-flowspec-parser-registry-and-spec-kind-affinity.mdfor the full rationale.Test plan
pnpm check— eslint + strict tsc clean (exhaustiveRecords prove no enum/kind was missed)pnpm build— production build green; the server-only parsers (incl. promotedtypescript) don't leak into a client bundlepnpm test— 266 passed, 26 new parser cases (per-parser happy path, malformed → sanitizedparseError, count caps, AsyncAPI v2 owner-relative inversion, GraphQL custom root types)CREATE TABLEDDL → toast "Parsed 2 flows"; connected DB → Service; routed both tables via+ flow→ connection shows "2 / 2 routed" with the derived arrowhead pointing at the database (REQUEST). Service shows OpenAPI / GraphQL SDL / TypeScript signatures / Custom. Network correctly hides the Attach-spec section.coderabbit review --agent --base main) — 0 critical, 0 warning, 1 minor: a false positive about strict typing onnames[opType.operation]thattsc --noEmitaccepts cleanly; leaving the code as-is per philosophy Drag-to-reposition + inline rename #6 (don't change code to silence a tool when the code is provably correct).Out of scope
FlowKinds (DB_TABLE,GRAPHQL_FIELD) are flagged in ADR-0025 for that work. Canvas routing is kind-agnostic and works immediately.signature, but not drawn as edges between tables. Possible follow-up.🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation