# Builder Package - Claude Code Guidance

## Overview

The **bongo/builder** package provides a visual page builder with 764+ pre-built HTML/CSS blocks (components, designs, layouts) for Laravel applications. It features file-based storage, a drag-and-drop editor, and comprehensive API endpoints.

**Key Features**:
- File-based block storage with vendor/resource override pattern
- Single polymorphic model handling three types (component, design, layout)
- Admin CRUD interface for block management
- JSON API for frontend integration
- ContentBuilder JS integration for WYSIWYG editing
- Shortcode support for dynamic content

**Dependencies**: PHP 8.2+, Laravel 10+, bongo/framework, bongo/image

**Documentation**:
- [ARCHITECTURE.md](./ARCHITECTURE.md) - Detailed architecture, data flow, class diagrams
- [.cursorrules](./.cursorrules) - Cursor IDE guidance
- [.github/copilot-instructions.md](./.github/copilot-instructions.md) - GitHub Copilot guidance

## Available Commands

### Testing & Code Quality

```bash
# Run tests
vendor/bin/phpunit

# Fix code style
vendor/bin/pint

# Check code style
vendor/bin/pint --test

# Static analysis
vendor/bin/phpstan analyse
```

### Frontend Assets

```bash
# Install dependencies
npm install

# Development build
npm run dev
npm run development

# Watch for changes
npm run watch
npm run watch-poll
npm run hot

# Production build
npm run prod
npm run production
```

### Laravel Commands

```bash
# Publish assets
php artisan vendor:publish --tag=builder:assets --force

# Clear caches
php artisan cache:clear
php artisan route:clear
php artisan view:clear

# Run seeders
php artisan db:seed --class="Bongo\Builder\Seeders\DataSeeder"
```

## Quick Architecture Reference

### Core Components

**BuilderItem Model** (`src/Models/BuilderItem.php`)
- Single model handling component, design, and layout types
- File-based storage (no database)
- Vendor/resource override pattern
- 10-minute cache for file lists

**Facades** (`src/Facades/`)
- `Component::all()` - Access components
- `Design::find($key)` - Access designs
- `Layout::findByCategory($category)` - Access layouts

**Service Provider** (`src/BuilderServiceProvider.php`)
- Extends `AbstractServiceProvider` from bongo/framework
- Registers singleton instances for each type
- Registers global facade aliases
- Publishes frontend assets
- Registers `hasShortCodes` middleware

### File Structure

Each block is stored as:
```
{type}/{category}/{name}/
    ├── index.blade.php    # Template
    └── preview.png        # Thumbnail
```

**Locations**:
- **Vendor**: `vendor/bongo/builder/src/Views/frontend/{type}/` (original)
- **Resource**: `resources/views/vendor/builder/{type}/` (customizations)

### Routes

**API Routes** (auth:sanctum):
- `GET /api/builder` - All components
- `GET /api/builder/designs` - All designs
- `GET /api/builder/icons` - Icon library
- `GET /api/builder/images` - Image library
- `GET /api/builder/files` - File manager
- (16 more endpoints)

**Backend Routes** (auth + employee):
- `/admin/components` - Component CRUD
- `/admin/sections` - Design CRUD
- `/admin/layouts` - Layout CRUD
- `/admin/icons` - Icon library

**Custom Routes** (no auth):
- `GET /api/builder/post` - Blog posts
- `GET /api/builder/review` - Reviews
- `GET /api/builder/form-builder` - Form builder
- (7 more endpoints)

## Key Files

