Skip to content

Commit

Permalink
feat[mixpanel]: integration of mix panel for analytics (#43)
Browse files Browse the repository at this point in the history
* feat[MIX_PANEL]: integrate mix panel for analytics

* fix: make debug optional based on the environment

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: remove api key tracking from event tracking

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: correct mixpanel variable name

* lint: fix prettier

---------

Co-authored-by: Gabriele Venturi <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 26, 2024
1 parent 86d8618 commit d876353
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 8 deletions.
6 changes: 3 additions & 3 deletions backend/app/api/v1/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ def get_user_api_key(db: Session = Depends(get_db)):

@user_router.get("/getme", status_code=200)
def get_me(db: Session = Depends(get_db)):
user_email = "[email protected]"
user = user_repository.get_user(db, user_email)
users = user_repository.get_users(db, n=1)


return {
"status": "success",
"message": "User details returned successfully!",
"data": user,
"data": users[0] if len(users) > 0 else None,
}


Expand Down
3 changes: 2 additions & 1 deletion frontend/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
NEXT_PUBLIC_API_URL=http://localhost:3000/api/v1
NEXT_PUBLIC_STORAGE_URL=http://localhost:3000/api/assets
NEXT_PUBLIC_STORAGE_URL=http://localhost:3000/api/assets
NEXT_PUBLIC_MIXPANEL_TOKEN=f2e8a71ab2bde33ebf346c5abf6ba9fa
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
"@react-pdf/renderer": "^4.0.0",
"@tanstack/react-query": "^5.51.1",
"@tippyjs/react": "^4.2.6",
"@types/mixpanel-browser": "^2.50.1",
"axios": "^1.7.2",
"date-fns": "^3.6.0",
"framer-motion": "^11.3.31",
"lucide-react": "^0.408.0",
"marked": "^13.0.2",
"mixpanel-browser": "^2.55.1",
"next": "14.2.4",
"openai": "^4.52.5",
"papaparse": "^5.4.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import DataTable from "@/components/DataTable";
import Papa from "papaparse";
import { BASE_API_URL } from "@/constants";
import { toast } from "react-hot-toast";
import { trackEvent } from "@/lib/mixpanelLib";

const ProcessPage = () => {
const router = useRouter();
Expand Down Expand Up @@ -55,6 +56,8 @@ const ProcessPage = () => {
},
header: true,
});

