Skip to content

Commit f76a694

Browse files
committed
cleanup, prepare a/b
1 parent 1fdb91f commit f76a694

File tree

7 files changed

+114
-53
lines changed

7 files changed

+114
-53
lines changed

apps/api/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const app = new Elysia()
2222
.use(query)
2323
.use(assistant)
2424
.use(health)
25-
.all('/trpc/*', async ({ request }) => {
25+
.all('/trpc/*', ({ request }) => {
2626
return fetchRequestHandler({
2727
endpoint: '/trpc',
2828
router: appRouter,

apps/dashboard/app/(main)/websites/[id]/_components/tabs/audience-tab.tsx

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ interface ScreenResolutionEntry {
8282
}
8383

8484
interface DeviceData {
85-
device_type: any[];
86-
browser_name: any[];
87-
os_name: any[];
85+
device_type: string[];
86+
browser_name: string[];
87+
os_name: string[];
8888
screen_resolution: ScreenResolutionEntry[];
89-
connection_type: any[];
89+
connection_type: string[];
9090
}
9191

9292
interface ProcessedData {
@@ -111,29 +111,38 @@ const formatNumber = (value: number | null | undefined): string => {
111111

112112
const getConnectionIcon = (connection: string): React.ReactNode => {
113113
const connectionLower = connection.toLowerCase();
114-
if (!connection || connection === 'Unknown')
114+
if (!connection || connection === 'Unknown') {
115115
return <HelpCircle className="h-4 w-4 text-muted-foreground" />;
116-
if (connectionLower.includes('wifi'))
116+
}
117+
if (connectionLower.includes('wifi')) {
117118
return <Wifi className="h-4 w-4 text-green-500" />;
118-
if (connectionLower.includes('4g'))
119+
}
120+
if (connectionLower.includes('4g')) {
119121
return <Smartphone className="h-4 w-4 text-blue-500" />;
120-
if (connectionLower.includes('5g'))
122+
}
123+
if (connectionLower.includes('5g')) {
121124
return <Smartphone className="h-4 w-4 text-purple-500" />;
122-
if (connectionLower.includes('3g'))
125+
}
126+
if (connectionLower.includes('3g')) {
123127
return <Smartphone className="h-4 w-4 text-yellow-500" />;
124-
if (connectionLower.includes('2g'))
128+
}
129+
if (connectionLower.includes('2g')) {
125130
return <Smartphone className="h-4 w-4 text-orange-500" />;
126-
if (connectionLower.includes('ethernet'))
131+
}
132+
if (connectionLower.includes('ethernet')) {
127133
return <Laptop className="h-4 w-4 text-blue-400" />;
128-
if (connectionLower.includes('cellular'))
134+
}
135+
if (connectionLower.includes('cellular')) {
129136
return <Smartphone className="h-4 w-4 text-blue-500" />;
130-
if (connectionLower.includes('offline'))
137+
}
138+
if (connectionLower.includes('offline')) {
131139
return <WifiOff className="h-4 w-4 text-red-500" />;
140+
}
132141
return <Globe className="h-4 w-4 text-primary" />;
133142
};
134143

135-
const normalizeData = (data: any[]): GeographicEntry[] =>
136-
data?.map((item: any) => ({
144+
const normalizeData = (data: string[]): GeographicEntry[] =>
145+
data?.map((item) => ({
137146
name: item.country_name || item.name || 'Unknown',
138147
visitors: item.visitors || 0,
139148
pageviews: item.pageviews || 0,
@@ -249,7 +258,9 @@ export function WebsiteAudienceTab({
249258

250259
const processedBrowserData = useMemo((): BrowserEntry[] => {
251260
const rawData = processedData.browsers;
252-
if (!rawData?.length) return [];
261+
if (!rawData?.length) {
262+
return [];
263+
}
253264

254265
if (rawData.length > 0 && rawData[0].versions) {
255266
return rawData
@@ -336,7 +347,7 @@ export function WebsiteAudienceTab({
336347
if (!connectionData?.length) return [];
337348

338349
const totalVisitors = connectionData.reduce(
339-
(sum: number, item: any) => sum + item.visitors,
350+
(sum: number, item: string) => sum + item.visitors,
340351
0
341352
);
342353

apps/dashboard/components/layout/navigation/navigation-config.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
CurrencyDollarIcon,
66
FunnelIcon,
77
GearIcon,
8-
GitBranchIcon,
98
GlobeIcon,
109
HouseIcon,
1110
// LinkIcon,

apps/dashboard/components/layout/navigation/navigation-item.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { ArrowSquareOut } from '@phosphor-icons/react';
22
import Link from 'next/link';
3-
import { useRouter } from 'next/navigation';
4-
import { useEffect } from 'react';
53
import { cn } from '@/lib/utils';
64
import type { NavigationItem as NavigationItemType } from './types';
75

@@ -10,7 +8,6 @@ interface NavigationItemProps extends Omit<NavigationItemType, 'icon'> {
108
isActive: boolean;
119
isRootLevel: boolean;
1210
isExternal?: boolean;
13-
isHighlighted?: boolean;
1411
currentWebsiteId?: string | null;
1512
}
1613

@@ -22,12 +19,9 @@ export function NavigationItem({
2219
isActive,
2320
isRootLevel,
2421
isExternal,
25-
isHighlighted,
2622
production,
2723
currentWebsiteId,
2824
}: NavigationItemProps) {
29-
const router = useRouter();
30-
3125
let fullPath: string;
3226
if (isRootLevel) {
3327
fullPath = href;
@@ -43,12 +37,6 @@ export function NavigationItem({
4337
return null;
4438
}
4539

46-
useEffect(() => {
47-
if (!isExternal) {
48-
router.prefetch(fullPath);
49-
}
50-
}, [fullPath, isExternal, router]);
51-
5240
const linkProps = isExternal
5341
? { href, target: '_blank', rel: 'noopener noreferrer' }
5442
: {

biome.jsonc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
{
22
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
3-
"extends": ["ultracite"]
3+
"extends": ["ultracite"],
4+
"javascript": {
5+
"formatter": {
6+
"indentStyle": "space",
7+
"indentWidth": 2
8+
}
9+
}
410
}

packages/db/src/drizzle/relations.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { relations } from 'drizzle-orm/relations';
22
import {
3+
abExperiments,
4+
abGoals,
5+
abVariants,
36
account,
47
apikey,
58
funnelDefinitions,
@@ -25,6 +28,7 @@ export const userRelations = relations(user, ({ many }) => ({
2528
websites: many(websites),
2629
funnelDefinitions: many(funnelDefinitions),
2730
apikeys: many(apikey),
31+
abExperiments: many(abExperiments),
2832
}));
2933

3034
export const organizationRelations = relations(organization, ({ many }) => ({
@@ -100,6 +104,7 @@ export const websitesRelations = relations(websites, ({ one, many }) => ({
100104
relationName: 'websites_organizationId_organization_id',
101105
}),
102106
funnelDefinitions: many(funnelDefinitions),
107+
abExperiments: many(abExperiments),
103108
}));
104109

105110
export const funnelGoalsRelations = relations(funnelGoals, ({ one }) => ({
@@ -137,3 +142,33 @@ export const apikeyRelations = relations(apikey, ({ one }) => ({
137142
references: [user.id],
138143
}),
139144
}));
145+
146+
export const abExperimentsRelations = relations(
147+
abExperiments,
148+
({ one, many }) => ({
149+
website: one(websites, {
150+
fields: [abExperiments.websiteId],
151+
references: [websites.id],
152+
}),
153+
user: one(user, {
154+
fields: [abExperiments.createdBy],
155+
references: [user.id],
156+
}),
157+
variants: many(abVariants),
158+
goals: many(abGoals),
159+
})
160+
);
161+
162+
export const abVariantsRelations = relations(abVariants, ({ one }) => ({
163+
experiment: one(abExperiments, {
164+
fields: [abVariants.experimentId],
165+
references: [abExperiments.id],
166+
}),
167+
}));
168+
169+
export const abGoalsRelations = relations(abGoals, ({ one }) => ({
170+
experiment: one(abExperiments, {
171+
fields: [abGoals.experimentId],
172+
references: [abExperiments.id],
173+
}),
174+
}));

packages/rpc/src/routers/funnels.ts

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,17 @@ const buildFilterConditions = (
137137
paramPrefix: string,
138138
params: Record<string, unknown>
139139
): string => {
140-
if (!filters || filters.length === 0) return '';
140+
if (!filters || filters.length === 0) {
141+
return '';
142+
}
141143
const filterConditions = filters
142144
.map((filter, i) => {
143-
if (!ALLOWED_FIELDS.has(filter.field)) return '';
144-
if (!ALLOWED_OPERATORS.has(filter.operator)) return '';
145+
if (!ALLOWED_FIELDS.has(filter.field)) {
146+
return '';
147+
}
148+
if (!ALLOWED_OPERATORS.has(filter.operator)) {
149+
return '';
150+
}
145151
const field = filter.field;
146152
const value = Array.isArray(filter.value) ? filter.value : [filter.value];
147153
const key = `${paramPrefix}_${i}`;
@@ -312,7 +318,7 @@ export const funnelsRouter = createTRPCRouter({
312318
};
313319

314320
return categorized;
315-
} catch (error: any) {
321+
} catch (error) {
316322
logger.error('Failed to fetch autocomplete data', error.message, {
317323
websiteId: website.id,
318324
});
@@ -355,7 +361,7 @@ export const funnelsRouter = createTRPCRouter({
355361
.orderBy(desc(funnelDefinitions.createdAt));
356362

357363
return funnels;
358-
} catch (error: any) {
364+
} catch (error) {
359365
logger.error('Failed to fetch funnels', error.message, {
360366
websiteId: website.id,
361367
});
@@ -396,8 +402,10 @@ export const funnelsRouter = createTRPCRouter({
396402
}
397403

398404
return funnel[0];
399-
} catch (error: any) {
400-
if (error instanceof TRPCError) throw error;
405+
} catch (error) {
406+
if (error instanceof TRPCError) {
407+
throw error;
408+
}
401409

402410
logger.error('Failed to fetch funnel', error.message, {
403411
funnelId: input.id,
@@ -442,7 +450,7 @@ export const funnelsRouter = createTRPCRouter({
442450
});
443451

444452
return newFunnel;
445-
} catch (error: any) {
453+
} catch (error) {
446454
logger.error('Failed to create funnel', error.message, {
447455
websiteId: website.id,
448456
userId: ctx.user.id,
@@ -495,7 +503,7 @@ export const funnelsRouter = createTRPCRouter({
495503
.returning();
496504

497505
return updatedFunnel;
498-
} catch (error: any) {
506+
} catch (error) {
499507
logger.error('Failed to update funnel', error.message, {
500508
funnelId: input.id,
501509
});
@@ -545,7 +553,7 @@ export const funnelsRouter = createTRPCRouter({
545553
);
546554

547555
return { success: true };
548-
} catch (error: any) {
556+
} catch (error) {
549557
logger.error('Failed to delete funnel', error.message, {
550558
funnelId: input.id,
551559
});
@@ -592,7 +600,7 @@ export const funnelsRouter = createTRPCRouter({
592600
type: string;
593601
target: string;
594602
name: string;
595-
conditions?: any;
603+
conditions?: Record<string, unknown>;
596604
}>;
597605
const filters =
598606
(funnelData.filters as Array<{
@@ -603,7 +611,7 @@ export const funnelsRouter = createTRPCRouter({
603611
const params: Record<string, unknown> = {
604612
websiteId: website.id,
605613
startDate,
606-
endDate: endDate + ' 23:59:59',
614+
endDate: `${endDate} 23:59:59`,
607615
};
608616
const filterClause = buildFilterConditions(filters, 'f', params);
609617
const stepQueries = steps.map((step, index) => {
@@ -748,8 +756,10 @@ export const funnelsRouter = createTRPCRouter({
748756
};
749757

750758
return overallAnalytics;
751-
} catch (error: any) {
752-
if (error instanceof TRPCError) throw error;
759+
} catch (error) {
760+
if (error instanceof TRPCError) {
761+
throw error;
762+
}
753763

754764
logger.error('Failed to fetch funnel analytics', error.message, {
755765
funnelId: input.funnelId,
@@ -798,7 +808,7 @@ export const funnelsRouter = createTRPCRouter({
798808
type: string;
799809
target: string;
800810
name: string;
801-
conditions?: any;
811+
conditions?: Record<string, unknown>;
802812
}>;
803813
const filters =
804814
(funnelData.filters as Array<{
@@ -815,7 +825,7 @@ export const funnelsRouter = createTRPCRouter({
815825
const params: Record<string, unknown> = {
816826
websiteId: website.id,
817827
startDate,
818-
endDate: endDate + ' 23:59:59',
828+
endDate: `${endDate} 23:59:59`,
819829
};
820830
const filterClause = buildFilterConditions(filters, 'f', params);
821831
const stepQueries = steps.map((step, index) => {
@@ -915,14 +925,22 @@ export const funnelsRouter = createTRPCRouter({
915925
}
916926
}
917927

918-
const referrerAnalytics = [];
928+
const referrerAnalytics: {
929+
referrer: string;
930+
referrer_parsed: ReturnType<typeof parseReferrer>;
931+
total_users: number;
932+
completed_users: number;
933+
conversion_rate: number;
934+
}[] = [];
919935
for (const [groupKey, group] of referrerGroups) {
920936
const stepCounts = new Map<number, Set<string>>();
921937
for (const sessionId of group.sessionIds) {
922938
const events = sessionEvents
923939
.get(sessionId)
924940
?.sort((a, b) => a.first_occurrence - b.first_occurrence);
925-
if (!events) continue;
941+
if (!events) {
942+
continue;
943+
}
926944
let currentStep = 1;
927945
for (const event of events) {
928946
if (event.step_number === currentStep) {
@@ -935,7 +953,9 @@ export const funnelsRouter = createTRPCRouter({
935953
}
936954
}
937955
const total_users = stepCounts.get(1)?.size || 0;
938-
if (total_users === 0) continue;
956+
if (total_users === 0) {
957+
continue;
958+
}
939959
const completed_users = stepCounts.get(steps.length)?.size || 0;
940960
const conversion_rate =
941961
total_users > 0
@@ -1003,8 +1023,10 @@ export const funnelsRouter = createTRPCRouter({
10031023
return {
10041024
referrer_analytics,
10051025
};
1006-
} catch (error: any) {
1007-
if (error instanceof TRPCError) throw error;
1026+
} catch (error) {
1027+
if (error instanceof TRPCError) {
1028+
throw error;
1029+
}
10081030

10091031
logger.error(
10101032
'Failed to fetch funnel analytics by referrer',

0 commit comments

Comments
 (0)