Files
sexy/CLAUDE.md
Sebastian Krüger ad7ceee5f8 fix: resolve lint errors from ACL/admin implementation
- Remove unused requireOwnerOrAdmin import from videos.ts
- Remove unused requireAuth import from users.ts
- Remove unused GraphQLError import from articles.ts
- Replace URLSearchParams with SvelteURLSearchParams in admin users page
- Apply prettier formatting to all changed files

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

4.0 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.