started using Claude Code

This commit is contained in:
Gavin McDonald
2025-10-14 18:15:41 -04:00
parent 070abb6b2e
commit 679c7c75d8
2 changed files with 436 additions and 0 deletions

152
CLAUDE.md Normal file
View File

@@ -0,0 +1,152 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Labelmaker is a Phoenix LiveView web application that generates text-based images via URL. Users can visit `labelmaker.xyz/Your Text` to instantly get an image with their text, with various customization options (font, color, outline, size). The app is designed for creating decals in Tabletop Simulator.
## Technology Stack
- **Elixir + Phoenix Framework** (Phoenix 1.7+ with LiveView)
- **ImageMagick** (`magick` command) for image generation
- **Tailwind CSS** for styling
- **esbuild** for JavaScript bundling
## Common Commands
### Development
```sh
# Install dependencies and set up assets
mix setup
# Start Phoenix server (runs on http://localhost:4000)
mix phx.server
# Start server with interactive Elixir shell
iex -S mix phx.server
```
### Testing
```sh
# Run all tests
mix test
# Run a specific test file
mix test test/labelmaker_web/controllers/label_controller_test.exs
# Run a specific test
mix test test/labelmaker_web/controllers/label_controller_test.exs:42
```
### Assets
```sh
# Install asset build tools (Tailwind, esbuild)
mix assets.setup
# Build assets for development
mix assets.build
# Build assets for production (minified + digest)
mix assets.deploy
```
### Docker
```sh
docker build -t labelmaker .
docker run -p 4000:4000 labelmaker
```
## Architecture
### Request Flow
1. **Homepage (`/`)**: `LabelmakerWeb.Home` LiveView provides an interactive form where users can preview text with different styling options
2. **Image Generation (`/:label`)**: `LabelmakerWeb.LabelController.show/2` handles dynamic image generation
### Core Components
**`LabelmakerWeb.LabelController`** (lib/labelmaker_web/controllers/label_controller.ex)
- Main entry point for image generation requests
- Takes URL path (label text) and query parameters (color, font, outline, size, width, height, align)
- Generates SHA256 hash from parameters to create unique filename for caching
- Checks if cached image exists; if not, builds ImageMagick command and generates image
- Stores generated images in `priv/static/labels/`
- Returns image as PNG response
**`LabelmakerWeb.Tools`** (lib/labelmaker_web/tools.ex)
- Contains parameter processing and validation logic
- `process_parameters/1`: Validates and normalizes user input against permitted values
- Handles two sizing modes:
- **Font mode** (default): Uses `label:` with `-pointsize` for natural text sizing
- **Width x Height mode**: Uses `caption:` with `-size WxH` for fixed dimensions
- `generate_link/1`: Creates URLs based on current parameters and sizing mode
- `process_label/1`: Handles `\n` to actual newline conversion for multi-line labels
- Input validation: filters colors, fonts, sizes, outlines against permitted lists
**`LabelmakerWeb.Constants`** (lib/labelmaker_web/constants.ex)
- Single source of truth for all permitted values and defaults
- Defines available colors, fonts, sizes, alignments
- Font map supports shortcuts (e.g., "h" → "Helvetica", "cs" → "Comic-Sans-MS")
- Max dimensions: 1024x1024 pixels
- Max label length: 1024 characters
- Available fonts: Comic Sans, Courier, Georgia, Helvetica, Impact, Verdana
**`LabelmakerWeb.Home`** (lib/labelmaker_web/live/home.ex)
- LiveView for homepage with interactive preview
- Handles real-time updates via `handle_event/3`:
- `update_label`: Updates label text and styling parameters
- `update_preview`: Changes preview background (gradient/solid)
- `update_sizing`: Toggles between font size mode and width×height mode
- `update_alignment`: Changes text alignment (left/center/right)
- Redirects to `/:label` route when user submits the form
**`LabelmakerWeb.RadioComponent`** (lib/labelmaker_web/live/components/radio_component.ex)
- Reusable Phoenix Component for radio button groups
- Used in the homepage form for alignment selection
### ImageMagick Command Construction
The controller builds ImageMagick commands programmatically:
1. **Basic settings**: background, fill color, font
2. **Outline settings**: stroke color and width (if not "none")
3. **Size settings**: Either pointsize + `label:` OR width×height + `caption:`
4. **Final settings**: Adds metadata comment and output filepath
Example generated command:
```sh
magick -background none -fill black -font Helvetica -stroke white -strokewidth 1 -pointsize 72 label:Hello World output.png
```
### Sizing Modes
The app supports two distinct sizing modes (controlled by `sizing` parameter):
- **Font mode** (`sizing=font`): ImageMagick calculates image size based on font size; natural text rendering
- **Width × Height mode** (`sizing=wxh`): Fixed canvas dimensions with text wrapped/aligned within bounds
### Parameter Processing
All parameters flow through `Tools.process_parameters/1`:
1. Merge with defaults from `Constants.defaults()`
2. Process label (convert `\n` escapes)
3. Validate each parameter against permitted lists
4. Filter out invalid values
5. Calculate derived values (preview_height, rows, link)
6. Return merged map with all parameters
### Caching Strategy
Images are cached using SHA256 hash of the processed options map:
- Hash includes: label, color, font, outline, size, width, height, align
- Cached files stored in `priv/static/labels/`
- Before generating, checks if file exists
- No expiration mechanism (cache persists until manually cleared)
## Important Notes
- **ImageMagick dependency**: The `magick` command must be available in PATH
- **Alignment/Gravity mapping**: User-facing "left/center/right" maps to ImageMagick "west/center/east" gravity values (see `Tools.process_gravity/1`)
- **URL escaping**: Special characters in labels must be URL-encoded; `\n` is processed as literal newline
- **Main branch**: This repo uses `trunk` as the main branch (not `main` or `master`)