Files
2025-10-02 19:27:15 -07:00

6.4 KiB

CLAUDE.md

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

Project Overview

FurryPlace is an unofficial open-source backend for wplace (a collaborative pixel art canvas), built with TypeScript, tinyhttp, Prisma, and MySQL. The system manages user authentication, pixel painting with charge-based rate limiting, alliances, leaderboards, and moderation features.

Development Commands

Essential Commands

  • pnpm dev - Run development server with hot reload (watches src/ directory)
  • pnpm build - Compile TypeScript to dist/
  • pnpm start - Run production build from dist/
  • pnpm test - Run tests once
  • pnpm test:watch - Run tests in watch mode
  • pnpm lint - Check for linting issues
  • pnpm lint:fix - Auto-fix linting issues

Database Commands

  • pnpm db:push - Push schema changes to database and regenerate Prisma client
  • pnpm db:generate - Regenerate Prisma client only
  • pnpm db:migrate - Create and run a new migration
  • pnpm seed - Seed database with initial data

Requirements

  • Node.js >= 24
  • pnpm >= 10
  • MySQL/MariaDB

Architecture

Backend Structure

Entry Point: src/index.ts - Sets up tinyhttp app with middleware (CORS, cookie parser, JSON body parsing, logging) and registers all route modules.

Authentication Flow: JWT tokens stored in j cookie → validated by src/middleware/auth.ts → checks session validity in database → attaches req.user with { id, sessionId }

Database: Prisma ORM with MySQL. Global instance exported from src/config/database.ts and injected into request via middleware.

Route Organization: Each feature module exports a function that registers routes on the tinyhttp app:

Service Layer: Business logic isolated in service classes:

  • src/services/pixel.ts - PixelService handles pixel painting with charge validation, color unlocking checks, tile image generation using @napi-rs/canvas, and level calculation
  • src/services/alliance.ts - AllianceService handles alliance creation, member management, bans
  • src/services/user.ts - UserService handles user profile updates, favorites

Core Systems:

  1. Charge System (src/utils/charges.ts): Rate-limiting mechanism where users have maxCharges (default 20) that regenerate every chargesCooldownMs (default 30s). Painting consumes charges. Function calculateChargeRecharge() computes current charge based on time elapsed.

  2. Bitmap System (src/utils/bitmap.ts): WplaceBitMap class stores boolean flags as packed bytes for efficient storage (used for unlocked colors, flags). Stored in database as Bytes, converted to base64 for API responses.

  3. Color Palette (src/utils/colors.ts): Defines available colors with RGB values and whether they're paid. checkColorUnlocked() validates if user has purchased a color by checking bitmap.

  4. Tile System: Canvas divided into 1000x1000 tiles. Each pixel has coordinates (tileX, tileY, x, y). Tile images dynamically generated on-demand from pixel data.

  5. Regions (src/config/regions.ts): Maps coordinates to geographic regions/countries. Users get 10% charge discount when painting in their equipped flag's region. Currently returns placeholder data - implementation needed.

Database Schema

Key models in prisma/schema.prisma:

  • User: Core user data, charge state, pixels painted, level, alliance membership, equipped flag, unlocked colors bitmap
  • Pixel: Individual pixel with coordinates (tileX, tileY, x, y), colorId, paintedBy userId, timestamp
  • Tile: Metadata for 1000x1000 tile regions, has many Pixels
  • Alliance: Groups with members, bans, invites, HQ coordinates, total pixels painted
  • Session: JWT session tracking with expiration
  • Ticket: Moderation reports with evidence
  • UserNote: Moderator notes on users

Frontend

Pre-built SvelteKit frontend in frontend/ directory (served as static files, not part of development workflow). Backend serves 404.html for unmatched routes.

Key Implementation Patterns

  1. Route Pattern: Routes validate input → call service method → return JSON or handle service errors via handleServiceError()

  2. Service Pattern: Services receive Prisma client in constructor, contain business logic, throw descriptive errors that are caught by error handler middleware

  3. Bulk Pixel Insert: Painting uses raw SQL INSERT ... ON DUPLICATE KEY UPDATE for performance when updating multiple pixels

  4. Level Calculation: Math.floor(Math.sqrt(pixelsPainted / 100)) + 1

  5. Validation: Separate validator functions in src/validators/ for common input patterns (seasons, coordinates, pagination)

  6. Error Responses: Standardized via createErrorResponse() and HTTP_STATUS constants in src/utils/response.ts

Environment Setup

Copy .env.example to .env and configure:

  • DATABASE_URL - MySQL connection string (format: mysql://user:password@host/database)
  • JWT_SECRET - Secret key for JWT signing
  • PORT - Server port (default 3000)

Important Notes

  • The project is a work-in-progress with incomplete features (see README.md warnings)
  • Region lookup system is stubbed and returns placeholder data - needs implementation
  • Authentication uses JWT cookies named j
  • All API responses use JSON format
  • The backend is designed to work with the wplace.live frontend protocol
  • Production deployment requires SSL/HTTPS (enforced by design)
  • Use pnpm as package manager (not npm)