| File Path | Purpose | Key Features |
|-----------|---------|--------------|
| `src/Models/BuilderItem.php` | Core file-based model | Polymorphic (3 types), caching, file operations |
| `src/BuilderServiceProvider.php` | Service provider | Singleton registration, facade aliases, asset publishing |
| `src/Config/builder.php` | Configuration | Paths, categories, 2050+ FontAwesome icons |
| `src/Http/Middleware/HasShortCodes.php` | Shortcode processor | Parses `[component key="..."]` syntax |
| `src/Routes/api.php` | API routes | 11 authenticated endpoints |
| `src/Routes/backend.php` | Admin routes | CRUD routes for 3 types + icons |
| `src/Routes/custom.php` | Public routes | 9 public endpoints (no auth) |
| `src/Facades/ComponentFacade.php` | Component facade | Accessor: `'component'` |
| `src/Facades/DesignFacade.php` | Design facade | Accessor: `'design'` |
| `src/Facades/LayoutFacade.php` | Layout facade | Accessor: `'layout'` |
| `resources/backend/js/contentbuilder/` | ContentBuilder JS | WYSIWYG editor library |
| `resources/backend/sass/editor.scss` | Backend styles | Admin interface styling |
| `resources/frontend/sass/box.scss` | Frontend styles | Public block styling |

## Common Patterns

### Retrieving Blocks

```php
// Get all items
Component::all()                           // Collection
Component::allByCategory()                 // Array keyed by category
Component::allAsJson()                     // JSON string

// Find specific item
Component::find('header-02')               // BuilderItem|null
Component::findOrFail('header-02')         // BuilderItem or 404

// Filter by category
Component::findByCategory('headline')      // Collection

// Get categories
Component::categories()                    // ['slug' => 'Name']
Component::categoriesAsJson()              // JSON string
```

### Creating/Updating Blocks

```php
$component = new BuilderItem('component');
$component->setName('my-block');           // Auto-slugified
$component->setKey('my-block');            // Unique key
$component->setCategory('headline');       // Auto-slugified
$component->setHtml('<div>HTML</div>');
$component->setThumbnail($imageData);      // Binary PNG data
$component->save();                        // Saves to resource path
```

### Deleting Blocks

```php
$component = Component::find('header-02');
$component->delete();                      // Removes resource version only
```

### Rendering Templates

```php
$item->getHtml()                           // Rendered Blade template
$item->getRawHtml()                        // Raw file contents
$item->getThumbnail()                      // Base64-encoded PNG
$item->getRawThumbnail()                   // Binary PNG data
```

### File Paths

```php
$item->getBasePath()                       // Vendor path (original)
$item->getResourcePath()                   // Resource path (customizations)
$item->getAllFiles()                       // Merged array (resource overrides vendor)
```

## Code Style Summary

### Naming Conventions

- **Classes**: PascalCase (`BuilderItem`, `ComponentController`)
- **Methods**: camelCase (`findByCategory`, `allAsJson`)
- **Properties**: camelCase (`$absolutePath`, `$category`)
- **Routes**: kebab-case (`component.index`, `design.create`)
- **Views**: kebab-case folders (`component/headline/header-02/`)
- **Config keys**: snake_case (`component_path`, `backend_css_file`)

### Type Declarations

Always declare return types:

```php
public function all(): Collection
public function categories(): array
public function allAsJson(): false|string
public function find(string $key): mixed
public function save(): void
```

### Error Handling

```php
// Use helper for logging
log_exception($e);

// Use specific exceptions
throw new ComponentException('Component not found');
throw new DesignException('Design not found');

// Use abort for 404s
return $item ?? abort('404');
```

### Path Handling

Always use `DIRECTORY_SEPARATOR`:

```php
$path = $category . DIRECTORY_SEPARATOR . $name;
$this->relativePath = $value . DIRECTORY_SEPARATOR;
```

### Caching

```php
Cache::remember($key, 600, function () {
    // Expensive operations
});

Cache::forget($key);  // Invalidate on mutations
```

## Configuration Options

### Path Configuration

