Skip to content

analytics pair programming review #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

analytics pair programming review #444

wants to merge 3 commits into from

Conversation

vincanger
Copy link
Collaborator

Description

Describe your PR! If it fixes specific issue, mention it with "Fixes # (issue)".

Contributor Checklist

Make sure to do the following steps if they are applicable to your PR:

sources: PageViewSource[];
};

type DailyStatsValues = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it has daily and weekly stats, so maybe DailyStatsValues is not the best name?

Comment on lines 33 to 34
context.entities.DailyStats.findFirst(statsQuery),
context.entities.DailyStats.findMany({ ...statsQuery, take: 7 }),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably just do findMany and get first one from it.

]);

if (!dailyStats) {
console.log('\x1b[34mNote: No daily stats have been generated by the dailyStatsJob yet. \x1b[0m');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that dailyStatsJob genreates the daily stats and that it is called that way. Might be better if the message here is less specific, or if it didn't happen here at all.

return undefined;
}

return { dailyStats, weeklyStats };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so this function says getDailyStats but returns both daily Stats and weeklyStats, look into that.

import { HttpError, prisma } from 'wasp/server';
import { type GetDailyStats } from 'wasp/server/operations';

type DailyStatsWithSources = DailyStats & {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it clear enough here that sources are PageViewSources? Mayee it is , but if not we can make it clearer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider renaming to jobs.ts and creating an index.ts entrypoint file.

import { stripe } from '../payment/stripe/stripeClient';
import { listOrders } from '@lemonsqueezy/lemonsqueezy.js';
import { getDailyPageViews, getSources } from './providers/plausibleAnalyticsUtils';
// import { getDailyPageViews, getSources } from './providers/googleAnalyticsUtils';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This often gets overlooked. Maybe create an interface in index.ts that's explicit about which provider is being used.

import { paymentProcessor } from '../payment/paymentProcessor';
import { SubscriptionStatus } from '../payment/plans';

export type DailyStatsProps = { dailyStats?: DailyStats; weeklyStats?: DailyStats[]; isLoading?: boolean };
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is only being used by the admin dash components. Consider moving it to a central place there.

Comment on lines 14 to 18
const nowUTC = new Date(Date.now());
nowUTC.setUTCHours(0, 0, 0, 0);

const yesterdayUTC = new Date(nowUTC);
yesterdayUTC.setUTCDate(yesterdayUTC.getUTCDate() - 1);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's extract this to a function or make it a one liner with a descriptive variable name.

const yesterdaysStats = await context.entities.DailyStats.findFirst({
where: {
date: {
equals: yesterdayUTC,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigate whether this needs to be equals or it could be, .e.g. the most recent entity from yesterday, or >= or <= or something like that.


export type DailyStatsProps = { dailyStats?: DailyStats; weeklyStats?: DailyStats[]; isLoading?: boolean };

export const calculateDailyStats: DailyStatsJob<never, void> = async (_args, context) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole function would benefit a lot by extracting the main parts to helper functions and organizing them logically.

Comment on lines 59 to 95
let dailyStats = await context.entities.DailyStats.findUnique({
where: {
date: nowUTC,
},
});

if (!dailyStats) {
console.log('No daily stat found for today, creating one...');
dailyStats = await context.entities.DailyStats.create({
data: {
date: nowUTC,
totalViews,
prevDayViewsChangePercent,
userCount,
paidUserCount,
userDelta,
paidUserDelta,
totalRevenue,
},
});
} else {
console.log('Daily stat found for today, updating it...');
dailyStats = await context.entities.DailyStats.update({
where: {
id: dailyStats.id,
},
data: {
totalViews,
prevDayViewsChangePercent,
userCount,
paidUserCount,
userDelta,
paidUserDelta,
totalRevenue,
},
});
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with upsert.

},
});
}
const sources = await getSources();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const sources = await getSources();
const sources = await getSources();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to pageViewSources.

Comment on lines 96 to 120
const sources = await getSources();

for (const source of sources) {
let visitors = source.visitors;
if (typeof source.visitors !== 'number') {
visitors = parseInt(source.visitors);
}
await context.entities.PageViewSource.upsert({
where: {
date_name: {
date: nowUTC,
name: source.source,
},
},
create: {
date: nowUTC,
name: source.source,
visitors,
dailyStatsId: dailyStats.id,
},
update: {
visitors,
},
});
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the user more aware of why pageViewSources are here and what's going on? Can we make it more clear what the connection between dailyStats and pageViewSources is here?

Also, can we extract this upsert logic to a helper function because it feels too specific?

console.table({ dailyStats });
} catch (error: any) {
console.error('Error calculating daily stats: ', error);
await context.entities.Logs.create({
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be extracted to a log provider/helper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants