agentsclimarketplace

Add query mode

Skill cliftonc/drizzle-cube/.claude/skills/add-query-mode

Use when adding a new analysis/query mode to drizzle-cube (e.g., cohort, path analysis). Covers backend types, query builder, executor/compiler integration, frontend adapter, store slice, hooks, UI components, tests, and icon.From its SKILL.md

Install
npx -y skills add cliftonc/drizzle-cube --skill add-query-mode

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

9.7 KB, as published. Nobody here has run it

Adding a Query Mode

Drizzle-cube has four analysis modes: query, funnel, flow, and retention. Each mode requires coordinated changes across backend (types → query builder → executor → compiler → cache), frontend (types → adapter → store slice → hooks → UI), tests, and an icon. Follow this checklist in order.

Documentation Context

Before designing or updating an analysis/query mode, review https://www.drizzle-cube.dev/llms.txt for the current documentation map, public API guidance, and mode-related examples. Use repository source and the checklist below as the implementation source of truth when docs and code differ.

Checklist

Backend

  • 1. Create type definitions — Create src/server/types/{mode}.ts with {Mode}QueryConfig, {Mode}ResultRow, and {Mode}ValidationResult interfaces. Export from src/server/types/index.ts. Add optional {mode}?: {Mode}QueryConfig field to SemanticQuery in src/server/types/query.ts.

  • 2. Create query builder — Create src/server/builders/{mode}-query-builder.ts with: has{Mode}(query) detection, validateConfig(config, cubes) validation, build{Mode}Query(config, cubes, context) SQL generation via Drizzle, and transformResult(rawResult) post-processing.

  • 3. Integrate with executor — In src/server/executor.ts, add a {mode}QueryBuilder field to the QueryExecutor class, initialize it in the constructor, add detection in the execute() method, add routing to a new execute{Mode}QueryWithCache() method, and implement execute{Mode}Query() and dryRun{Mode}() methods.

  • 4. Integrate with compiler — In src/server/compiler.ts, add a dryRun{Mode}() public method, add a validation path in validateQueryAgainstCubes(), and add routing in explainQuery().

  • 5. Update cache utils — In src/server/cache-utils.ts, add normalize{Mode}Config() and wire it into normalizeQuery().

  • 6. Database adapter updates (if mode needs DB-specific SQL) — Add abstract methods to src/server/adapters/base-adapter.ts and implement in postgres, mysql, sqlite, duckdb, snowflake, singlestore, and databend adapters.

  • 7. Update AI prompts (if AI should understand this mode) — Update src/server/prompts/types.ts and src/server/prompts/step1-shape-prompt.ts with mode-specific query structures.

Frontend

  • 8. Create frontend types — Create src/client/types/{mode}.ts with {Mode}SliceState, Server{Mode}Query, {Mode}ChartData, and type guards. Export public types from src/client/index.ts.

  • 9. Update AnalysisConfig types — In src/client/types/analysisConfig.ts, add '{mode}' to the AnalysisType union, create {Mode}AnalysisConfig extending AnalysisConfigBase, and add to the AnalysisConfig union type.

  • 10. Create mode adapter — Create src/client/adapters/{mode}ModeAdapter.ts implementing ModeAdapter<{Mode}SliceState> with: type, createInitial(), extractState() (critical for workspace persistence), canLoad(), load(), save(), validate(), clear(), getDefaultChartConfig(). Register via adapterRegistry.register() in src/client/adapters/adapterRegistry.ts.

  • 11. Create store slice — Create src/client/stores/slices/{mode}Slice.ts with state interface, actions (including build{Mode}Query() returning Server{Mode}Query | null and is{Mode}ModeEnabled()), and createInitial{Mode}State(). Export from src/client/stores/slices/index.ts. Compose into src/client/stores/analysisBuilderStore.tsx.

  • 12. Create query hook — Create src/client/hooks/queries/use{Mode}Query.ts handling debouncing, caching, and result transformation via useQuery. Export from src/client/hooks/queries/index.ts. A single shared useDryRunQuery.ts already handles SQL preview for all modes.

  • 13. Update query execution — In src/client/hooks/useAnalysisQueryExecution.ts, add server{Mode}Query to the options interface and add mode routing. In src/client/hooks/useAnalysisBuilderHook.ts, add mode-specific state and actions to the hook result.

  • 14. Create UI components — Create src/client/components/AnalysisBuilder/{Mode}ModeContent.tsx (main mode panel) and {Mode}ConfigPanel.tsx (configuration UI). Update AnalysisQueryPanel.tsx to conditionally render {Mode}ModeContent. Update AnalysisTypeSelector.tsx to add the mode option.

  • 15. Update portlet integration — Update src/client/components/AnalyticsPortlet.tsx and src/client/components/PortletContainer.tsx to detect and handle the new mode's queries.

  • 16. Add icon — In src/client/icons/customIcons.ts, create {mode}Icon: IconifyIcon with appropriate SVG path data.

  • 17. Chart type integration (if mode needs a new chart type) — Create chart component in src/client/components/charts/, update src/client/shared/chartDefaults.ts getChartAvailability(), and update ChartTypeSelector excludeTypes.

