Files
sexy/CLAUDE.md
Sebastian Krüger 97269788ee feat: add shared @sexy.pivoine.art/types package and fix type safety across frontend/backend
- Create packages/types with shared TypeScript domain model interfaces (User, Video, Model, Article, Comment, Recording, etc.)
- Wire both frontend and backend packages to use @sexy.pivoine.art/types via workspace:*
- Update backend Pothos objectRef types to use shared interfaces instead of inline types
- Update frontend $lib/types.ts to re-export from shared package
- Fix all type errors introduced by more accurate nullable types (avatar/banner as string|null UUIDs, author nullable, events/device_info as object[])
- Add artist_name to comment user select in backend resolver
- Widen utility function signatures (getAssetUrl, getUserInitials, calcReadingTime) to accept null/undefined

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 11:01:11 +01:00

3.8 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

sexy.pivoine.art is a self-hosted adult content platform (18+) built as a pnpm monorepo with three packages: frontend (SvelteKit 5), backend (Fastify + GraphQL), and buttplug (hardware integration via WebBluetooth/WASM).

Common Commands

Run from the repo root unless otherwise noted.

# Development
pnpm dev:data        # Start postgres & redis via Docker
pnpm dev:backend     # Start backend on http://localhost:4000
pnpm dev             # Start backend + frontend (frontend on :3000)

# Linting & Formatting
pnpm lint            # ESLint across all packages
pnpm lint:fix        # Auto-fix ESLint issues
pnpm format          # Prettier format all files
pnpm format:check    # Check formatting without changes

# Build
pnpm build:frontend  # SvelteKit production build
pnpm build:backend   # Compile backend TypeScript to dist/

# Database migrations (from packages/backend/)
pnpm migrate         # Run pending Drizzle migrations

Architecture

Monorepo Layout

packages/
  frontend/   # SvelteKit 2 + Svelte 5 + Tailwind CSS 4
  backend/    # Fastify v5 + GraphQL Yoga v5 + Drizzle ORM
  buttplug/   # TypeScript/Rust hybrid, compiles to WASM

Backend (packages/backend/src/)

  • index.ts — Fastify server entry: registers plugins (CORS, multipart, static), mounts GraphQL at /graphql, serves transformed assets at /assets/:id
  • graphql/builder.ts — Pothos schema builder (code-first GraphQL)
  • graphql/context.ts — Injects currentUser from Redis session into every request
  • lib/auth.ts — Session management: nanoid(32) token stored in Redis with 24h TTL, set as httpOnly cookie
  • db/schema/ — Drizzle ORM table definitions (users, videos, files, comments, gamification, etc.)
  • migrations/ — SQL migration files managed by Drizzle Kit

Frontend (packages/frontend/src/)

  • lib/api.ts — GraphQL client (graphql-request)
  • lib/services.ts — All API calls (login, videos, comments, models, etc.)
  • lib/types.ts — Shared TypeScript types
  • hooks.server.ts — Auth guard: reads session cookie, fetches me query, redirects if needed
  • routes/ — SvelteKit file-based routing: /, /login, /signup, /me, /models, /models/[slug], /videos, /play/[slug], /magazine, /leaderboard

Asset Pipeline

Backend serves images with server-side Sharp transforms, cached to disk as WebP. Presets: mini (80×80), thumbnail (300×300), preview (800px wide), medium (1400px wide), banner (1600×480 cropped).

Gamification

Points + achievements system tracked in user_points and user_stats tables. Logic in packages/backend/src/lib/gamification.ts and the gamification resolver.

Code Style

  • TypeScript strict mode in all packages
  • ESLint flat config (eslint.config.js at root) — any is allowed but discouraged; enforces consistent type imports
  • Prettier: 2-space indent, trailing commas, 100-char line width, Svelte plugin
  • Migrations folder (packages/backend/src/migrations/) is excluded from lint

Environment Variables (Backend)

Variable Purpose
DATABASE_URL PostgreSQL connection string
REDIS_URL Redis connection string
COOKIE_SECRET Session cookie signing
CORS_ORIGIN Frontend origin URL
UPLOAD_DIR File storage path
SMTP_HOST/PORT/EMAIL_FROM Email (Nodemailer)

Docker

docker compose up -d          # Start all services (postgres, redis, backend, frontend)
arty up -d <service>          # Preferred way to manage containers in this project

Production images are built and pushed to dev.pivoine.art via Gitea Actions on push to main.