# Skyltvaruhuset Plugin — CLAUDE.md

## Project Overview

A WordPress plugin powering a sign design studio (Skyltvaruhuset). It provides a canvas-based design tool for customers to create custom signs, with file upload, pricing, preview generation, and order management.

## Architecture

### Entry Point
- `skyltvaruhuset.php` — Main plugin file. Registers all REST API routes, enqueues scripts/styles, and bootstraps the plugin.

### REST API Routes
All routes are registered in `skyltvaruhuset.php`:
- `skyltar/v1/*` — Public design tool endpoints (price, upload, user images, symbols, etc.)
- `adm_skyltar/v1/*` — Admin symbol management
- `adm_order/v1/*` — Order management
- `adm_cart/v1/*` — Cart operations
- `signstudio/v1/*` — Sign studio endpoints
- `admin/v1/*` — Admin utilities (price algo, templates, etc.)

**Authentication:** Most `skyltar/v1` endpoints use `validate_rest` (requires `X-WP-Nonce` header with `wp_rest` nonce). Admin routes use `validate_admin_nonce`.

### PHP Backend (`assets/classes/`)
| File | Purpose |
|------|---------|
| `FileUploader.php` | Handles file uploads (jpg, png, svg, pdf, eps, ai, webp). Uses strategy pattern per file type. Sanitizes SVGs, generates thumbnails. |
| `SvgProcessing.php` | SVG pre-processing: unique ID/class prefixing, SVGO optimization |
| `ImageQualityAssessor.php` | Assesses DPI/quality of uploaded images |
| `ThumbnailManager.php` | Thumbnail generation |
| `GenerateProductionFile.php` | Generates production-ready PDF/SVG files for orders |
| `preview.php` | Sign preview generation |
| `price.php` / `PriceAlgoGenClass.php` | Pricing logic |
| `sign.php` / `load_sign.php` | Sign data loading |
| `get_user_images.php` / `handle_user_images.php` | User image management |
| `SymbolManager.php` / `get_symbols.php` | Symbol library management |
| `cart.php` / `order.php` | Cart and order handling |

### Frontend (`assets/ts/` → compiled to `assets/js/`)
- `designtool_fabric5.ts` — Main design tool (Fabric.js v5 canvas). Contains `APIClient`, `UploadsManager`, sign operations, UI management.
- `designtool_fabric_quick.ts` — Lightweight quick-design variant.

**Build:** TypeScript compiled with `tsc`. Run `npm run build` or `npm run watch`.

**Key frontend classes:**
- `APIClient` — All REST API calls. Uses jQuery AJAX. Nonce passed via `X-WP-Nonce` header.
- `UploadsManager` — Manages user image uploads and gallery.

### Database Tables
Created in `install/table_creation.php`:
- `{prefix}user_images` — Uploaded user images (path, thumbnail, quality data, etc.)
- Other custom tables for signs, sessions, etc.

## Development Workflow

### TypeScript Build
```bash
npm run build    # one-time compile
npm run watch    # watch mode
```
Output: `assets/ts/*.ts` → `assets/js/*.js` (+ `.js.map`)

### Cache Busting
Script/style version is controlled by `SIGNSTUDIOS_CACHE_VERSION` constant in `skyltvaruhuset.php`. Increment when deploying JS/CSS changes.

### Key Constants
- `SIGNSTUDIOS_PATH` — Plugin directory path
- `SIGNSTUDIOS_URL` — Plugin directory URL
- `SIGNSTUDIOS_CACHE_VERSION` — Current: `1.0.51`

## System Dependencies
The plugin requires these server-side tools (see `readme.md`):
- **Ghostscript** — PDF thumbnail generation
- **Inkscape** — SVG thumbnail generation
- **ImageMagick (Magic)** — Image processing (requires font dir in `type.xml` and `fonts.conf`)
- **pdf2svg** — PDF to SVG conversion
- **Python** — with `numpy`, `matplotlib`, `scikit-learn`, `Pillow`, `PyMuPDF`
- **svgo** / **svgcleaner** — SVG optimization
- **Composer** — PHP dependencies (`enshrined/svg-sanitize`)

## Important Patterns

### API Client `request()` method
When `contentType = 'none'`, the FormData must be assigned to `options.data`. This was a past bug — do not remove the `options.data = data` in the `contentType == 'none'` else branch.

### File Upload Flow
1. Frontend sends `FormData` via POST to `skyltar/v1/user_upload`
2. `handle_user_upload()` → `FileUploader::handle_upload()`
3. `sanitize_file_uploads()` renames file to MD5 hash + original ext
4. File type check against `allowed_file_types()`
5. SVG/PDF/AI/EPS files get a pre-reserved DB row (`reserveDbRowForSvg`)
6. SVGs are sanitized before upload via `sanitizeSvg()`
7. `wp_handle_upload()` moves file to `uploads/user-uploads/{a}/{b}/{c}/`
8. Strategy (`SVGProcessingStrategy`, `StandardProcessingStrategy`, etc.) processes the file
9. `add_to_database()` inserts/updates `user_images` table
10. Response: `{"files": [...], "errors": [...], "success": true/false}`

### Nonce / Auth
- Nonce is generated server-side via `wp_create_nonce('wp_rest')` and localized to JS as `ajaxob.nonce`
- Frontend sends it as `X-WP-Nonce` header on every request
- `validate_rest()` verifies the nonce server-side

## Common Gotchas
- After editing `.ts` files, always recompile and update `SIGNSTUDIOS_CACHE_VERSION` to bust browser cache
- The upload directory structure is `uploads/user-uploads/{char1}/{char2}/{char3}/filename.ext` based on MD5 hash of filename
- SVG sanitization uses `enshrined/svg-sanitize` via Composer — must run `composer install` on new environments
