A Next.js application for creating and sharing kinks profiles based on Aella's kinks list data.
- 📊 Interactive scatter plot visualization using Chart.js
- 🔐 Optional client-side E2E encryption with password protection
- 🔗 Short URL generation for easy sharing
- 📱 Responsive design with dark theme
- 💾 PostgreSQL database for storing profiles
- 🐳 Docker support for easy deployment
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS + shadcn/ui components
- Database: PostgreSQL with Prisma ORM
- Charts: Chart.js with react-chartjs-2
- Encryption: crypto-js (client-side)
- Package Manager: pnpm
- Node.js 20+
- pnpm
- Docker & Docker Compose (for running with containers)
- Clone the repository
cd kinks-bksp-in- Install dependencies
pnpm install- Set up environment variables
cp .env.example .envEdit .env and configure your database connection.
For easier testing, set NEXT_PUBLIC_USE_TEST_DATA="true" in .env to use only 15 kinks instead of all 246.
- Start PostgreSQL with Docker (Development)
docker-compose -f docker-compose.dev.yml up -d- Run database migrations
pnpm prisma:migrate- Start development server
pnpm devVisit http://localhost:3000
- Build and start all services
docker-compose up -dThis will start:
- PostgreSQL database on port 5432
- Next.js application on port 3000
- Run migrations
docker-compose exec app pnpm prisma:migratepnpm dev- Start development serverpnpm build- Build for productionpnpm start- Start production serverpnpm lint- Run ESLintpnpm prisma:migrate- Run database migrationspnpm prisma:studio- Open Prisma Studiopnpm docker:up- Start Docker servicespnpm docker:down- Stop Docker services
├── app/
│ ├── api/
│ │ └── profiles/ # API routes
│ ├── create/ # Profile creation page
│ ├── [shortId]/ # Profile view page
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ └── page.tsx # Landing page
├── components/
│ ├── ui/ # shadcn/ui components
│ ├── KinkRatingSlider.tsx # Rating slider component
│ ├── ProfileChart.tsx # Chart.js visualization
│ ├── PasswordPrompt.tsx # Password dialog
│ └── StepWizard.tsx # Multi-step form
├── lib/
│ ├── aella-data.ts # Kinks data utilities
│ ├── encryption.ts # Encryption utilities
│ ├── prisma.ts # Prisma client
│ └── utils.ts # General utilities
├── prisma/
│ └── schema.prisma # Database schema
├── aella_data.json # Source data (246 kinks)
├── aella_data.test.json # Test data (15 kinks for easier testing)
├── docker-compose.yml # Production Docker config
├── docker-compose.dev.yml # Development Docker config
└── Dockerfile # Application Dockerfile
For easier testing during development, you can use a smaller dataset:
- Set
NEXT_PUBLIC_USE_TEST_DATA="true"in your.envfile - Restart the dev server
- The app will now use only 15 kinks instead of 246
The test dataset (aella_data.test.json) includes a diverse range of kinks:
- Common/vanilla: blowjobs, cunnilingus, anal sex
- Light BDSM: light spanking, hair pulling, bondage
- Role-based: dominant, submissive
- Taboo: scat, furries, rapeplay
- Fetishes: feet, urine, choking
To switch back to the full dataset, set NEXT_PUBLIC_USE_TEST_DATA="false".
- Create Profile: Users fill out a step-by-step form rating 246 kinks from 0-100
- Optional Encryption: Users can set a password for client-side AES encryption
- Generate Link: System creates a short URL using nanoid
- View Profile: Interactive chart displays ratings on a scatter plot with:
- X-axis: Tabooness score
- Y-axis: Popularity (logarithmic scale)
- Color: Green (high rating) to Red (low rating)
- Zoom & Pan support
model Profile {
id String @id @default(cuid())
shortId String @unique
nickname String
data String // JSON (encrypted if password set)
isEncrypted Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}- Passwords are NEVER sent to the server
- Encryption happens entirely client-side using AES
- Encrypted data is stored as an encrypted string in the database
- Decryption also happens client-side when viewing profiles
MIT