// 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.
[HINT] Download the complete skill directory including SKILL.md and all related files
name
add-query-mode
description
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.
metadata
{"author":"cliftonc"}
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.
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.
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.tsgetChartAvailability(), and update ChartTypeSelectorexcludeTypes.
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.