Perception
3D visualization of how couples see their relationship differently
Overview
Perception started with a question: how can two people in the same relationship describe it so differently? Each partner takes a 32-question quiz across 8 psychological dimensions independently. The scoring engine compares each person's self-perception against how their partner sees them and visualizes the gaps. A React Three Fiber body map renders 400+ colored particles based on Nummenmaa et al. (2014). D3 draws the radar chart as three overlapping layers (self, partner view, meta-perception). Fastify backend with password, magic link, and Google OAuth. Prisma on Postgres, organized as a 6-package Turborepo.
Built With
Architecture
Code
// Compare self-perception against how your partner sees you,
// per dimension. Lower gap = higher alignment.
export function computeDimensionScores(
self: Answers,
partnerView: Answers,
): DimensionScore[] {
return DIMENSIONS.map((dim) => {
const selfItems = self.filter((a) => a.dim === dim);
const viewItems = partnerView.filter((a) => a.dim === dim);
const selfAvg = mean(selfItems.map((a) => a.value));
const viewAvg = mean(viewItems.map((a) => a.value));
const gap = Math.abs(selfAvg - viewAvg);
return {
dim,
self: selfAvg,
partnerView: viewAvg,
gap,
alignment: 1 - gap / 6, // 6-point scale
};
});
}Feeds both the radar chart layers and the 3D body map. Shared across web and server so numbers match exactly.
Key Highlights
3D Body Maps
The body map renders 400+ colored particles mapped to body regions via React Three Fiber, inspired by Nummenmaa et al. (2014) research.
Radar Visualizations
A multi-layer D3.js radar chart overlays self, partner, and meta-perception scores across 8 dimensions.
Research-Backed
The quiz includes 32 questions derived from ECR-R, Gottman, IOS, Sternberg, and Ickes frameworks across 8 psychological dimensions.
Triple Auth
Users can sign in via email/password, magic link (Resend), or Google OAuth, with all three methods using JWT refresh tokens.
Monorepo
The codebase is organized as a 6-package Turborepo (web, server, db, shared, monitor, scaler) with shared scoring logic and independent deploys.