Testing

  • 18. Backend tests — Create tests/{mode}-query.test.ts covering query builder methods, execution integration, security context isolation, cross-cube filtering, and multi-database compatibility (TEST_DB_TYPE env).

  • 19. Client adapter tests — Create tests/client/adapters/{mode}ModeAdapter.test.ts covering createInitial(), canLoad(), load(), save(), validate(), clear(), getDefaultChartConfig(), and a round-trip test (save → load state equivalence).

  • 20. Client validation and execution tests — Create tests/client/{mode}/{mode}Validation.test.ts and tests/client/{mode}/{mode}Execution.test.ts for validation functions, data transformations, and metric calculations.

File Reference

FileActionKey Symbols
src/server/types/{mode}.tsCreate{Mode}QueryConfig, {Mode}ResultRow
src/server/types/index.tsExport new types—
src/server/types/query.tsAdd field to unionSemanticQuery
src/server/builders/{mode}-query-builder.tsCreatehas{Mode}(), build{Mode}Query(), validateConfig(), transformResult()
src/server/executor.tsAdd builder + routingQueryExecutor, execute(), execute{Mode}QueryWithCache()
src/server/compiler.tsAdd public methodsdryRun{Mode}(), validateQueryAgainstCubes(), explainQuery()
src/server/cache-utils.tsAdd normalizernormalize{Mode}Config(), normalizeQuery()
src/client/types/{mode}.tsCreate{Mode}SliceState, Server{Mode}Query, {Mode}ChartData
src/client/types/analysisConfig.tsExtend union + configAnalysisType, {Mode}AnalysisConfig
src/client/adapters/{mode}ModeAdapter.tsCreate{mode}ModeAdapter : ModeAdapter
src/client/adapters/adapterRegistry.tsRegister adapteradapterRegistry.register()
src/client/stores/slices/{mode}Slice.tsCreatecreate{Mode}Slice, createInitial{Mode}State()
src/client/stores/analysisBuilderStore.tsxCompose slicecreateAnalysisBuilderStore()
src/client/hooks/queries/use{Mode}Query.tsCreateuse{Mode}Query()
src/client/hooks/useAnalysisQueryExecution.tsAdd mode routingserver{Mode}Query
src/client/hooks/useAnalysisBuilderHook.tsAdd state/actions—
src/client/components/AnalysisBuilder/{Mode}ModeContent.tsxCreate—
src/client/components/AnalysisBuilder/{Mode}ConfigPanel.tsxCreate—
src/client/components/AnalysisBuilder/AnalysisTypeSelector.tsxAdd option—
src/client/components/AnalysisBuilder/AnalysisQueryPanel.tsxAdd conditional render—
src/client/components/AnalyticsPortlet.tsxAdd mode detection—
src/client/icons/customIcons.tsAdd icon{mode}Icon : IconifyIcon

Reference Implementations

Study these existing modes as patterns (paths only — read the files directly):

Funnel — src/server/builders/funnel-query-builder.ts, src/server/types/funnel.ts, src/client/adapters/funnelModeAdapter.ts, src/client/types/funnel.ts, src/client/stores/slices/funnelSlice.ts, src/client/hooks/queries/useFunnelQuery.ts, src/client/components/AnalysisBuilder/FunnelModeContent.tsx, src/client/components/AnalysisBuilder/FunnelConfigPanel.tsx, tests/funnel-query.test.ts, tests/client/adapters/funnelModeAdapter.test.ts

Flow — src/server/builders/flow-query-builder.ts, src/server/types/flow.ts, src/client/adapters/flowModeAdapter.ts, src/client/types/flow.ts, src/client/stores/slices/flowSlice.ts, src/client/hooks/queries/useFlowQuery.ts, src/client/components/AnalysisBuilder/FlowModeContent.tsx, tests/flow-query.test.ts, tests/client/adapters/flowModeAdapter.test.ts

Retention — src/server/builders/retention-query-builder.ts, src/server/types/retention.ts, src/client/adapters/retentionModeAdapter.ts, src/client/types/retention.ts, src/client/stores/slices/retentionSlice.ts, src/client/hooks/queries/useRetentionQuery.ts, src/client/components/AnalysisBuilder/RetentionModeContent.tsx, src/client/components/AnalysisBuilder/RetentionConfigPanel.tsx, tests/retention-query.test.ts, tests/client/adapters/retentionModeAdapter.test.ts

Verification

  • npx tsc --noEmit — zero type errors
  • npm test -- {mode}-query.test.ts — backend tests pass
  • npm test -- {mode}ModeAdapter.test.ts — adapter tests pass
  • npm run build — successful build
  • New mode appears in AnalysisTypeSelector with correct icon
  • Mode adapter round-trips correctly (save → load preserves state)

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.