Skip to content

feat: component-kind-aware spec attachment with four new parsers#56

Merged
CuriouslyCory merged 1 commit into
mainfrom
feat/component-kind-aware-specs
Jun 1, 2026
Merged

feat: component-kind-aware spec attachment with four new parsers#56
CuriouslyCory merged 1 commit into
mainfrom
feat/component-kind-aware-specs

Conversation

@CuriouslyCory

@CuriouslyCory CuriouslyCory commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

Generalizes "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. 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.

  • Parser registryflow-parser.ts split into flow-parser/{index,shared}.ts + parsers/*.ts. An exhaustive Record<FlowSpecKind, SpecParser | null> is the compile guard; adding a routable format is one parser module + one line.
  • Four new parsers — AsyncAPI (v2 + v3), GraphQL SDL, SQL DDL (node-sql-parser, multi-dialect), TypeScript signatures (ts.createSourceFile, syntax-only). All bounded, never-throw, no $ref/import resolution. Interaction is owner-relative — notably AsyncAPI v2 publish → SUBSCRIBE / subscribe → PUSH per the 2.x spec, which inverts the intuitive reading.
  • Kind-aware picker — new client-safe src/lib/spec-kinds.ts maps NodeKind → FlowSpecKind[] (mirroring KIND_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.
  • Enums in lockstepFlowSpecKind += SQL_DDL; FlowKind += DB_TABLE, GRAPHQL_FIELD. Migrated across Prisma + Zod + the parity guards (flow.service.ts). Migration applied via pnpm db:author / pnpm db:migrate per ADR-0010.
  • Dependencies — adds graphql, node-sql-parser; promotes typescript from devDependencies to dependencies (used only by the server-only TS-signature parser).
  • DocsCONTEXT.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.md for the full rationale.

Test plan

  • pnpm check — eslint + strict tsc clean (exhaustive Records prove no enum/kind was missed)
  • pnpm build — production build green; the server-only parsers (incl. promoted typescript) don't leak into a client bundle
  • pnpm test266 passed, 26 new parser cases (per-parser happy path, malformed → sanitized parseError, count caps, AsyncAPI v2 owner-relative inversion, GraphQL custom root types)
  • End-to-end via dev-browser — Database component shows only SQL schema / Custom; pasted a 2-table CREATE TABLE DDL → 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 (coderabbit review --agent --base main) — 0 critical, 0 warning, 1 minor: a false positive about strict typing on names[opType.operation] that tsc --noEmit accepts 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

  • Flow rendering in markdown / MCP (issue Slice 5: Aggregated parent rendering + markdown export for Flows #38) — the new FlowKinds (DB_TABLE, GRAPHQL_FIELD) are flagged in ADR-0025 for that work. Canvas routing is kind-agnostic and works immediately.
  • SQL foreign keys → Connection materialization — FKs are captured in each table's signature, but not drawn as edges between tables. Possible follow-up.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for SQL DDL and GraphQL schema specifications as attachment options.
    • Introduced new flow types: DB_TABLE and GRAPHQL_FIELD.
    • Enhanced spec attachment UI now dynamically displays relevant options based on component type.
    • Expanded parser support for AsyncAPI, OpenAPI, GraphQL, SQL DDL, and TypeScript signatures with improved error handling.
  • Documentation

    • Updated architecture documentation for FlowSpec parsing strategy and component spec affinity.

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>
@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
infinite-docs Ready Ready Preview, Comment Jun 1, 2026 6:22am

Request Review

@CuriouslyCory CuriouslyCory merged commit 4ffd9be into main Jun 1, 2026
2 of 3 checks passed
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1e2facea-3621-4387-acc9-072a38d7cd73

📥 Commits

Reviewing files that changed from the base of the PR and between edc3f36 and fc8cfae.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • CONTEXT.md
  • docs/adr/0025-flowspec-parser-registry-and-spec-kind-affinity.md
  • package.json
  • prisma/migrations/20260601054742_add_sql_ddl_and_flow_kinds/migration.sql
  • prisma/schema.prisma
  • src/app/p/[slug]/_canvas/component-detail-panel.tsx
  • src/lib/schemas.ts
  • src/lib/spec-kinds.ts
  • src/server/architecture/__tests__/flow-parser.test.ts
  • src/server/architecture/flow-parser.ts
  • src/server/architecture/flow-parser/index.ts
  • src/server/architecture/flow-parser/parsers/asyncapi.ts
  • src/server/architecture/flow-parser/parsers/graphql.ts
  • src/server/architecture/flow-parser/parsers/openapi.ts
  • src/server/architecture/flow-parser/parsers/sql-ddl.ts
  • src/server/architecture/flow-parser/parsers/ts-signature.ts
  • src/server/architecture/flow-parser/shared.ts
  • src/server/architecture/flow.service.ts

📝 Walkthrough

Walkthrough

This 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.

Changes

FlowSpec Parser Registry Refactor and Type System

Layer / File(s) Summary
Data model expansion and enum parity
prisma/schema.prisma, prisma/migrations/..., src/lib/schemas.ts, src/server/architecture/flow.service.ts
FlowKind gains GRAPHQL_FIELD and DB_TABLE; FlowSpecKind gains SQL_DDL. Prisma schema, migrations, client Zod enums, and service enum parity guards are all updated together to maintain type safety.
Parsing dependencies and shared primitives
package.json, src/server/architecture/flow-parser/shared.ts
Adds graphql and node-sql-parser dependencies. Defines ParsedFlow/ParseFlowSpecResult types and bounded safety helpers (byte-cap, depth walker, YAML/JSON loader) used by all parsers.
Parser registry and OpenAPI parser
src/server/architecture/flow-parser/index.ts, src/server/architecture/flow-parser/parsers/openapi.ts
Creates registry entry point that enforces 1MB byte caps and exhaustive compile-time dispatch by FlowSpecKind. Implements OpenAPI parser extracting paths and HTTP methods with REQUEST interaction.
AsyncAPI and GraphQL parsers
src/server/architecture/flow-parser/parsers/asyncapi.ts, src/server/architecture/flow-parser/parsers/graphql.ts
AsyncAPI parser handles v2 (publish/subscribe with owner-relative inversion) and v3 (action-based send/receive) with appropriate interaction mapping. GraphQL parser extracts root fields with schema-block root type resolution and subscription-as-PUSH semantics.
SQL DDL and TypeScript signature parsers
src/server/architecture/flow-parser/parsers/sql-ddl.ts, src/server/architecture/flow-parser/parsers/ts-signature.ts
SQL DDL parser extracts CREATE TABLE with columns, primary keys, foreign keys. TypeScript parser extracts top-level functions, const-arrow functions, and methods with parameter/return type signatures.
Parser test coverage
src/server/architecture/__tests__/flow-parser.test.ts
Comprehensive test suite for all parsers covering CUSTOM (no-parser error), interaction mapping inversions, signature extraction, depth/operation caps, and sanitized parse errors.

Client-Side Spec Kind Affinity and Component UI

Layer / File(s) Summary
Spec kind catalog and affinity mapping
src/lib/spec-kinds.ts
Defines SPEC_KIND_LABEL and SPEC_KIND_PLACEHOLDER per spec kind for UI display. Exports exhaustive SPEC_KIND_AFFINITY mapping NodeKind to ordered supported spec kinds and specKindsFor(kind) helper appending CUSTOM only when affinity is non-empty.
Kind-aware Attach-spec panel
src/app/p/[slug]/_canvas/component-detail-panel.tsx
Refactors AttachSpecSection to compute available spec kinds from selected component kind, clamp selected kind to valid options, hide Attach-spec entirely when no structured specs apply, and display kind-specific labels and placeholders.

Architecture Documentation

Layer / File(s) Summary
Glossary and ADR documentation
CONTEXT.md, docs/adr/0025-flowspec-parser-registry-and-spec-kind-affinity.md
Updates CONTEXT.md FlowSpec/FlowKind/FlowSpecKind definitions to clarify non-destructive re-parsing, registry-based parser selection, and presentation-only affinity. Adds ADR-0025 documenting the parser registry decision, shared bounded primitives, exhaustive compile-time dispatch, parser-specific owner-relative interaction derivation, and client-side kind-aware affinity picker.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • CuriouslyCory/infinite-docs#41: Introduces the initial single-purpose flow-parser.ts module that this PR refactors into a modular registry with multiple parser implementations.
  • CuriouslyCory/infinite-docs#54: Updates parser output expectations from polarity to interaction, which directly aligns with this PR's refactored parser-output contract.
  • CuriouslyCory/infinite-docs#49: Introduces kind-aware Canvas UI with NodeKind selection and breadcrumbs, which this PR extends by making the Attach-spec panel driven by the selected currentKind affinity.

🐰 A registry of parsers, each bounded and pure,
FlowSpecs now render in flavors for sure—
Kind-aware affinity guides what we show,
SQL, GraphQL, AsyncAPI flow!
hops excitedly

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/component-kind-aware-specs

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant