# CLAUDE.md

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

## Overview

BlockRegistry is a Laravel module providing ACF-style block management for the MTC Pharmacy platform. It lets admins define reusable content blocks with configurable fields, assign them to page templates, and manage block instances on pages, products, and categories.

## Commands

Migrations live in `database/migrations/` and run via the standard `make migrate` / `php artisan migrate`.

## Architecture

### Bootstrap

The module boots via `BlockRegistryServiceProvider` (registered in `config/app.php`). It registers four service singletons, loads routes and migrations. Legacy hooks in `hooks.php` register Twig functions and add admin tabs.

### Two-Layer Data Model

**Definition layer** — what a block *is*:
- `BlockRegistry` — block definitions (name, slug, icon, optional Twig template path)
- `BlockRegistryField` — field definitions with self-referencing `parent_field_id` for repeater sub-fields
- `BlockRegistryCategory` — organizational grouping
- `BlockRegistryTemplateAssignment` — whitelist of which blocks are available on which page templates (with `is_default` flag for auto-add)
- `BlockRegistryVersion` — audit snapshots of block structure changes

**Instance layer** — block data on a specific entity:
- `EntityBlock` — a block placed on a page/product/category/global, stores field values as JSON in `data` column
- `entity_type` is one of: `page`, `item`, `category`, `global`
- Global blocks (`entity_type=global`, `entity_id=0`) can be referenced from other entities via `source_block_id`

### Services

| Service | Responsibility |
|---------|---------------|
| `BlockRegistryService` | CRUD for block definitions, field management, duplication, validation |
| `EntityBlockService` | Runtime block rendering, data access, Twig function implementations |
| `TemplateBlockService` | Template-to-block assignment management |
| `ImageProcessingService` | Image cropping, srcset generation via Intervention Image v3 (Imagick) |

### Rendering Pipeline

`EntityBlockService::renderBlock()` resolves the block's Twig template (from `BlockRegistry.template` field), prepares template data, and renders via `app('twig')`. The template receives: `block`, `block_name`, `block_slug`, `banner` (field data), `block_data`, `fields` (simple values), `slides` (repeater data), and `p.pagedata` (legacy-compatible format).

Frontend Twig functions (registered in `hooks.php`):
- `render_block(entityBlockId)` — single block
- `render_entity_blocks(entityType, entityId)` — all published blocks for an entity
- `render_blocks_by_type(entityType, entityId, blockSlug)` — filter by block type
- `get_entity_blocks(entityType, entityId)` — raw block data
- `render_global_block(globalBlockId)` — global block by ID

### Admin Routes

All under `/admin/blocks` with `auth` middleware. The controller handles:
- Block definition CRUD (`/`, `/create`, `/{id}/edit`)
- Entity block data editing (`/data/{id}`)
- Global blocks (`/global`, `/global/create`)
- Categories (`/categories`)
- AJAX endpoints for pages (`/ajax/*`) and generic entities (`/ajax/entity/*`) — adding, reordering, toggling status

Admin integration files in `admin/` inject "Blocks" tabs into product, category, and page editors.

### Field Types

`text`, `textarea`, `checkbox`, `select`, `image`, `file`, `gallery`, `datetime`, `colorpicker`, `coordinates`, `tags`, `repeater`

Repeater fields support sub-fields (but not nested repeaters). Image fields support cropping with aspect ratio enforcement, and automatic srcset generation to `/uploads/cache/blocks/{entityBlockId}/`.

### JavaScript

Vanilla JS files in `js/` — no build step, loaded directly in admin templates. Key files: `block-registry-edit.js` (block definition editor), `block-registry-edit-data.js` (data editor with image crop), `block-registry-entity-blocks.js` (AJAX block management on pages/entities), `block-registry-drag.js` (drag-and-drop reordering).

## Key Patterns

- Block definitions auto-generate UUID and slug on create, cascade-delete related data
- EntityBlock auto-sets `order` on create and initializes `data` with field defaults
- Published/draft status filtering — frontend rendering only shows published blocks
- Versioning creates automatic snapshots on block creation and field updates with rollback support
- Image paths are validated against directory traversal in `ImageProcessingService`
