Katarzyna Stępień
Overview
All work

Data engineering · streaming · CDC

UX friction detection, in real time

A data platform that watches how people use an app and flags friction as it happens: rage clicks, abandoned sessions, screens people get stuck on. Every interaction is captured from the database with change data capture and processed as a stream.

Goal

Detect UX friction signals while sessions are happening.

What I built

A Docker stack: PostgreSQL with Debezium CDC, Kafka, Spark Structured Streaming, Delta Lake on MinIO.

Output

Friction events scored per interaction and per session, stored with ACID guarantees.

PythonPostgreSQLDebeziumKafkaSparkDelta LakeMinIODocker
UX events flow from a Python simulator into PostgreSQL, are captured by Debezium, streamed through Kafka, processed by Spark Structured Streaming, and stored in Delta Lake on MinIO, with friction signals flagged UX simulatorpython PostgreSQLlogical replication DebeziumCDC Kafkatopics Sparkstreaming Delta Lakeon MinIO (S3) rage clicks abandonment long screen time

Friction rules

SignalRuleSeverity
Rage clickevent_type = 'rage_click' or more than 5 clicksHigh
Session abandonmentevent_type = 'session_abandon'High
Long screen timemore than 120 s on a screenMedium
Form errorevent_type = 'form_error'Medium
Excessive scrollingevent_type = 'rapid_scroll'Low

Data model

TableWhat it holds
usersProfiles: device, OS, browser, country
screensEach screen's category, UX goal, expected time and whether it sits on the critical path
sessionsStart and end, device, converted, abandoned, number of events, total friction score
ux_interactionsEach event: screen, type, time on screen, clicks, scroll depth, friction flag and score

How it runs

Capture

A Python simulator writes realistic sessions to PostgreSQL. Debezium reads the logical replication log and publishes every insert and update to Kafka as JSON.

Process and store

Spark Structured Streaming reads from Kafka, applies the rules and aggregates per session in time windows. Results land in Delta Lake on MinIO, S3-compatible storage with ACID transactions.

Operate

One docker-compose up -d starts everything, with health checks, automatic connector registration and named volumes. Kafka UI and Spark UI make it observable.

A reusable template

The same pattern as a mini data platform: CSV-driven activity, Kafka in KRaft mode without Zookeeper, and bronze, silver and gold layers on MinIO, started with one script.

See all work