trackEvent("Table opened", { url: `process_${processId}.csv` });
} catch (error) {
console.error("Error loading CSV data:", error);
setIsLoading(false);
Expand All @@ -77,6 +80,7 @@ const ProcessPage = () => {
document.body.removeChild(a);

// Show success toast
trackEvent("Download CSV", { url: `process_${processId}.csv` });
toast.success("CSV downloaded successfully");
} catch (error) {
console.error("Error downloading CSV:", error);
Expand Down
55 changes: 55 additions & 0 deletions frontend/src/lib/mixpanelLib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { GetUserData } from "@/services/user";
import mixpanel, { Mixpanel } from "mixpanel-browser";

const MIXPANEL_TOKEN = process.env.NEXT_PUBLIC_MIXPANEL_TOKEN;

let mixpanelInstance: Mixpanel | null = null;

let isInitialized = false;

const initMixpanel = async () => {
if (typeof window !== "undefined" && MIXPANEL_TOKEN && !isInitialized) {
mixpanel.init(MIXPANEL_TOKEN, {
debug: process.env.NODE_ENV === "development",
});

const user = await GetUserData();

if (user.data.data) {
mixpanel.identify(user.data.data.email);

mixpanel.people.set({
$name: `${user.data.data.first_name} ${user.data.data.last_name}`,
$email: user.data.data.email,
});
}

mixpanelInstance = mixpanel;
isInitialized = true;
} else if (!MIXPANEL_TOKEN) {
console.warn("Mixpanel token is missing; tracking will be disabled.");
}
};

const trackEvent = async (
eventName: string,
eventProps = {}
): Promise<void> => {
if (!isInitialized) {
initMixpanel();
}
if (mixpanelInstance) {
mixpanelInstance.track(eventName, eventProps);
} else {
console.warn(
`Event "${eventName}" not tracked because Mixpanel is not initialized.`
);
}
};

// Initialize Mixpanel on the client at import
if (typeof window !== "undefined") {
initMixpanel();
}

export { trackEvent };
2 changes: 2 additions & 0 deletions frontend/src/services/processes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ProcessResumeData,
ProcessSuggestionRequest,
} from "@/interfaces/processes";
import { trackEvent } from "@/lib/mixpanelLib";

export const processApiUrl = "/processes";

Expand Down Expand Up @@ -35,6 +36,7 @@ export const StartProcess = async (data: ProcessRequest) => {
`${processApiUrl}/start`,
data
);
trackEvent("Start Process", data);
return response;
} catch (error) {
throw error;
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/services/projects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { AssetData } from "@/interfaces/assets";
import { ProcessData } from "@/interfaces/processes";
import { BASE_API_URL } from "@/constants";
import { AxiosResponse } from "axios";
import { trackEvent } from "@/lib/mixpanelLib";

const projectsApiUrl = "/projects";

Expand Down Expand Up @@ -49,6 +50,8 @@ export const CreateProject = async (data: {
projectsApiUrl,
data
);

trackEvent("Project created", { data });
return response;
} catch (error) {
throw error;
Expand Down Expand Up @@ -158,7 +161,6 @@ export const DeleteAssets = async (projectId: string, assetId: string) => {
}
};

// Add this new function to update a project
export const UpdateProject = async (
projectId: string,
data: { name: string; description: string }
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/services/user.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { GetRequest, PostRequest, PutRequest } from "@/lib/requests";
import { APIKeyData } from "@/interfaces/user";
import { UserData } from "@/interfaces/user";
import localStorage from "@/lib/localStorage";
import { trackEvent } from "@/lib/mixpanelLib";

const userApiUrl = "/user";

Expand All @@ -11,6 +12,7 @@ export const APIKeyRequest = async (data: { email: string }) => {
`${userApiUrl}/request-api-key`,
data
);
trackEvent("API Key Request", data);
return response;
} catch (error) {
throw error;
Expand All @@ -24,6 +26,10 @@ export const SaveAPIKey = async (data: { api_key: string }) => {
data
);
localStorage.setItem("api_key", data.api_key);
trackEvent("API Key Activation", {
timestamp: new Date().toISOString(),
success: true,
});
return response;
} catch (error) {
throw error;
Expand Down
94 changes: 91 additions & 3 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,13 @@
resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz"
integrity sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==

"@rrweb/types@^2.0.0-alpha.13":
version "2.0.0-alpha.17"
resolved "https://registry.yarnpkg.com/@rrweb/types/-/types-2.0.0-alpha.17.tgz#bf4af026e767022674892919692d59e766e9368e"
integrity sha512-AfDTVUuCyCaIG0lTSqYtrZqJX39ZEYzs4fYKnexhQ+id+kbZIpIJtaut5cto6dWZbB3SEe4fW0o90Po3LvTmfg==
dependencies:
rrweb-snapshot "^2.0.0-alpha.17"

"@rtsao/scc@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz"
Expand Down Expand Up @@ -746,6 +753,11 @@
dependencies:
tippy.js "^6.3.1"

"@types/[email protected]":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz#2f98ede46acc0975de85c0b7b0ebe06041d24601"
integrity sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==

"@types/debug@^4.0.0":
version "4.1.12"
resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz"
Expand Down Expand Up @@ -784,6 +796,11 @@
dependencies:
"@types/unist" "*"

"@types/mixpanel-browser@^2.50.1":
version "2.50.1"
resolved "https://registry.yarnpkg.com/@types/mixpanel-browser/-/mixpanel-browser-2.50.1.tgz#e93b8754893369bd0a9eae61ce2a45f392ca4e7f"
integrity sha512-Z9QnzNIZtsyhc0tvGFeaYCo2NJTGwWi8pqLMB3z/BnGUdEpr3x2qK28KKTjVH31DMbQ0IwqjNQElwJP+XpmeMQ==

"@types/ms@*":
version "0.7.34"
resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz"
Expand Down Expand Up @@ -918,6 +935,11 @@
resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz"
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==

"@xstate/fsm@^1.4.0":
version "1.6.5"
resolved "https://registry.yarnpkg.com/@xstate/fsm/-/fsm-1.6.5.tgz#f599e301997ad7e3c572a0b1ff0696898081bea5"
integrity sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==

abbrev@1:
version "1.1.1"
resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz"
Expand Down Expand Up @@ -1188,6 +1210,11 @@ balanced-match@^1.0.0:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==

base64-arraybuffer@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==

base64-js@^1.1.2, base64-js@^1.3.0:
version "1.5.1"
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
Expand Down Expand Up @@ -2123,6 +2150,11 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"

fflate@^0.4.4:
version "0.4.8"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==

file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
Expand Down Expand Up @@ -3628,6 +3660,18 @@ minizlib@^2.1.1:
minipass "^3.0.0"
yallist "^4.0.0"

mitt@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==

mixpanel-browser@^2.55.1:
version "2.55.1"
resolved "https://registry.yarnpkg.com/mixpanel-browser/-/mixpanel-browser-2.55.1.tgz#d37a8d3777abd4c58d537ea87959c9d9b9b507c8"
integrity sha512-NSEPdFSJxoR1OCKWKHbtqd3BeH1c9NjXbEt0tN5TgBEO1nSDji6niU9n4MopAXOP0POET9spjpQKxZtLZKTJwA==
dependencies:
rrweb "2.0.0-alpha.13"

mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
Expand Down Expand Up @@ -4050,7 +4094,7 @@ [email protected]:
picocolors "^1.0.0"
source-map-js "^1.0.2"

postcss@^8, postcss@^8.4.23:
postcss@^8, postcss@^8.4.23, postcss@^8.4.38:
version "8.4.47"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz"
integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
Expand Down Expand Up @@ -4408,6 +4452,34 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"

rrdom@^2.0.0-alpha.13:
version "2.0.0-alpha.17"
resolved "https://registry.yarnpkg.com/rrdom/-/rrdom-2.0.0-alpha.17.tgz#c200f21a63bab341caea7f3f2f88d760aa045c3a"
integrity sha512-b6caDiNcFO96Opp7TGdcVd4OLGSXu5dJe+A0IDiAu8mk7OmhqZCSDlgQdTKmdO5wMf4zPsUTgb8H/aNvR3kDHA==
dependencies:
rrweb-snapshot "^2.0.0-alpha.17"

rrweb-snapshot@^2.0.0-alpha.13, rrweb-snapshot@^2.0.0-alpha.17:
version "2.0.0-alpha.17"
resolved "https://registry.yarnpkg.com/rrweb-snapshot/-/rrweb-snapshot-2.0.0-alpha.17.tgz#c4667cbca62530bcb98508e6c85c20f2b320f5ca"
integrity sha512-GBg5pV8LHOTbeVmH2VHLEFR0mc2QpQMzAvcoxEGfPNWgWHc8UvKCyq7pqN1vA+fDZ+yXXbixeO0kB2pzVvFCBw==
dependencies:
postcss "^8.4.38"

[email protected]:
version "2.0.0-alpha.13"
resolved "https://registry.yarnpkg.com/rrweb/-/rrweb-2.0.0-alpha.13.tgz#37798404acd985212f72544c8823af275fdad514"
integrity sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==
dependencies:
"@rrweb/types" "^2.0.0-alpha.13"
"@types/css-font-loading-module" "0.0.7"
"@xstate/fsm" "^1.4.0"
base64-arraybuffer "^1.0.1"
fflate "^0.4.4"
mitt "^3.0.0"
rrdom "^2.0.0-alpha.13"
rrweb-snapshot "^2.0.0-alpha.13"

run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
Expand Down Expand Up @@ -4592,7 +4664,16 @@ string-argv@~0.3.2:
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==

"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -4696,7 +4777,14 @@ stringify-entities@^4.0.0:
character-entities-html4 "^2.0.0"
character-entities-legacy "^3.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down

0 comments on commit d876353

Please sign in to comment.