Improve automation, relinted webapp to tab alignment

and introduced basic EDA in a jupyter notebook of kafka export (nonmodular yet)
This commit is contained in:
2025-11-02 21:34:18 +01:00
parent 8797fb3976
commit f4da5289bd
7 changed files with 680 additions and 118 deletions

View File

@@ -5,8 +5,13 @@ TEX := main.tex
JOBNAME := main JOBNAME := main
PDF := paper/$(BUILDDIR)/$(JOBNAME).pdf PDF := paper/$(BUILDDIR)/$(JOBNAME).pdf
.DEFAULT_GOAL := help
all: pdf all: pdf
run.webapp:
@cd web && npm install && npm run dev
$(BUILDDIR): $(BUILDDIR):
mkdir -p paper/$(BUILDDIR) mkdir -p paper/$(BUILDDIR)
@@ -31,4 +36,4 @@ clean:
rm -rf paper/$(BUILDDIR)/* rm -rf paper/$(BUILDDIR)/*
.PHONY: all pdf clean watch .PHONY: all pdf clean watch run.webapp

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,6 @@
kafka-python kafka-python
dotenv dotenv
pandas
jupyter
ipykernel
matplotlib

View File

@@ -1,4 +1,5 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import '@/lib/experiments' // ensure experiments lib is loaded
const genSessionId = () => { const genSessionId = () => {
if (typeof window === 'undefined') return ''; if (typeof window === 'undefined') return '';
@@ -6,6 +7,9 @@ const genSessionId = () => {
if (!sid) { if (!sid) {
sid = `${Date.now()}-${Math.random().toString(36).slice(2)}`; sid = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
sessionStorage.setItem('phantom_session_id', sid); sessionStorage.setItem('phantom_session_id', sid);
// TODO: when creating new id send to exepriemtn tracking db
// match between sesion-id and experiment-id for this session
// so that we can identify all interactions aligning with a specific experiment goal.
} }
return sid; return sid;
}; };
@@ -71,13 +75,43 @@ export const useInteractionTracking = () => {
}); });
}; };
enum DefinedInteractions {
ADD_TO_CART = 'add_to_cart',
PURCHASE = 'purchase',
}
// called when clicking on "Add to Cart" button or "Purchase" button
const handleDefinedInteraction = (
interactionType: DefinedInteractions,
metadata?: Record<string, any>
) => {
track({
sessionId: sidRef.current,
eventType: interactionType,
metadata: {
path: window.location.pathname,
...metadata,
},
});
};
handlePageView(); handlePageView();
document.addEventListener('click', handleClick); document.addEventListener('click', handleClick);
window.addEventListener('scroll', handleScroll, { passive: true }); document.addEventListener('definedInteraction', (e: Event) => {
const customEvent = e as CustomEvent;
handleDefinedInteraction(customEvent.detail.interactionType, customEvent.detail.metadata);
});
// TOO NOISY: enable if needed but tbh not worth it
//window.addEventListener('scroll', handleScroll, { passive: true });
return () => { return () => {
document.removeEventListener('click', handleClick); document.removeEventListener('click', handleClick);
window.removeEventListener('scroll', handleScroll); document.removeEventListener('definedInteraction', (e: Event) => {
const customEvent = e as CustomEvent;
handleDefinedInteraction(customEvent.detail.interactionType, customEvent.detail.metadata);
});
//window.removeEventListener('scroll', handleScroll);
}; };
}, []); }, []);
}; };

View File

@@ -0,0 +1 @@
//

View File

@@ -24,6 +24,7 @@ export const sendInteractionEvent = async (ev: {
ts: number; ts: number;
}) => { }) => {
const p = await getProducer(); const p = await getProducer();
// add to the metadata
await p.send({ await p.send({
topic: 'user-interactions', topic: 'user-interactions',
messages: [{ messages: [{