```php
// API endpoint
'api_path' => '/api/builder'

// Asset paths
'vendor_asset_path' => '/vendor'
'backend_asset_path' => '/backend'
'frontend_asset_path' => '/frontend'

// Template paths
'vendor_path' => 'vendor/bongo/builder/src/Views/'
'resource_path' => 'resources/views/vendor/builder/'
'component_path' => 'frontend/component/'
'design_path' => 'frontend/design/'
'layout_path' => 'frontend/layout/'
```

### Route Prefixes

```php
'component_prefix' => 'components'   // /admin/components
'design_prefix' => 'sections'        // /admin/sections
'layout_prefix' => 'layouts'         // /admin/layouts
```

### Categories

**Components** (16 categories):
Achievements, Basic, Buttons, Contact, Custom, Features, Headline, Help/FAQ, Photos, Pricing, Process, Products, Profile, Quotes, Services, Skills

**Designs** (16 categories):
Achievements, Banners, Basic, CTAs, Contact, Features, Headline, Help/FAQ, Photos, Pricing, Process, Products, Profile, Quotes, Services, Skills

**Layouts** (3 categories):
Headers, Headings, Footers

### Icon Libraries

- **Regular Icons**: 160 FontAwesome regular icons
- **Solid Icons**: 1,400 FontAwesome solid icons
- **Brand Icons**: 490 FontAwesome brand icons

Total: **2,050 icons** available

## Integration Points

### Bongo Framework

Extends `AbstractServiceProvider` which provides:
- Auto-registration of config, routes, views, migrations, translations
- Middleware, command, listener, subscriber, composer registration
- Standard route patterns (api, backend, frontend, web, custom)

### Other Bongo Packages

- **bongo/image** - Image library integration
- **bongo/post** - Blog post listings in templates
- **bongo/gallery** - Gallery builder integration
- **bongo/menu** - Menu builder integration
- **bongo/form** - Form builder integration

### ContentBuilder JS

JavaScript WYSIWYG editor in `resources/backend/js/contentbuilder/`:
- Drag-and-drop interface
- Component palette
- Responsive design tools
- Icon library (2,050 FontAwesome icons)

## Environment Variables

```bash
# Asset paths (optional overrides)
VENDOR_ASSET_PATH=/vendor
BACKEND_ASSET_PATH=/backend
FRONTEND_ASSET_PATH=/frontend

# Asset filenames (optional overrides)
BACKEND_CSS_FILE=editor.css
BACKEND_JS_FILE=editor.js
FRONTEND_CSS_FILE=box.css
FRONTEND_JS_FILE=box.js
```

## Common Tasks

### Adding a New Block

1. Create directory: `src/Views/frontend/{type}/{category}/{name}/`
2. Add `index.blade.php` template
3. Add `preview.png` thumbnail
4. Block auto-discovered on next `Component::all()` call

### Adding a New Category

1. Add to config: `config/builder.php` → `{type}_categories`
2. Create directory: `src/Views/frontend/{type}/{category-slug}/`
3. Add blocks following standard structure

### Adding an API Endpoint

1. Create controller in `src/Http/Controllers/Api/`
2. Add route to `src/Routes/api.php` (auth) or `custom.php` (public)
3. Optional: Create view template in `src/Views/api/`

### Compiling Frontend Assets

```bash
npm install           # Install dependencies
npm run dev          # Development build
npm run watch        # Watch for changes
npm run production   # Production build
```

### Publishing Assets to Application

```bash
php artisan vendor:publish --tag=builder:assets --force
```

## Performance Tips

1. **Cache is automatic** - 10-minute TTL, cleared on save/delete
2. **Keep thumbnails small** - Recommended ~1-2KB PNG
3. **Use simple Blade templates** - Minimize logic in blocks
4. **Limit blocks per category** - < 100 for best performance
5. **Use production builds** - `npm run production` for optimized assets
6. **Consider CDN** - For compiled frontend assets

## Security Notes

- API routes require `auth:sanctum` middleware
- Backend routes require `auth` + `employee` middleware
- Custom routes are **public** (no authentication)
- Always validate user input in controllers
- Sanitize HTML before saving to prevent XSS
- Blade auto-escapes output (use `{!! !!}` carefully)
- File operations restricted to resource path only

