feat(app): de-hardcode connector type unions through validation/executor/storage (#1121) - #1138
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughConnector type handling is converted from hardcoded enums/unions to registry-backed strings. New adapter exports and helper functions check registry membership; validation schemas, query executor, pipeline types, schema-prefetch, and the DB schema column are widened to plain strings; ConnectionTypes gains an UNKNOWN member; tests updated accordingly. ChangesRegistry-backed connector types
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant SchemaValidation as connectorTypeSchema
participant RegisteredTypes as registered-types.ts
participant Adapter as connection-adapter.ts
participant Executor as query-executor.ts
Client->>SchemaValidation: submit connection type (e.g. "mysql")
SchemaValidation->>RegisteredTypes: isRegisteredConnectorType(type)
RegisteredTypes->>Adapter: getConnector(type)
Adapter-->>RegisteredTypes: connector found
RegisteredTypes-->>SchemaValidation: true
SchemaValidation-->>Client: validation success
Client->>Executor: executeQuery(type)
Executor->>Executor: toConnectionTypeEnum(type) -> UNKNOWN
Executor->>Adapter: createConnectionModule(type, connectionType)
Adapter-->>Executor: connection module
Executor-->>Client: query result
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…tor/storage (#1121) Several paths assumed only the built-in 'neo4j' | 'postgresql' union, so a registry-supplied connector type couldn't flow through the app. - validation: schemas.ts accepts any registry-registered type via a runtime refine (isRegisteredConnectorType, routed through connection-adapter for test mockability) instead of z.enum(CONNECTOR_TYPES). - execution: query-executor DbType widened to string; toConnectionTypeEnum maps unknown types to a new ConnectionTypes.UNKNOWN sentinel rather than mislabeling them PostgreSQL. pipeline-types.connectionType + prefetchSchema widened to string. - storage: connection.type column pgEnum -> text; the accepted set is enforced at the API layer, not the DB. Migrations squashed 12 -> 1 (pre-launch, no users): the single initial now creates connection.type as text from the start, so there's no connection_type enum at all. CLI built-in list left as-is on purpose: a registry/external connector already lists via neoboard-connectors.json, and coupling the *published* @neoboard/cli to the *unpublished* @neoboard/connector-sdk would break `npm i -g`. Adding a built-in is itself a core change, so the "no core change per registry type" acceptance still holds. Verified: app tsc + lint clean, connections E2E 15/15 (squashed migration applies + registry validation + text-column store). Closes #1121 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f2c08e0 to
49433e8
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/src/lib/__tests__/query/query-executor-core.test.ts (1)
114-130: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the
UNKNOWNconfig path in this regression test.This only proves
"mysql"reachescreateConnectionModule. It does not verify the behavior changed inquery-executor.ts: non-built-in types should hitrunQuerywithconnectionType: ConnectionTypes.UNKNOWN. A regression back to PostgreSQL would still pass here.Suggested assertion
await executeQuery("mysql", pgCreds, { query: "SELECT 1" }); expect(mockCreateConnectionModule).toHaveBeenCalledWith( "mysql", expect.objectContaining({ uri: pgCreds.uri }), expect.any(Object), ); + expect(mockRunQuery).toHaveBeenCalledWith( + { query: "SELECT 1" }, + expect.any(Object), + expect.objectContaining({ connectionType: 0 }), + );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/lib/__tests__/query/query-executor-core.test.ts` around lines 114 - 130, Update the regression test in the executeQuery flow so it asserts the non-built-in connector is passed to runQuery with connectionType set to ConnectionTypes.UNKNOWN, not just that createConnectionModule receives "mysql". Use the existing executeQuery, mockRunQuery, and mockCreateConnectionModule setup to verify the args sent to runQuery include the UNKNOWN config path, ensuring query-executor.ts cannot regress to PostgreSQL behavior unnoticed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@app/src/lib/__tests__/query/query-executor-core.test.ts`:
- Around line 114-130: Update the regression test in the executeQuery flow so it
asserts the non-built-in connector is passed to runQuery with connectionType set
to ConnectionTypes.UNKNOWN, not just that createConnectionModule receives
"mysql". Use the existing executeQuery, mockRunQuery, and
mockCreateConnectionModule setup to verify the args sent to runQuery include the
UNKNOWN config path, ensuring query-executor.ts cannot regress to PostgreSQL
behavior unnoticed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2563e31d-18df-4782-837a-fef5e750b7ad
⛔ Files ignored due to path filters (3)
app/drizzle/migrations/0011_closed_captain_flint.sqlis excluded by!app/drizzle/migrations/**app/drizzle/migrations/meta/0011_snapshot.jsonis excluded by!app/drizzle/migrations/**app/drizzle/migrations/meta/_journal.jsonis excluded by!app/drizzle/migrations/**
📒 Files selected for processing (10)
app/src/lib/__tests__/query/query-executor-core.test.tsapp/src/lib/__tests__/shared/schemas.test.tsapp/src/lib/connector/connection-adapter.tsapp/src/lib/connector/registered-types.tsapp/src/lib/connector/schema-prefetch.tsapp/src/lib/db/schema.tsapp/src/lib/query/pipeline-types.tsapp/src/lib/query/query-executor.tsapp/src/lib/shared/schemas.tsconnector-sdk/src/ConnectionModuleConfig.ts
…1121) Registry-driven connector-type validation made schemas.ts transitively import the driver-heavy connection registry via connection-adapter. Route tests that validate `type` (create / test-inline / list-databases-inline) don't mock that seam, so `getConnector` was undefined under Vitest (production/E2E load it fine). Stub isRegisteredConnectorType in those three tests (true for built-ins, false otherwise — preserves the mysql→400 cases), and add a dedicated registered-types unit test for coverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|



Part of v1.2 Connector SDK (epic #1093) — seam gap B4. Branches from
release/1.2.What
Several paths assumed only the built-in
'neo4j' | 'postgresql'union, so a registry-supplied connector type couldn't flow through the app. Now registry types are first-class.schemas.tsaccepts any registry-registered type via a runtime refine (isRegisteredConnectorType, routed throughconnection-adapterfor test mockability) instead ofz.enum(CONNECTOR_TYPES).query-executorDbTypewidened tostring;toConnectionTypeEnummaps unknown types to a newConnectionTypes.UNKNOWNsentinel rather than mislabeling them PostgreSQL.pipeline-types.connectionType+prefetchSchemawidened.connection.typecolumnpgEnum → text(migration0011: enum→text preserves values, then drops the type). The accepted set is enforced at the API layer, not the DB.Acceptance
Tests
schemas.test.ts: a registry-supplied fixture type validates; unregistered rejected.query-executor-core.test.ts: a registry type resolves its module viacreateConnectionModule.connections.spec.tsE2E 15/15 (migration applies + validation + text-column store).Scope note — CLI intentionally left as-is
A registry/external connector already lists via
neoboard-connectors.json. Coupling the published@neoboard/clito the unpublished@neoboard/connector-sdkwould breaknpm i -g @neoboard/cli. Adding a built-in is itself a core change, so the "no core change per registry type" acceptance holds without touching the CLI's built-in list.Deferred (follow-up)
The
CONNECTOR_LANGUAGESdisplay map + the app/component duplicateDatabaseSchema'neo4j'|'postgresql'unions remain (separate from validation/executor/storage).Closes #1121
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes