Staging#37
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Caution Review failedThe pull request is closed. WalkthroughThis update introduces a major refactor and modularization of analytics processing in the codebase. Core logic for funnel and goal analytics is extracted into reusable utility modules, and new routers, including an autocomplete router, are added to the API. Type annotations are improved across query builder modules, and several UI components are refactored for better accessibility, clarity, and prop typing. Some scripts and configuration files are updated for improved development workflows. Changes
Changes Table (Cohorts)
Sequence Diagram(s)sequenceDiagram
participant Client
participant Dashboard
participant API Router
participant AnalyticsUtils
participant Database
Client->>Dashboard: Request funnel analytics (with filters/referrer)
Dashboard->>API Router: Call getAnalytics/getAnalyticsByReferrer
API Router->>AnalyticsUtils: processFunnelAnalytics/processFunnelAnalyticsByReferrer
AnalyticsUtils->>Database: Query event/session data
Database-->>AnalyticsUtils: Return raw analytics data
AnalyticsUtils-->>API Router: Return processed analytics (conversion rates, dropoffs, etc.)
API Router-->>Dashboard: Return analytics result
Dashboard-->>Client: Render analytics UI (funnel, referrer breakdown, etc.)
sequenceDiagram
participant Dashboard
participant API Router
participant AutocompleteRouter
participant Database
Dashboard->>API Router: Call autocomplete.get (websiteId, date range)
API Router->>AutocompleteRouter: Fetch autocomplete suggestions
AutocompleteRouter->>Database: Query distinct event fields
Database-->>AutocompleteRouter: Return raw suggestion data
AutocompleteRouter-->>API Router: Return categorized suggestions
API Router-->>Dashboard: Return autocomplete data
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (6)
apps/api/src/query/screen-resolution-to-device-type.ts (1)
29-31: Remove unnecessary type check.After
screenResolution.split('x'), the array elements will always be strings, making this type check redundant.- if (typeof widthStr !== 'string' || typeof heightStr !== 'string') { - return null; - }packages/rpc/src/routers/autocomplete.ts (2)
28-29: Consider extracting hardcoded event names as constants.The excluded event names ('screen_view', 'page_exit', 'error', 'web_vitals', 'link_out') are hardcoded in the SQL query. Consider defining these as constants for better maintainability.
Add constants at the top of the file:
const EXCLUDED_EVENT_NAMES = ['screen_view', 'page_exit', 'error', 'web_vitals', 'link_out'] as const;Then use them in the query by joining them as a string.
104-134: Optimize categorization for better performance.The current implementation filters the results array multiple times. Consider using a single loop for better performance.
-const categorizeAutocompleteResults = ( - results: Array<{ category: string; value: string }> -) => ({ - customEvents: results - .filter((r) => r.category === 'customEvents') - .map((r) => r.value), - pagePaths: results - .filter((r) => r.category === 'pagePaths') - .map((r) => r.value), - browsers: results - .filter((r) => r.category === 'browsers') - .map((r) => r.value), - operatingSystems: results - .filter((r) => r.category === 'operatingSystems') - .map((r) => r.value), - countries: results - .filter((r) => r.category === 'countries') - .map((r) => r.value), - deviceTypes: results - .filter((r) => r.category === 'deviceTypes') - .map((r) => r.value), - utmSources: results - .filter((r) => r.category === 'utmSources') - .map((r) => r.value), - utmMediums: results - .filter((r) => r.category === 'utmMediums') - .map((r) => r.value), - utmCampaigns: results - .filter((r) => r.category === 'utmCampaigns') - .map((r) => r.value), -}); +const categorizeAutocompleteResults = ( + results: Array<{ category: string; value: string }> +) => { + const categorized = { + customEvents: [] as string[], + pagePaths: [] as string[], + browsers: [] as string[], + operatingSystems: [] as string[], + countries: [] as string[], + deviceTypes: [] as string[], + utmSources: [] as string[], + utmMediums: [] as string[], + utmCampaigns: [] as string[], + }; + + for (const { category, value } of results) { + if (category in categorized) { + categorized[category as keyof typeof categorized].push(value); + } + } + + return categorized; +};apps/dashboard/app/(main)/websites/[id]/funnels/page.tsx (1)
47-47: Use Array.from instead of Array constructorReplace
[...new Array(n)]withArray.from({length: n})to avoid using the Array constructor.-{[...new Array(3)].map((_, i) => ( +{Array.from({length: 3}).map((_, i) => (Apply similar changes to lines 107 and 129.
Also applies to: 107-107, 129-129
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx (1)
107-107: Use Array.from instead of Array constructorReplace
[...new Array(n)]withArray.from({length: n})to avoid using the Array constructor.-{[...new Array(4)].map((_, i) => ( +{Array.from({length: 4}).map((_, i) => (Apply similar change to line 129.
Also applies to: 129-129
packages/rpc/src/lib/analytics-utils.ts (1)
207-276: Consider documenting the placeholder time-based metrics.The time-based metrics (
avg_completion_time,avg_time_to_complete) are currently hardcoded to 0. Consider adding a TODO comment to indicate these are placeholders for future implementation.return { step_number: 1, step_name: firstStep.name, users: goalCompletions, total_users: totalWebsiteUsers, conversion_rate, dropoffs: 0, dropoff_rate: 0, + // TODO: Implement time-based analytics avg_time_to_complete: 0, }, ]; return { overall_conversion_rate: conversion_rate, total_users_entered: totalWebsiteUsers, total_users_completed: goalCompletions, + // TODO: Implement time-based analytics avg_completion_time: 0, avg_completion_time_formatted: '0s', steps_analytics: analyticsResults, };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
apps/api/src/query/builders/errors.ts(1 hunks)apps/api/src/query/builders/pages.ts(3 hunks)apps/api/src/query/builders/profiles.ts(2 hunks)apps/api/src/query/builders/sessions.ts(2 hunks)apps/api/src/query/builders/summary.ts(2 hunks)apps/api/src/query/builders/traffic.ts(1 hunks)apps/api/src/query/screen-resolution-to-device-type.ts(2 hunks)apps/api/src/query/simple-builder.ts(2 hunks)apps/api/src/query/types.ts(1 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx(3 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx(9 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsx(3 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsx(1 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsx(3 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsx(2 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/_components/page-header.tsx(0 hunks)apps/dashboard/app/(main)/websites/[id]/funnels/page.tsx(6 hunks)apps/dashboard/hooks/use-funnels.ts(1 hunks)apps/database/package.json(1 hunks)package.json(1 hunks)packages/rpc/src/lib/analytics-utils.ts(1 hunks)packages/rpc/src/lib/logger.ts(1 hunks)packages/rpc/src/root.ts(2 hunks)packages/rpc/src/routers/autocomplete.ts(1 hunks)packages/rpc/src/routers/funnels.ts(10 hunks)packages/rpc/src/routers/goals.ts(4 hunks)
💤 Files with no reviewable changes (1)
- apps/dashboard/app/(main)/websites/[id]/funnels/_components/page-header.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/01-MUST-DO.mdc)
**/*.{ts,tsx}: Always ensure type-safety, don't use type: any unless needed, when creating APIs, responses, or components, create proper interfaces and make them in the shared types folders where it fits best, not in the same file
Never throw errors in server actions, use try catch and return the error to the client
**/*.{ts,tsx}: Don't use primitive type aliases or misleading types.
Don't use empty type parameters in type aliases and interfaces.
Don't use any or unknown as type constraints.
Don't return a value from a function with the return type 'void'.
Don't use the TypeScript directive @ts-ignore.
Don't use TypeScript enums.
Don't export imported variables.
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Don't use TypeScript namespaces.
Don't use non-null assertions with the!postfix operator.
Don't use parameter properties in class constructors.
Don't use user-defined types.
Useas constinstead of literal types and type annotations.
Use eitherT[]orArray<T>consistently.
Initialize each enum member value explicitly.
Useexport typefor types.
Useimport typefor types.
Make sure all enum members are literal values.
Don't use TypeScript const enum.
Don't declare empty interfaces.
Don't let variables evolve into any type through reassignments.
Don't use the any type.
Don't misuse the non-null assertion operator (!) in TypeScript files.
Don't use implicit any type on variable declarations.
Don't merge interfaces and classes unsafely.
Don't use overload signatures that aren't next to each other.
Use the namespace keyword instead of the module keyword to declare TypeScript namespaces.
Use consistent accessibility modifiers on class properties and methods.
Use function types instead of object types with call signatures.
Don't use void type outside of generic or return types.
Files:
packages/rpc/src/root.tsapps/api/src/query/types.tspackages/rpc/src/routers/autocomplete.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/api/src/query/builders/traffic.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/api/src/query/builders/sessions.tsapps/api/src/query/builders/errors.tspackages/rpc/src/lib/logger.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/api/src/query/simple-builder.tsapps/dashboard/hooks/use-funnels.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/api/src/query/builders/pages.tsapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/api/src/query/builders/profiles.tspackages/rpc/src/routers/goals.tspackages/rpc/src/routers/funnels.tsapps/api/src/query/builders/summary.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsxapps/api/src/query/screen-resolution-to-device-type.tspackages/rpc/src/lib/analytics-utils.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/01-MUST-DO.mdc)
**/*.{js,jsx,ts,tsx}: use console properly, like console.error, console.time, console.json, console.table, etc
Use Dayjs NEVER date-fns, and Tanstack query for hooks, NEVER SWR
Use ONLY Zod V4 from zod/v4 never zod 3 from zod
use json.stringify() when adding debugging
**/*.{js,jsx,ts,tsx}: Don't use consecutive spaces in regular expression literals.
Don't use theargumentsobject.
Don't use the comma operator.
Don't write functions that exceed a given Cognitive Complexity score.
Don't use unnecessary boolean casts.
Don't use unnecessary callbacks with flatMap.
Use for...of statements instead of Array.forEach.
Don't create classes that only have static members (like a static namespace).
Don't use this and super in static contexts.
Don't use unnecessary catch clauses.
Don't use unnecessary constructors.
Don't use unnecessary continue statements.
Don't export empty modules that don't change anything.
Don't use unnecessary escape sequences in regular expression literals.
Don't use unnecessary labels.
Don't use unnecessary nested block statements.
Don't rename imports, exports, and destructured assignments to the same name.
Don't use unnecessary string or template literal concatenation.
Don't use String.raw in template literals when there are no escape sequences.
Don't use useless case statements in switch statements.
Don't use ternary operators when simpler alternatives exist.
Don't use uselessthisaliasing.
Don't initialize variables to undefined.
Don't use the void operators (they're not familiar).
Use arrow functions instead of function expressions.
Use Date.now() to get milliseconds since the Unix Epoch.
Use .flatMap() instead of map().flat() when possible.
Use literal property access instead of computed property access.
Don't use parseInt() or Number.parseInt() when binary, octal, or hexadecimal literals work.
Use concise optional chaining instead of chained logical expressions.
Use regular expression literals instead of the RegExp constructor when possib...
Files:
packages/rpc/src/root.tsapps/api/src/query/types.tspackages/rpc/src/routers/autocomplete.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/api/src/query/builders/traffic.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/api/src/query/builders/sessions.tsapps/api/src/query/builders/errors.tspackages/rpc/src/lib/logger.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/api/src/query/simple-builder.tsapps/dashboard/hooks/use-funnels.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/api/src/query/builders/pages.tsapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/api/src/query/builders/profiles.tspackages/rpc/src/routers/goals.tspackages/rpc/src/routers/funnels.tsapps/api/src/query/builders/summary.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsxapps/api/src/query/screen-resolution-to-device-type.tspackages/rpc/src/lib/analytics-utils.ts
**/*.{html,ts,css}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuild
Files:
packages/rpc/src/root.tsapps/api/src/query/types.tspackages/rpc/src/routers/autocomplete.tsapps/api/src/query/builders/traffic.tsapps/api/src/query/builders/sessions.tsapps/api/src/query/builders/errors.tspackages/rpc/src/lib/logger.tsapps/api/src/query/simple-builder.tsapps/dashboard/hooks/use-funnels.tsapps/api/src/query/builders/pages.tsapps/api/src/query/builders/profiles.tspackages/rpc/src/routers/goals.tspackages/rpc/src/routers/funnels.tsapps/api/src/query/builders/summary.tsapps/api/src/query/screen-resolution-to-device-type.tspackages/rpc/src/lib/analytics-utils.ts
package.json
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
package.json: Usebun installinstead ofnpm install,yarn install, orpnpm install
Usebun run <script>instead ofnpm run <script>,yarn run <script>, orpnpm run <script>
Files:
package.json
**/*.{jsx,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/01-MUST-DO.mdc)
**/*.{jsx,tsx}: Always use rounded, not rounded-xl or rounded-md, always rounded
Don't use lucide for icons, ONLY use phosphor icons, use width="duotone" for most, but for arrows use fill, for plus icons don't add width
ALWAYS use error boundaries properly
use Icon at the end of phosphor react icons, like CaretIcon not Caret
Almost NEVER use useEffect unless it's critical
**/*.{jsx,tsx}: Don't useaccessKeyattribute on any HTML element.
Don't setaria-hidden="true"on focusable elements.
Don't add ARIA roles, states, and properties to elements that don't support them.
Don't use distracting elements like<marquee>or<blink>.
Only use thescopeprop on<th>elements.
Don't assign non-interactive ARIA roles to interactive HTML elements.
Make sure label elements have text content and are associated with an input.
Don't assign interactive ARIA roles to non-interactive HTML elements.
Don't assigntabIndexto non-interactive HTML elements.
Don't use positive integers fortabIndexproperty.
Don't include "image", "picture", or "photo" in img alt prop.
Don't use explicit role property that's the same as the implicit/default role.
Make static elements with click handlers use a valid role attribute.
Always include atitleelement for SVG elements.
Give all elements requiring alt text meaningful information for screen readers.
Make sure anchors have content that's accessible to screen readers.
AssigntabIndexto non-interactive HTML elements witharia-activedescendant.
Include all required ARIA attributes for elements with ARIA roles.
Make sure ARIA properties are valid for the element's supported roles.
Always include atypeattribute for button elements.
Make elements with interactive roles and handlers focusable.
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden).
Always include alangattribute on the html element.
Always include atitleattribute for iframe elements.
AccompanyonClickwith ...
Files:
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx
apps/dashboard/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (apps/dashboard/.cursor/rules/ultracite.mdc)
apps/dashboard/**/*.{js,jsx,ts,tsx}: Don't useaccessKeyattribute on any HTML element.
Don't setaria-hidden="true"on focusable elements.
Don't add ARIA roles, states, and properties to elements that don't support them.
Don't use distracting elements like<marquee>or<blink>.
Only use thescopeprop on<th>elements.
Don't assign non-interactive ARIA roles to interactive HTML elements.
Make sure label elements have text content and are associated with an input.
Don't assign interactive ARIA roles to non-interactive HTML elements.
Don't assigntabIndexto non-interactive HTML elements.
Don't use positive integers fortabIndexproperty.
Don't include "image", "picture", or "photo" in imgaltprop.
Don't use explicit role property that's the same as the implicit/default role.
Make static elements with click handlers use a valid role attribute.
Always include atitleelement for SVG elements.
Give all elements requiring alt text meaningful information for screen readers.
Make sure anchors have content that's accessible to screen readers.
AssigntabIndexto non-interactive HTML elements witharia-activedescendant.
Include all required ARIA attributes for elements with ARIA roles.
Make sure ARIA properties are valid for the element's supported roles.
Always include atypeattribute for button elements.
Make elements with interactive roles and handlers focusable.
Give heading elements content that's accessible to screen readers (not hidden witharia-hidden).
Always include alangattribute on the html element.
Always include atitleattribute for iframe elements.
AccompanyonClickwith at least one of:onKeyUp,onKeyDown, oronKeyPress.
AccompanyonMouseOver/onMouseOutwithonFocus/onBlur.
Include caption tracks for audio and video elements.
Use semantic elements instead of role attributes in JSX.
Make sure all anchors are valid and navigable.
Ensure all ARIA properties (aria-*) are valid.
Use valid, non-abstract ARIA ...
Files:
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/dashboard/hooks/use-funnels.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx
apps/dashboard/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (apps/dashboard/.cursor/rules/ultracite.mdc)
apps/dashboard/**/*.{ts,tsx}: Don't use primitive type aliases or misleading types.
Don't use empty type parameters in type aliases and interfaces.
Don't use any or unknown as type constraints.
Don't return a value from a function that has a 'void' return type.
Don't use the TypeScript directive @ts-ignore.
Don't use TypeScript enums.
Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Don't use TypeScript namespaces.
Don't use non-null assertions with the!postfix operator.
Don't use parameter properties in class constructors.
Don't use user-defined types.
Useas constinstead of literal types and type annotations.
Use eitherT[]orArray<T>consistently.
Use consistent accessibility modifiers on class properties and methods.
Initialize each enum member value explicitly.
Useexport typefor types.
Useimport typefor types.
Make sure all enum members are literal values.
Use function types instead of object types with call signatures.
Don't use void type outside of generic or return types.
Don't use TypeScript const enum.
Don't declare empty interfaces.
Don't let variables evolve into any type through reassignments.
Don't use the any type.
Don't misuse the non-null assertion operator (!) in TypeScript files.
Don't use implicit any type on variable declarations.
Don't merge interfaces and classes unsafely.
Don't use overload signatures that aren't next to each other.
Use the namespace keyword instead of the module keyword to declare TypeScript namespaces.
Files:
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/dashboard/hooks/use-funnels.tsapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx
apps/dashboard/**/*.{jsx,tsx}
📄 CodeRabbit Inference Engine (apps/dashboard/.cursor/rules/ultracite.mdc)
apps/dashboard/**/*.{jsx,tsx}: Don't use unnecessary fragments.
Don't pass children as props.
Don't forget key props in iterators and collection literals.
Don't destructure props inside JSX components in Solid projects.
Don't use configured elements.
Don't use<img>elements in Next.js projects.
Don't use dangerous JSX props.
Don't use bothchildrenanddangerouslySetInnerHTMLprops on the same element.
Don't use<head>elements in Next.js projects.
Use<>...</>instead of<Fragment>...</Fragment>.
Don't add extra closing tags for components without children.
Don't use Array index in keys.
Don't insert comments as text nodes.
Don't import next/document outside of pages/_document.jsx in Next.js projects.
Don't assign JSX properties multiple times.
Watch out for possible "wrong" semicolons inside JSX elements.
Files:
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsxapps/dashboard/app/(main)/websites/[id]/funnels/page.tsxapps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx
🧠 Learnings (20)
apps/database/package.json (12)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use dotenv; Bun automatically loads .env
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use the node: protocol for Node.js builtin modules.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to package.json : Use bun run <script> instead of npm run <script>, yarn run <script>, or pnpm run <script>
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use node:assert/strict over node:assert.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use the next/head module in pages/_document.js on Next.js projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't export empty modules that don't change anything.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't import next/document outside of pages/_document.jsx in Next.js projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't rename imports, exports, and destructured assignments to the same name.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use bun <file> instead of node <file> or ts-node <file>
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to package.json : Use bun install instead of npm install, yarn install, or pnpm install
packages/rpc/src/root.ts (4)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use import type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Prevent import cycles.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Declare regex literals at the top level.
apps/api/src/query/types.ts (18)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use ONLY Zod V4 from zod/v4 never zod 3 from zod
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use any or unknown as type constraints.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use import type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use import type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Don't use the any type.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use any or unknown as type constraints.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Don't use user-defined types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use === and !==.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use === and !==.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use bitwise operators.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use the void operators (they're not familiar).
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't compare against -0.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use ternary operators when simpler alternatives exist.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use assignment operator shorthand where possible.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Remove redundant terms from logical expressions.
package.json (17)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to package.json : Use bun run <script> instead of npm run <script>, yarn run <script>, or pnpm run <script>
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't export empty modules that don't change anything.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure to use the "use strict" directive in script files.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use the node: protocol for Node.js builtin modules.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure builtins are correctly instantiated.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't rename imports, exports, and destructured assignments to the same name.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't hardcode sensitive data like API keys and tokens.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use node:assert/strict over node:assert.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use __dirname and __filename in the global scope.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use dotenv; Bun automatically loads .env
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use better-sqlite3; use bun:sqlite instead
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use bun <file> instead of node <file> or ts-node <file>
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Read the Bun API docs in node_modules/bun-types/docs/**.md for more information
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use Bun.$ instead of execa
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use specified modules when loaded by import or require.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use the namespace keyword instead of the module keyword to declare TypeScript namespaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-27T11:37:54.955Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use ioredis; use Bun.redis instead
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsx (12)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use valid values for the autocomplete attribute on input elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use semantic elements instead of role attributes in JSX.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't assign interactive ARIA roles to non-interactive HTML elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't assign non-interactive ARIA roles to interactive HTML elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make elements with interactive roles and handlers focusable.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use event handlers on non-interactive elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Always include a type attribute for button elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Use valid values for the autocomplete attribute on input elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Assign tabIndex to non-interactive HTML elements with aria-activedescendant.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use accessKey attribute on any HTML element.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Accompany onMouseOver/onMouseOut with onFocus/onBlur.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress.
apps/api/src/query/builders/traffic.ts (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use implicit any type on variable declarations.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsx (21)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use duplicate function parameter names.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use arrow functions instead of function expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Remove redundant terms from logical expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't reassign function parameters.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't have unused function parameters.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make static elements with click handlers use a valid role attribute.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary labels.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : use Icon at the end of phosphor react icons, like CaretIcon not Caret
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : Don't use lucide for icons, ONLY use phosphor icons, use width="duotone" for most, but for arrows use fill, for plus icons don't add width
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Make static elements with click handlers use a valid role attribute.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use event handlers on non-interactive elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't use event handlers on non-interactive elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Accompany onClick with at least one of: onKeyUp, onKeyDown, or onKeyPress.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make elements with interactive roles and handlers focusable.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Make elements with interactive roles and handlers focusable.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't pass children as props.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't destructure props inside JSX components in Solid projects.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsx (15)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't export empty modules that don't change anything.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use Array index in keys.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't destructure props inside JSX components in Solid projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't forget key props in iterators and collection literals.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use empty destructuring patterns.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use Array constructors.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't pass children as props.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't rename imports, exports, and destructured assignments to the same name.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use .flatMap() instead of map().flat() when possible.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure all React hooks are called from the top level of component functions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use import type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary constructors.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use useless undefined.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't use Array index in keys.
apps/api/src/query/builders/sessions.ts (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use implicit any type on variable declarations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use any or unknown as type constraints.
apps/api/src/query/builders/errors.ts (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use implicit any type on variable declarations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use any or unknown as type constraints.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsx (19)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Remove redundant terms from logical expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary labels.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't have unused imports.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't have unused function parameters.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use arrow functions instead of function expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't have unused labels.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary callbacks with flatMap.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use duplicate function parameter names.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't declare empty interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : use Icon at the end of phosphor react icons, like CaretIcon not Caret
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use Number properties instead of global ones.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : Don't use lucide for icons, ONLY use phosphor icons, use width="duotone" for most, but for arrows use fill, for plus icons don't add width
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use literal numbers that lose precision.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use semantic elements instead of role attributes in JSX.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use dangerous JSX props.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure to use the digits argument with Number#toFixed().
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't destructure props inside JSX components in Solid projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Simplify data flow to eliminate prop drilling and callback hell.
apps/api/src/query/simple-builder.ts (2)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Don't use parameter properties in class constructors.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use parameter properties in class constructors.
apps/dashboard/hooks/use-funnels.ts (1)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx (19)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Remove redundant terms from logical expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use Array index in keys.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't forget key props in iterators and collection literals.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't use Array index in keys.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use for-of loops when you need the index to extract an item from the iterated array.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use Array constructors.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't forget key props in iterators and collection literals.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use sparse arrays (arrays with holes).
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use for...of statements instead of Array.forEach.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use at() instead of integer index access.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Use <>...</> instead of <Fragment>...</Fragment>.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use .flatMap() instead of map().flat() when possible.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Use while loops instead of for loops when you don't need initializer and update expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't use Array constructors.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure to use the digits argument with Number#toFixed().
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Simplify data flow to eliminate prop drilling and callback hell.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Handle complex data transformations independently of React. Keep these modules decoupled from React for improved modularity and testability.
apps/api/src/query/builders/pages.ts (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't add type annotations to variables, parameters, and class properties that are initialized with literal expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use implicit any type on variable declarations.
apps/dashboard/app/(main)/websites/[id]/funnels/page.tsx (28)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Remove redundant terms from logical expressions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use useless undefined.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't export empty modules that don't change anything.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't use unnecessary fragments.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't have unused function parameters.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't declare empty interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary labels.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use empty destructuring patterns.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't use unnecessary callbacks with flatMap.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : use Icon at the end of phosphor react icons, like CaretIcon not Caret
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure all React hooks are called from the top level of component functions.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{jsx,tsx} : Don't use lucide for icons, ONLY use phosphor icons, use width="duotone" for most, but for arrows use fill, for plus icons don't add width
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use <img> elements in Next.js projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make sure all dependencies are correctly specified in React hooks.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Decouple state management, data transformations, and API interactions from the React lifecycle.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use dangerous JSX props.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't destructure props inside JSX components in Solid projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Use <>...</> instead of <Fragment>...</Fragment>.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/01-MUST-DO.mdc:0-0
Timestamp: 2025-07-27T11:36:04.592Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use Dayjs NEVER date-fns, and Tanstack query for hooks, NEVER SWR
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't forget key props in iterators and collection literals.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{jsx,tsx} : Don't use <head> elements in Next.js projects.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Make elements with interactive roles and handlers focusable.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Assign tabIndex to non-interactive HTML elements with aria-activedescendant.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Assign tabIndex to non-interactive HTML elements with aria-activedescendant.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Make elements with interactive roles and handlers focusable.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{js,jsx,ts,tsx} : Don't assign tabIndex to non-interactive HTML elements.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{jsx,tsx} : Don't assign tabIndex to non-interactive HTML elements.
apps/api/src/query/builders/profiles.ts (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
apps/api/src/query/builders/summary.ts (1)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.942Z
Learning: Applies to **/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx (10)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use primitive type aliases or misleading types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use as const instead of literal types and type annotations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use the any type.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.599Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use empty type parameters in type aliases and interfaces.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use either T[] or Array<T> consistently.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use user-defined types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Don't use implicit any type on variable declarations.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use import type for types.
apps/api/src/query/screen-resolution-to-device-type.ts (4)
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: apps/dashboard/.cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:39:48.600Z
Learning: Applies to apps/dashboard/**/*.{ts,tsx} : Use function types instead of object types with call signatures.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use export type for types.
Learnt from: CR
PR: databuddy-analytics/Databuddy#0
File: .cursor/rules/ultracite.mdc:0-0
Timestamp: 2025-07-27T11:37:42.943Z
Learning: Applies to **/*.{ts,tsx} : Use function types instead of object types with call signatures.
🧬 Code Graph Analysis (6)
packages/rpc/src/root.ts (1)
packages/rpc/src/routers/autocomplete.ts (1)
autocompleteRouter(136-169)
apps/api/src/query/builders/traffic.ts (2)
apps/api/src/query/types.ts (1)
SimpleQueryConfig(28-54)packages/db/src/clickhouse/schema.ts (1)
AnalyticsEvent(445-546)
apps/api/src/query/builders/errors.ts (1)
apps/api/src/query/types.ts (1)
SimpleQueryConfig(28-54)
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsx (1)
apps/dashboard/app/(main)/websites/[id]/funnels/_components/index.ts (1)
FunnelFlow(6-6)
apps/api/src/query/simple-builder.ts (1)
apps/api/src/query/types.ts (2)
SimpleQueryConfig(28-54)QueryRequest(56-68)
packages/rpc/src/routers/goals.ts (3)
packages/rpc/src/lib/analytics-utils.ts (3)
AnalyticsStep(4-9)getTotalWebsiteUsers(62-83)processGoalAnalytics(207-276)packages/rpc/src/lib/logger.ts (1)
logger(5-9)apps/dashboard/hooks/use-goals.ts (2)
useBulkGoalAnalytics(107-122)useGoalAnalytics(90-105)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (50)
apps/api/src/query/screen-resolution-to-device-type.ts (3)
10-14: Well-structured interface definition.The
Resolutioninterface is clean and appropriately typed for internal use. The inclusion of theaspectproperty alongsidewidthandheightimproves code clarity in the device classification logic.
48-71: Well-structured device classification logic.The function uses appropriate width and aspect ratio thresholds for device type classification. The hierarchical condition structure is logical and the fallback to 'unknown' ensures robust handling of edge cases.
82-83: Excellent refactoring that improves code clarity.The main function is now much cleaner and easier to understand. The separation of parsing and classification logic into helper functions improves maintainability while preserving the same external interface.
apps/api/src/query/types.ts (1)
41-41: Improved type safety by replacinganywithunknown.This change aligns with TypeScript best practices and the coding guidelines. Using
unknowninstead ofanyprovides better type safety by requiring explicit type checking before use.apps/api/src/query/builders/traffic.ts (1)
4-4: Good type simplification as part of coordinated refactoring.Removing the generic parameter makes the type annotation more accurate since the
SimpleQueryConfiginterface doesn't actually use generic constraints. This change is consistent with similar updates across other query builder files.apps/api/src/query/builders/errors.ts (1)
4-4: Consistent type simplification aligns with broader refactoring.This change mirrors the updates in other query builder files, removing unnecessary generic parameters from
SimpleQueryConfig. The typing remains functionally equivalent while being more accurate to the actual interface definition.apps/api/src/query/builders/pages.ts (3)
4-4: Consistent type annotation simplification.This change aligns with the coordinated refactoring across all query builder files, removing unnecessary generic parameters while maintaining functional equivalence.
41-42: Good parameter naming and type safety improvements.The underscore prefix correctly indicates these parameters are unused, and changing from
anytounknownimproves type safety. This follows TypeScript best practices and the project's coding guidelines.
101-102: Consistent parameter improvements match entry_pages function.The naming convention and type safety improvements are consistently applied, maintaining code uniformity across the customSql functions.
apps/api/src/query/simple-builder.ts (2)
12-24: LGTM: Constructor refactor follows coding guidelines.The refactor from parameter properties to explicit field declarations aligns with the coding guidelines and retrieved learnings. This improves code clarity by making the class structure more explicit.
149-151: Good formatting improvement.The expansion of the single-line conditional to a block with braces improves code consistency and readability.
apps/api/src/query/builders/profiles.ts (2)
4-4: LGTM: Type annotation simplification improves consistency.Removing the generic parameter
<typeof Analytics.events>fromSimpleQueryConfigmakes the type more general and consistent across the codebase.
10-11: Excellent type safety improvement with parameter renaming.The changes from
any[]/anytounknown[]/unknownand prefixing parameter names with underscores (_filters,_granularity) improve type safety and clearly indicate these parameters are intentionally unused in the function implementations.Also applies to: 226-227
apps/api/src/query/builders/sessions.ts (2)
4-4: LGTM: Consistent type annotation simplification.The removal of the generic parameter maintains consistency with other builder files and simplifies the type declaration.
117-118: Good type safety enhancement.Changing parameter types from
any[]/anytounknown[]/unknownand using underscore prefixes for unused parameters follows best practices for type safety and parameter naming.apps/api/src/query/builders/summary.ts (2)
4-4: LGTM: Type annotation follows established pattern.The type simplification is consistent with changes in other builder files, improving overall codebase consistency.
117-118: Good type safety improvement with preserved functionality.The parameter type changes from specific types (
Filter[],TimeUnit) tounknown[]/unknownwith underscore prefixes improve type consistency across builder files. The granularity logic on line 124 continues to work correctly, demonstrating that the calling code maintains proper type handling.Also applies to: 124-124
packages/rpc/src/root.ts (1)
1-1: LGTM! Clean integration of autocomplete routerThe new autocomplete router is properly imported and integrated into the appRouter following the established pattern. The change is consistent with the existing code structure.
Also applies to: 15-15
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-card.tsx (2)
33-69: LGTM! Good refactoring for improved readabilityThe extraction of
getStepIconandgetStepTooltipTexthelper functions improves code organization by removing inline conditional logic. The functions handle different step types appropriately and follow the established icon usage patterns.
81-83: Clean formatting improvementThe reformatted early return condition is more readable while maintaining the same logic.
apps/dashboard/hooks/use-funnels.ts (1)
346-346: LGTM! Endpoint migration looks correct.The update from
trpc.funnels.getAutocompletetotrpc.autocomplete.getcorrectly reflects the backend refactoring that moves autocomplete functionality to a dedicated router.apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-components.tsx (1)
99-112: Excellent accessibility improvements!The changes properly implement:
- Semantic HTML by using
buttonelements for interactive items- Keyboard navigation with Enter/Space key handling
- Better key prop using suggestion string instead of array index
- Correct
type="button"to prevent form submissionThese changes align with the coding guidelines for accessibility and best practices.
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnels-list.tsx (2)
3-3: Good cleanup - removed unused import.Removing
CardContentfrom imports follows best practices for keeping imports clean.
33-34: Clean array initialization improvement.Using
new Array(3).fill(null)is cleaner than the spread operator approach, and renamingitoindeximproves readability. For static loading skeletons, using index as key is acceptable.apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-flow.tsx (2)
3-3: Good cleanup - removed unused icon imports.Keeping only the required
TargetIconimport follows best practices.
20-20: Clean refactoring improvements.
- Removed unused
formatCompletionTimeprop from interface and component- Used
.at()method for array access as per coding guidelinesThese changes simplify the component interface and follow modern JavaScript practices.
Also applies to: 30-31
packages/rpc/src/routers/autocomplete.ts (3)
1-6: Imports look good!Correctly using
zod/v4as specified in coding guidelines and proper module imports.
33-36: Verify URL path extraction logic.The path extraction logic assumes URLs start with 'http' and uses position 9 to find the path. This might not work correctly for all URL formats (e.g., 'https://' vs 'http://', URLs with ports).
Consider using URL parsing for more robust path extraction:
-CASE - WHEN path LIKE 'http%' THEN - substring(path, position(path, '/', 9)) - ELSE path -END as value +CASE + WHEN path LIKE 'http%' THEN + extractURLParameter(path, 'path') + ELSE path +END as valueOr handle this in the application layer using the URL constructor.
136-169: Implementation looks solid overall!The router implementation follows best practices:
- Proper authorization checks
- Parameterized queries preventing SQL injection
- Appropriate error handling and logging
- Clean separation of concerns
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics-by-referrer.tsx (3)
26-29: Good type safety improvement!The explicit typing of the
dataprop removes the use ofanyand provides proper type information, aligning with TypeScript best practices.
53-58: Excellent removal ofanytype!The explicit typing of the grouped Map values with
FunnelAnalyticsByReferrerResult['referrer_parsed']improves type safety and code maintainability.
163-163: Good practice: Let TypeScript infer the typeRemoving the explicit
anytype annotation on theoptionparameter allows TypeScript to properly infer the type from the array, which is the recommended approach.packages/rpc/src/routers/goals.ts (3)
5-10: Great refactoring: Analytics logic extractionExcellent work extracting analytics processing logic into reusable utility functions. This improves code maintainability and follows the DRY principle.
191-198: Good type safety with explicit typingThe explicit
AnalyticsStep[]typing and structured step object improve type safety and code clarity.
271-291: Excellent error handling implementationThe try-catch block with proper logging provides robust error handling. The error response structure ensures clients receive meaningful error information while logging details server-side.
apps/dashboard/app/(main)/websites/[id]/funnels/page.tsx (2)
6-6: Good practice: Removing unnecessary useEffectExcellent removal of
useEffectfrom imports, following the guideline to avoid useEffect unless critical.
323-323: Good accessibility improvementAdding
role="tablist"improves screen reader accessibility for the analytics container.packages/rpc/src/routers/funnels.ts (3)
5-10: Excellent refactoring: Centralized analytics processingGreat work extracting funnel analytics logic into reusable utilities. This significantly reduces code duplication and improves maintainability.
93-96: Consistent structured logging implementationExcellent adoption of the centralized logger with structured logging. The error context includes all relevant information for debugging.
Also applies to: 139-143, 176-181, 185-189
353-360: Clean analytics steps transformationThe mapping to
AnalyticsStep[]with explicit typing and proper structure improves type safety and code clarity.apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx (4)
11-11: Good optimization: Using useMemo for derived stateExcellent choice using
useMemoinstead ofuseStatefor derived data, avoiding unnecessary re-computations.
16-26: Well-structured interface definitionThe
ReferrerAnalyticsinterface is properly typed without usinganytypes, following TypeScript best practices.
45-96: Complex but well-implemented data derivationThe memoized computation properly handles the conditional display logic for referrer-specific data. Good use of nullish checks and proper typing throughout.
219-219: Correct usage of toFixedGood practice using
toFixed(1)with the proper digits argument as required by the coding guidelines.Also applies to: 237-237
packages/rpc/src/lib/analytics-utils.ts (6)
1-61: LGTM! Well-structured interfaces for analytics data models.The interfaces are properly typed and provide a clear structure for analytics data flow throughout the module.
62-83: LGTM! Clean implementation for fetching total website users.Good use of parameterized queries and null-safe return value.
85-126: LGTM! Secure query building with proper parameterization.The query builders handle both PAGE_VIEW and EVENT types appropriately, with good support for partial URL matching.
128-205: LGTM! Efficient session event processing with correct sequential logic.The implementation properly tracks users through sequential funnel steps using efficient data structures.
486-603: LGTM! Comprehensive funnel analytics processing with proper error handling.The implementation correctly calculates conversion rates, dropoff rates, and identifies the biggest dropoff step. Good use of error handling in the referrer parsing logic.
605-841: LGTM! Well-implemented referrer analytics with proper domain grouping.The implementation effectively groups and analyzes funnel performance by traffic source, with appropriate handling of direct traffic and domain-based aggregation.
| {displayData.avg_completion_time} | ||
| </div> |
There was a problem hiding this comment.
Use formatted time value for display
The code displays the numeric avg_completion_time value directly. Consider using avg_completion_time_formatted for proper time display.
-{displayData.avg_completion_time}
+{displayData.avg_completion_time_formatted}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {displayData.avg_completion_time} | |
| </div> | |
| {displayData.avg_completion_time_formatted} | |
| </div> |
🤖 Prompt for AI Agents
In
apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx
around lines 228 to 229, replace the direct display of the numeric
avg_completion_time with the formatted time value avg_completion_time_formatted
to ensure the time is shown properly to users.
| "private": true, | ||
| "scripts": { | ||
| "dev": "next dev -p 3004", | ||
| "dev": "dotenv -- next dev -p 3004", |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Remove unnecessary dotenv prefix - Bun automatically loads .env files
According to the coding guidelines, Bun automatically loads .env files, making the dotenv -- prefix unnecessary. This script should simply be "next dev -p 3004".
- "dev": "dotenv -- next dev -p 3004",
+ "dev": "next dev -p 3004",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "dev": "dotenv -- next dev -p 3004", | |
| "dev": "next dev -p 3004", |
🤖 Prompt for AI Agents
In apps/database/package.json at line 6, remove the unnecessary "dotenv --"
prefix from the "dev" script since Bun automatically loads .env files. Change
the script value from "dotenv -- next dev -p 3004" to just "next dev -p 3004".
| "db:deploy": "dotenv -- turbo run db:deploy", | ||
| "email:dev": "cd packages/email && bun run dev", | ||
| "sdk:build": "cd packages/sdk && bun run build", | ||
| "dashboard:dev": "dotenv -- cd apps/dashboard; bun run dev" |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Remove unnecessary dotenv prefix - Bun automatically loads .env files
The new dashboard:dev script uses dotenv -- which is unnecessary since Bun automatically loads .env files. This script should be simplified.
- "dashboard:dev": "dotenv -- cd apps/dashboard; bun run dev"
+ "dashboard:dev": "cd apps/dashboard; bun run dev"Note: This pattern appears in multiple scripts throughout the file, suggesting a broader refactoring opportunity to remove dotenv usage project-wide.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "dashboard:dev": "dotenv -- cd apps/dashboard; bun run dev" | |
| "dashboard:dev": "cd apps/dashboard; bun run dev" |
🤖 Prompt for AI Agents
In package.json at line 20, remove the unnecessary "dotenv --" prefix from the
"dashboard:dev" script since Bun automatically loads .env files. Simplify the
script to just run "cd apps/dashboard; bun run dev". Also, review other scripts
in the file using "dotenv --" and remove that prefix project-wide for
consistency.
| const token = process.env.LOGTAIL_SOURCE_TOKEN as string; | ||
| const endpoint = process.env.LOGTAIL_ENDPOINT as string; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add proper environment variable validation
Using type assertions without validation can cause runtime errors if the environment variables are undefined. Consider adding proper validation or fallback values.
-const token = process.env.LOGTAIL_SOURCE_TOKEN as string;
-const endpoint = process.env.LOGTAIL_ENDPOINT as string;
+const token = process.env.LOGTAIL_SOURCE_TOKEN;
+const endpoint = process.env.LOGTAIL_ENDPOINT;
+
+if (!token || !endpoint) {
+ throw new Error('LOGTAIL_SOURCE_TOKEN and LOGTAIL_ENDPOINT must be defined');
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const token = process.env.LOGTAIL_SOURCE_TOKEN as string; | |
| const endpoint = process.env.LOGTAIL_ENDPOINT as string; | |
| // packages/rpc/src/lib/logger.ts | |
| import { Logtail } from '@logtail/node'; | |
| const token = process.env.LOGTAIL_SOURCE_TOKEN; | |
| const endpoint = process.env.LOGTAIL_ENDPOINT; | |
| if (!token || !endpoint) { | |
| throw new Error('LOGTAIL_SOURCE_TOKEN and LOGTAIL_ENDPOINT must be defined'); | |
| } | |
| const logger = new Logtail(token, { | |
| endpoint, | |
| batchSize: 10, | |
| batchInterval: 3000, | |
| }); | |
| export { logger }; |
🤖 Prompt for AI Agents
In packages/rpc/src/lib/logger.ts around lines 3 to 4, the environment variables
LOGTAIL_SOURCE_TOKEN and LOGTAIL_ENDPOINT are accessed using type assertions
without validation, which can lead to runtime errors if they are undefined. Add
checks to verify these environment variables are defined before using them, and
provide fallback values or throw descriptive errors if they are missing to
ensure safe usage.
| }; | ||
|
|
||
| const escapeSqlWildcards = (value: string): string => { | ||
| return value.replace(/[%_]/g, '\\$&'); |
Check failure
Code scanning / CodeQL
Incomplete string escaping or encoding High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 12 months ago
To fix the problem, the escapeSqlWildcards function should be updated to also escape backslashes in the input string. The correct order is to first escape all backslashes (replace each \ with \\), then escape % and _ (replace each with \% and \_, respectively). This ensures that any existing backslashes do not interfere with the escaping of wildcards and that the resulting string is safe for use in SQL LIKE clauses. The change should be made in the function definition at line 376-378 in packages/rpc/src/lib/analytics-utils.ts. No new imports are needed, as this can be accomplished with regular expressions.
| @@ -376,3 +376,4 @@ | ||
| const escapeSqlWildcards = (value: string): string => { | ||
| return value.replace(/[%_]/g, '\\$&'); | ||
| // First escape backslashes, then escape % and _ | ||
| return value.replace(/\\/g, '\\\\').replace(/[%_]/g, '\\$&'); | ||
| }; |
Pull Request
Description
Please include a summary of the change and which issue is fixed. Also include relevant motivation and context.
Checklist
Summary by CodeRabbit
New Features
Enhancements
Refactor
Chores
Removals