## Troubleshooting

### Blocks Not Appearing
```bash
# Clear cache
php artisan cache:clear

# Or programmatically
Cache::forget('component_files');
Cache::forget('design_files');
Cache::forget('layout_files');
```

### Routes Not Working
```bash
# Clear route cache
php artisan route:clear

# Check middleware registration
# Verify route prefix in config
```

### Assets Not Compiling
```bash
# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install

# Try verbose build
npm run dev -- --verbose
```

#### `Cannot find module 'webpack/lib/SizeFormatHelpers'` / `Progress Plugin ... unknown property 'name'`

This package uses laravel-mix 6.0.49 (the final 6.x release — there is no newer
major), which is incompatible with the newest webpack 5 releases. The `overrides`
block in `package.json` pins `webpack` to **5.105.4** to avoid two separate breakages:

- **webpack 5.107.0** removed `lib/SizeFormatHelpers.js`, which laravel-mix's
  `BuildOutputPlugin` still `require()`s → `Cannot find module`.
- **webpack 5.106.0** added an apply-time `compiler.hooks.validate` step that
  re-validates `ProgressPlugin` options. The bundled `webpackbar@5.0.2` overwrites
  those options after construction, so the re-validation rejects them with
  `Progress Plugin ... unknown property 'name'`.

5.105.4 is the newest webpack that has `SizeFormatHelpers` **and** lacks the
re-validation. **Do not remove or bump this pin** without re-testing
`npm run production` — `npm update` will otherwise pull a broken webpack.

### Thumbnails Not Displaying

1. Verify `preview.png` exists in block directory
2. Check file format (must be PNG)
3. Recommended size: ~1-2KB

## Important Notes

- Each block **must** have both `index.blade.php` and `preview.png`
- Block names and categories are **auto-slugified** (lowercase, hyphenated)
- Delete operations **only remove from resource path** (vendor versions remain)
- Cache is **automatically cleared** on save/delete operations
- Use shortcodes in templates: `[component key="header-02"]`
- ContentBuilder JS library is fully integrated in backend
- Preview images are **base64-encoded** for display in admin
- Resource path is **automatically created** if it doesn't exist
- Customized blocks **override** vendor blocks with same path

## Quick Reference

### BuilderItem Public Methods

```php
// Retrieval
all(): Collection
allByCategory(): array
allAsJson(): false|string
categories(): array
categoriesAsJson(): false|string
find(string $key): mixed
findOrFail(string $key): mixed
findByCategory(string $category): Collection

// Persistence
save(): void
delete(): void

// Path Operations
getBasePath(): string
getResourcePath(): string
getAllFiles(): array
getVendorFiles(): array
getResourceFiles(): array

// Content Access
getHtml(): ?string
getRawHtml(): ?string
getThumbnail(): ?string
getRawThumbnail(): ?string

// Setters/Getters
getName(): ?string
setName(string $value): void
getKey(): ?string
setKey(string $value): void
getCategory(): ?string
setCategory(string $value): void
setHtml($value): void
setThumbnail($value): void
// ... more path getters/setters
```

### Controller Responsibilities

**API Controllers** (`src/Http/Controllers/Api/`):
- Return JSON or rendered views
- Integrate with other packages
- Provide data for ContentBuilder JS

**Backend Controllers** (`src/Http/Controllers/Backend/`):
- Standard CRUD operations
- Form validation
- File upload handling
- Admin UI rendering

### Middleware

**HasShortCodes** (`hasShortCodes` alias):
- Parses shortcodes in response content
- Format: `[component key="header-02"]`
- Replaces with rendered HTML
- Applied automatically to routes needing shortcode support

---

For detailed architecture information, class diagrams, and data flow, see [ARCHITECTURE.md](./ARCHITECTURE.md).
