managarten/uload/CLAUDE.md
Till-JS c712a2504a feat: integrate uload and picture, unify package naming
- Add uload project with apps/web structure
  - Reorganize from flat to monorepo structure
  - Remove PocketBase binary and local data
  - Update to pnpm and @uload/web namespace

- Add picture project to monorepo
  - Remove embedded git repository

- Unify all package names to @{project}/{app} schema:
  - @maerchenzauber/* (was @storyteller/*)
  - @manacore/* (was manacore-*, manacore)
  - @manadeck/* (was web, backend, manadeck)
  - @memoro/* (was memoro-web, landing, memoro)
  - @picture/* (already unified)
  - @uload/web

- Add convenient dev scripts for all apps:
  - pnpm dev:{project}:web
  - pnpm dev:{project}:landing
  - pnpm dev:{project}:mobile
  - pnpm dev:{project}:backend

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 04:00:36 +01:00

3.4 KiB

CLAUDE.md

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

Project Overview

uLoad is a URL shortener and link management platform built with SvelteKit and PocketBase.

Live: https://ulo.ad

Project Structure

uload/
├── apps/
│   └── web/              # SvelteKit web application
│       ├── src/          # Source code
│       │   ├── routes/   # SvelteKit pages
│       │   └── lib/      # Components, services, utilities
│       ├── static/       # Static assets
│       └── e2e/          # End-to-end tests
├── backend/              # PocketBase configuration
│   ├── pb_migrations/    # Database migrations
│   └── pb_schema.json    # Schema definition
├── docs/                 # Documentation
├── scripts/              # Utility scripts
└── CLAUDE.md

Commands

All commands should be run from uload/apps/web/:

Development

pnpm run dev              # Start development server (http://localhost:5173)
pnpm run preview          # Preview production build locally

Build & Deploy

pnpm run build            # Create production build

Code Quality

pnpm run format           # Auto-format code with Prettier
pnpm run lint             # Run ESLint and Prettier checks
pnpm run check            # Run Svelte type checking

Testing

pnpm run test             # Run all tests (unit + e2e)
pnpm run test:unit        # Run unit tests with Vitest
pnpm run test:e2e         # Run end-to-end tests with Playwright

Database

pnpm run db:generate      # Generate Drizzle migrations
pnpm run db:migrate       # Run migrations
pnpm run db:push          # Push schema changes
pnpm run db:studio        # Open Drizzle Studio

Technology Stack

  • Framework: SvelteKit v2.22 with Svelte 5.0
  • Backend: PocketBase (embedded SQLite)
  • Database: PostgreSQL via Drizzle ORM + Redis for caching
  • Styling: Tailwind CSS v4.0
  • Testing: Vitest + Playwright
  • Payments: Stripe
  • Email: Resend
  • Storage: Cloudflare R2

Key Patterns

Svelte 5 Runes Mode

  • NEVER use $: reactive statements - use $derived instead
  • NEVER use let for reactive values - use $state for reactive state
  • For side effects - use $effect instead of $: statements
// ✅ CORRECT - Svelte 5 runes
let headerModule = $derived(card.config.modules?.find(m => m.type === 'header'));
let count = $state(0);

$effect(() => {
  console.log('Count changed:', count);
});

PocketBase Usage

In server-side code (+page.server.ts, +server.ts):

  • ALWAYS use locals.pb from the request context
  • The imported pb is for client-side only
// Server-side
export const load: PageServerLoad = async ({ locals }) => {
  const items = await locals.pb.collection('items').getList();
}

// Client-side
import { pb } from '$lib/pocketbase';

Environment Configuration

Copy .env.example to .env and configure:

  • DATABASE_URL - PostgreSQL connection string
  • R2_* - Cloudflare R2 storage credentials
  • RESEND_API_KEY - Email service
  • STRIPE_* - Payment processing (see .env.stripe.example)

Code Style

  • Tabs for indentation
  • Single quotes for strings
  • 100 character line width
  • Prettier auto-sorts Tailwind classes