managarten/apps/uload/CLAUDE.md
Till JS d847eb4115 feat(uload): rewrite to local-first + Hono architecture
- Move from apps-archived/ to apps/
- Delete NestJS backend, PocketBase, old scripts and docs
- Create Hono/Bun redirect server (click tracking, analytics API)
- Create @manacore/uload-database shared Drizzle schema package
- Add local-first store (Dexie.js) for links, tags, folders
- Rewrite Links and Tags pages to use IndexedDB
- Simplify hooks, layouts, remove all server-side data loading
- Add dev scripts: dev:uload:web, dev:uload:server, dev:uload:local

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:16:04 +02:00

132 lines
3.4 KiB
Markdown

# 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
```bash
pnpm run dev # Start development server (http://localhost:5173)
pnpm run preview # Preview production build locally
```
### Build & Deploy
```bash
pnpm run build # Create production build
```
### Code Quality
```bash
pnpm run format # Auto-format code with Prettier
pnpm run lint # Run ESLint and Prettier checks
pnpm run check # Run Svelte type checking
```
### Testing
```bash
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
```bash
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
```typescript
// ✅ 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
```typescript
// 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