# 💋 SEXY

<div align="center">

![sexy lips tongue mouth american apparel moist lip gloss ](https://i.gifer.com/1pYe.gif)

_"Lust und Liebe gehören zusammen - wer das eine verteufelt, zerstört auch das andere."_
— **Beate Uhse**, Pionierin der sexuellen Befreiung ✈️

---

### 🍆 An Intimate Platform for Liberation & Pleasure 🍆

Built with passion, technology, and the fearless spirit of sexual empowerment

[![Build Frontend](https://dev.pivoine.art/valknar/sexy/actions/workflows/docker-build-frontend.yml/badge.svg)](https://dev.pivoine.art/valknar/sexy/actions)
[![Build Backend](https://dev.pivoine.art/valknar/sexy/actions/workflows/docker-build-backend.yml/badge.svg)](https://dev.pivoine.art/valknar/sexy/actions)
[![Build Buttplug](https://dev.pivoine.art/valknar/sexy/actions/workflows/docker-build-buttplug.yml/badge.svg)](https://dev.pivoine.art/valknar/sexy/actions)
[![License](https://img.shields.io/badge/License-For_Pleasure-FF1493?style=for-the-badge&logo=heart&logoColor=white&labelColor=8B008B)](LICENSE)
[![Made with Love](https://img.shields.io/badge/Made_with-💜_Love-FF69B4?style=for-the-badge&labelColor=8B008B)](https://pivoine.art)

</div>

---

## 👅 What Is This Delicious Creation?

Welcome, dear pleasure-seeker! This is **sexy** — a modern, sensual platform built from the ground up with full control over every intimate detail. A **SvelteKit** frontend caresses a purpose-built **Fastify + GraphQL** backend, while **Buttplug.io** hardware integration brings the experience into the physical world.

Like Beate Uhse breaking barriers in post-war Germany, we believe in the freedom to explore, create, and celebrate sexuality without shame. This platform is built for **models**, **creators**, and **connoisseurs** of adult content who deserve technology as sophisticated as their desires.

### ♉ Features That'll Make You Blush ♊

- 💖 **Sensual SvelteKit Frontend** with Tailwind CSS 4 styling
- ⚡ **Purpose-built GraphQL Backend** — lean, fast, no CMS overhead
- 🔐 **Session-based Auth** with Redis & Argon2 — discretion guaranteed
- 🖼️ **Smart Image Transforms** via Sharp (WebP, multiple presets, cached)
- 🎮 **Hardware Integration** via Buttplug.io (yes, really!)
- 📱 **Responsive Design** that looks sexy on any device
- 🌍 **Internationalization** — pleasure speaks all languages
- 🏆 **Gamification** — achievements, leaderboards, and reward points
- 💬 **Comments & Social** — build your community
- 💌 **Professional HTML Emails** — Maizzle v6 + Tailwind CSS 4 templated email (verification, password reset)
- 📊 **Analytics Integration** (Umami) — know your admirers
- 🐳 **Self-hosted CI/CD** via Gitea Actions on `dev.pivoine.art`

<div align="center">

### 🍑 Technology Stack 🍑

</div>

```
┌─────────────────────────────────────────────────────────────┐
│  💋 Frontend Layer                                          │
│  ├─ SvelteKit 2           → Smooth as silk                  │
│  ├─ Tailwind CSS 4        → Styled to seduce                │
│  ├─ bits-ui Components    → Building blocks of pleasure     │
│  ├─ graphql-request v7    → Whispering to the backend       │
│  └─ Vite                  → Fast and furious                │
├─────────────────────────────────────────────────────────────┤
│  🍷 Backend Layer                                           │
│  ├─ Fastify v5            → The fastest penetration         │
│  ├─ GraphQL Yoga v5       → Flexible positions              │
│  ├─ Pothos (code-first)   → Schema with intention           │
│  ├─ Drizzle ORM           → Data with grace                 │
│  ├─ PostgreSQL 16         → Deep and persistent             │
│  ├─ Redis                 → Sessions that never forget      │
│  ├─ Sharp                 → Images transformed beautifully  │
│  └─ Argon2                → Passwords hashed with passion   │
├─────────────────────────────────────────────────────────────┤
│  🎀 Hardware Layer                                          │
│  ├─ Buttplug.io           → Real connections                │
│  ├─ TypeScript + Rust     → Power and precision             │
│  └─ WebBluetooth API      → Wireless intimacy               │
├─────────────────────────────────────────────────────────────┤
│  💌 Email Layer                                             │
│  ├─ Maizzle v6            → HTML email framework            │
│  ├─ @maizzle/tailwindcss  → Email-safe Tailwind CSS 4       │
│  └─ Nodemailer            → SMTP delivery                   │
├─────────────────────────────────────────────────────────────┤
│  🌸 DevOps Layer                                            │
│  ├─ Docker                → Containerized ecstasy           │
│  ├─ Gitea Actions         → Self-hosted seduction           │
│  └─ dev.pivoine.art       → Our own pleasure palace         │
└─────────────────────────────────────────────────────────────┘
```

---

## 🔥 Quick Start — Get Intimate Fast

### 💕 Option 1: Using Docker Compose (Recommended)

```bash
# Clone the repository
git clone https://dev.pivoine.art/valknar/sexy.git
cd sexy

# Configure your secrets
cp .env.example .env
# Edit .env with your intimate details

# Awaken all services (postgres, redis, backend, frontend)
docker compose up -d

# Visit your creation at http://localhost:3000 💋
```

### 💜 Option 2: Local Development

**Prerequisites:**

1. Node.js 20.19.1 — _the foundation_
2. `corepack enable` — _unlock the tools_
3. `pnpm install` — _gather your ingredients_
4. PostgreSQL 16 + Redis — _the data lovers_

**Start your pleasure journey:**

```bash
# Awaken data services
pnpm dev:data

# Start the backend (port 4000)
pnpm dev:backend

# Start the frontend (port 3000, proxied to :4000)
pnpm --filter @sexy/frontend dev
```

Visit `http://localhost:3000` and let the experience begin... 💋

GraphQL playground is available at `http://localhost:4000/graphql` — explore every query.

---

## 🌹 Project Structure

This monorepo contains four packages, each serving its purpose:

```
sexy/
├─ 💄 packages/frontend/    → SvelteKit app (the seduction)
├─ ⚡ packages/backend/      → Fastify + GraphQL API (the engine)
├─ 🎮 packages/buttplug/     → Hardware control (the connection)
└─ 💌 packages/email/        → Maizzle HTML email templates
```

### 💄 Frontend (`packages/frontend/`)

SvelteKit 2 application with server-side rendering, i18n, and a clean component library.
Communicates with the backend exclusively via GraphQL using `graphql-request`.
Assets served via `/api/assets/:id?transform=<preset>` — no CDN, no Directus, just raw power.

### ⚡ Backend (`packages/backend/`)

Purpose-built Fastify v5 + GraphQL Yoga server. All business logic lives here:
auth, file uploads, video processing, comments, gamification, and analytics.
Files stored as `<UPLOAD_DIR>/<uuid>/<filename>` with on-demand WebP transforms cached on disk.

### 🎮 Buttplug (`packages/buttplug/`)

Hybrid TypeScript/Rust package for intimate hardware control via WebBluetooth.
Compiled to WebAssembly for browser-based Bluetooth device communication.

### 💌 Email (`packages/email/`)

Professional HTML email templates built with **Maizzle v6** + **Tailwind CSS 4** (`@maizzle/tailwindcss`).
Design tokens mirror the frontend's `app.css` exactly — same oklch colors, Noto Sans font, semantic classes.
LightningCSS automatically converts oklch values to hex for email client compatibility.
Exported functions: `renderVerification({ token })` and `renderPasswordReset({ token })` — each returns `{ subject, html }`.

---

## 🗃️ Database Schema

Built with Drizzle ORM — clean tables, no `directus_` prefix, full control:

```
users          → profiles, roles (model/viewer/admin), auth tokens
files          → uploaded assets with metadata and duration
videos         → content with model junctions, likes, plays
articles       → magazine / editorial content
recordings     → user-created content with play tracking
comments       → threaded by collection + item_id
achievements   → gamification goals
user_points    → points ledger
user_stats     → cached leaderboard data
```

---

## 🔐 Authentication Flow

```
POST /graphql (login mutation)
  → verify argon2 password hash
  → nanoid(32) session token
  → SET session:<token> <user JSON> EX 86400 in Redis
  → set httpOnly cookie: session_token
  → return CurrentUser

Every request:
  → read session_token cookie
  → GET session:<token> from Redis
  → inject currentUser into GraphQL context
```

---

## 🖼️ Image Transforms

Assets are transformed on first request and cached as WebP:

| Preset      | Size        | Fit    | Use              |
| ----------- | ----------- | ------ | ---------------- |
| `mini`      | 80×80       | cover  | Avatars in lists |
| `thumbnail` | 300×300     | cover  | Profile photos   |
| `preview`   | 800px wide  | inside | Video teasers    |
| `medium`    | 1400px wide | inside | Full-size images |
| `banner`    | 1600×480    | cover  | Profile banners  |

---

## 🚀 Deployment

### Production with Docker Compose

```bash
# Configure your secrets
cp .env.example .env.production
# Edit .env.production — set DB credentials, SMTP, cookie secret, CORS origin

# Deploy
docker compose --env-file .env.production up -d
```

Key environment variables for the backend:

```env
DATABASE_URL=postgresql://sexy:sexy@postgres:5432/sexy
REDIS_URL=redis://redis:6379
COOKIE_SECRET=your-very-secret-key
CORS_ORIGIN=https://sexy.pivoine.art
UPLOAD_DIR=/data/uploads
SMTP_HOST=your.smtp.host
SMTP_PORT=587
EMAIL_FROM=noreply@sexy.pivoine.art
PUBLIC_URL=https://sexy.pivoine.art
```

### 🎬 CI/CD — Self-Hosted Seduction

Automated builds run on **[dev.pivoine.art](https://dev.pivoine.art/valknar/sexy)** via Gitea Actions:

- ✅ Frontend image → `dev.pivoine.art/valknar/sexy:latest`
- ✅ Backend image → `dev.pivoine.art/valknar/sexy-backend:latest`
- ✅ Buttplug image → `dev.pivoine.art/valknar/sexy-buttplug:latest`
- ✅ Triggers on push to `main`, `develop`, or version tags (`v*.*.*`)
- ✅ Build cache via registry for fast successive builds

Images are pulled on the production server via Watchtower or manual `docker compose pull && docker compose up -d`.

---

## 🎭 Development Workflow

```mermaid
graph LR
    A[💡 Idea] --> B[💻 Code]
    B --> C[🧪 Test Locally]
    C --> D[🌿 Feature Branch]
    D --> E[📤 Push to dev.pivoine.art]
    E --> F{✅ Build Pass?}
    F -->|Yes| G[🔀 Merge to Main]
    F -->|No| B
    G --> H[🚀 Images Built & Pushed]
    H --> I[🎉 Deploy to Production]
```

1. Create → `git checkout -b feature/my-sexy-feature`
2. Develop → Write beautiful code
3. Test → `pnpm dev:data && pnpm dev:backend && pnpm dev`
4. Push → `git push` to `dev.pivoine.art` (triggers CI build)
5. Merge → Images published, deploy to production
6. Release → `git tag v1.0.0 && git push origin v1.0.0`

---

## 🌈 Environment Variables

### Backend (required)

| Variable        | Description                   |
| --------------- | ----------------------------- |
| `DATABASE_URL`  | PostgreSQL connection string  |
| `REDIS_URL`     | Redis connection string       |
| `COOKIE_SECRET` | Session cookie signing secret |
| `CORS_ORIGIN`   | Allowed frontend origin       |
| `UPLOAD_DIR`    | Path for uploaded files       |

### Backend (optional)

| Variable     | Default | Description                    |
| ------------ | ------- | ------------------------------ |
| `PORT`       | `4000`  | Backend listen port            |
| `LOG_LEVEL`  | `info`  | Fastify log level              |
| `SMTP_HOST`  | —       | Email server for auth flows    |
| `SMTP_PORT`  | `587`   | Email server port              |
| `EMAIL_FROM` | —       | Sender address                 |
| `PUBLIC_URL` | —       | Frontend URL (for email links) |

### Frontend

| Variable              | Description                                   |
| --------------------- | --------------------------------------------- |
| `PUBLIC_API_URL`      | Backend URL (e.g. `http://sexy_backend:4000`) |
| `PUBLIC_URL`          | Frontend public URL                           |
| `PUBLIC_UMAMI_ID`     | Umami analytics site ID (optional)            |
| `PUBLIC_UMAMI_SCRIPT` | Umami script URL (optional)                   |

---

## 💌 Credits & Acknowledgments

<div align="center">

### 🌸 Created with Love by 🌸

**[Palina](https://palina.pivoine.art) & [Valknar](https://pivoine.art)**

_Für die Mäuse..._ 🐭💕

---

### 🙏 Built With

| Technology                                                | Purpose              |
| --------------------------------------------------------- | -------------------- |
| [SvelteKit](https://kit.svelte.dev/)                      | Frontend framework   |
| [Fastify](https://fastify.dev/)                           | HTTP server          |
| [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server) | GraphQL server       |
| [Pothos](https://pothos-graphql.dev/)                     | Code-first schema    |
| [Drizzle ORM](https://orm.drizzle.team/)                  | Database             |
| [Sharp](https://sharp.pixelplumbing.com/)                 | Image transforms     |
| [Buttplug.io](https://buttplug.io/)                       | Hardware             |
| [Maizzle](https://maizzle.com/)                           | HTML email framework |
| [Nodemailer](https://nodemailer.com/)                     | Email delivery       |
| [bits-ui](https://www.bits-ui.com/)                       | UI components        |
| [Gitea](https://dev.pivoine.art)                          | Self-hosted VCS & CI |

---

### 💐 Inspired by Beate Uhse

Pioneer of sexual liberation (1919-2001)
Pilot, Entrepreneur, Freedom Fighter

_"Eine Frau, die ihre Sexualität selbstbestimmt lebt, ist eine freie Frau."_

![Beate Uhse Quote](https://img.shields.io/badge/Beate_Uhse-Sexual_Liberation_Pioneer-FF1493?style=for-the-badge&logo=heart&logoColor=white&labelColor=8B008B)

</div>

---

## ⚖️ License & Legal

- 📜 See [LICENSE](LICENSE) file for details
- 🔞 **18+ Only** — This platform is for adults
- 🌍 Users must be of legal age in their jurisdiction
- ⚖️ We support equality, freedom, and consensual pleasure

---

## 💬 Support & Community

<div align="center">

[![Repository](https://img.shields.io/badge/🐙_Repository-dev.pivoine.art-FF69B4?style=for-the-badge&labelColor=8B008B)](https://dev.pivoine.art/valknar/sexy)
[![Issues](https://img.shields.io/badge/🐛_Issues-Report_Here-DA70D6?style=for-the-badge&labelColor=8B008B)](https://dev.pivoine.art/valknar/sexy/issues)
[![Website](https://img.shields.io/badge/🌐_Website-Visit_Here-FF1493?style=for-the-badge&labelColor=8B008B)](https://pivoine.art)

</div>

---

<div align="center">

### 🍑 Made with 💜 for Freedom, Pleasure & Technology 🍑

<pre>
 ██████╗ ███████╗██╗  ██╗██╗   ██╗
██╔════╝ ██╔════╝╚██╗██╔╝╚██╗ ██╔╝
╚█████╗  █████╗   ╚███╔╝  ╚████╔╝
 ╚═══██╗ ██╔══╝   ██╔██╗   ╚██╔╝
██████╔╝ ███████╗██╔╝╚██╗   ██║
╚═════╝  ╚══════╝╚═╝  ╚═╝   ╚═╝
</pre>

_Pleasure is a human right. Technology is freedom. Together, they are power._

**[pivoine.art](https://pivoine.art)** | © 2026 Palina & Valknar

</div>
