# Bongo Framework - Cursor AI Rules

## Project Overview

**Bongo Framework** is the core foundation package for the Bongo Laravel monorepo system. It provides the base architecture that all other Bongo packages extend, including the AbstractServiceProvider for automatic bootstrapping, AbstractModel with audit traits, reusable model traits, custom casts and enums, Schema.org structured data generation, helper classes, and comprehensive middleware.

**Key Technologies**: PHP 8.2+, Laravel 10+, Spatie Schema.org, Maatwebsite Excel

## Package Information

- **Name**: bongo/framework
- **Type**: Core Laravel package (foundation for all Bongo packages)
- **Namespace**: `Bongo\Framework`
- **Repository**: https://bitbucket.org/designtec/framework
- **Private Composer Repository**: https://designtecpackages.co.uk

## Architecture

### Directory Structure

```
src/
├── Casts/              # Custom Eloquent attribute casts (12 casts)
├── Config/             # Package configurations
│   ├── cloudflare.php
│   ├── developer.php
│   ├── schema.php
│   └── settings.php
├── Console/            # Artisan commands
├── Enums/              # PHP 8.1+ enums with array interfaces
├── Events/             # Event classes
├── Exceptions/         # Custom exceptions
├── Helpers/            # Helper classes (13 helpers)
├── Http/
│   ├── Controllers/    # Abstract controller base classes
│   ├── Middleware/     # Framework middleware (11 middleware)
│   └── ViewComposers/  # View composers
├── Interfaces/         # Contracts
├── Migrations/         # Database migrations (4 tables)
├── Models/             # AbstractModel base class
├── Providers/          # Service providers
│   ├── AbstractServiceProvider.php (KEY - extended by all packages)
│   ├── AuthServiceProvider.php
│   ├── EventServiceProvider.php
│   └── RouteServiceProvider.php
├── Schema/             # Schema.org graph generation
│   └── Concerns/       # Schema graph traits
├── Traits/             # Reusable model traits (37 traits)
│   ├── Address/        # Address-related traits
│   ├── Audit/          # Audit trail traits
│   └── Contact/        # Contact information traits
├── Views/              # Blade templates
├── FrameworkServiceProvider.php (Main service provider)
└── helpers.php         # Global helper functions
```

### Key Classes & Their Purposes

#### Core Service Provider Architecture

**`AbstractServiceProvider`** (`src/Providers/AbstractServiceProvider.php`)
- Base class that ALL Bongo packages must extend
- Provides automatic bootstrapping via the `boot()` method
- Requires: `protected string $module` property (must match config filename and view namespace)
- Auto-registers via protected arrays:
  - `$commands` - Console commands
  - `$composers` - View composers
  - `$listeners` - Event listeners (event => [listener1, listener2])
  - `$subscribers` - Event subscribers
  - `$middlewares` - Route middleware (alias => class)

**Route Registration Pattern** (automatic in AbstractServiceProvider):
- `src/Routes/api.php` → `api.*` prefix, `auth:sanctum` middleware, `/api` URL prefix
- `src/Routes/backend.php` → `backend.*` prefix, `auth + employee` middleware, `/admin` URL prefix
- `src/Routes/frontend.php` → `frontend.*` named routes, `web` middleware
- `src/Routes/web.php` → Standard web routes, `web` middleware
- `src/Routes/custom.php` → No middleware or session (for payment webhooks, external callbacks)

**`FrameworkServiceProvider`** (`src/FrameworkServiceProvider.php`)
- Main entry point for the framework
- Extends AbstractServiceProvider
- Orchestrates loading of all Bongo packages
- Handles installation flow detection
- Registers package manager for conditional loading
- Boots flash response macros (success, error, warning, info, danger)
- Configures trusted proxies for Cloudflare
- Sets up MySQL default string length (191)
- Prevents lazy loading in non-production environments

#### Model Architecture

**`AbstractModel`** (`src/Models/AbstractModel.php`)
- Base class for all Bongo models
- Includes audit traits by default:
  - `HasCreatedAt`, `HasCreatedBy`
  - `HasUpdatedAt`, `HasUpdatedBy`
  - `HasDeletedAt`, `HasDeletedBy`
  - `HasDiff` - Track changes between saves
- Method: `attributeExists(string $key): bool` - Check if attribute exists

**Reusable Traits** (37 traits available):
- **Audit Traits** (`src/Traits/Audit/`): Automatic created_by, updated_by, deleted_by tracking
- **Contact Traits** (`src/Traits/Contact/`): Email, phone, mobile, social, marketing preferences
- **Address Traits** (`src/Traits/Address/`): Postcode, latitude, longitude
- **SEO**: `HasSeo` - Auto-generates slug, meta_title, meta_description on save
- **Hierarchy**: `HasRecursive` - Parent/child/sibling relationships with nested loading
- **UI**: `HasHeaderClass`, `HasVisible`, `HasDate`, `HasStatus`, `HasKey`

#### Controller Architecture

**`AbstractController`** (`src/Http/Controllers/AbstractController.php`)
- Base controller with `AuthorizesRequests` and `ValidatesRequests` traits

**`AbstractDatatableController`** (`src/Http/Controllers/AbstractDatatableController.php`)
- For building DataTables-compatible JSON API endpoints
- Flow: `setup()` → `applyFilters()` → `applySearchQuery()` → `applyOrderBy()` → `runQuery()`
- Override: `getBaseQuery()` - Define the base Eloquent query
- Override: `applyFilters()` - Add custom filters
- Returns: JSON with `results` and `totalResults`

**`AbstractApiController`** (`src/Http/Controllers/AbstractApiController.php`)
- Base for API controllers with standardized JSON responses

#### Helper Classes (13 available)

Located in `src/Helpers/`, all have static methods:

- **SEO**: Generate Schema.org meta graphs for pages/posts/projects
- **Str**: String manipulation (`camelWords()`, `key()`, `id()`)
- **Route**: Route utilities (`exists()`, `is()`)
- **URL**: URL manipulation helpers
- **File**: File handling utilities
- **CloudFlare**: Cloudflare API integration
- **Cookie**: Cookie consent helpers
- **Password**: Secure password generation
- **Html**: HTML manipulation
- **ShortCode**: Process custom shortcodes
- **Tax**: Tax calculation utilities
- **Console**: CLI output formatting
- **Log**: Enhanced logging with exception handling

Global helper functions in `src/helpers.php`:
- `user()` - Get authenticated user
- `route_exists()`, `route_is()` - Route checking
- `camel_words()`, `make_key()`, `make_id()` - String utilities
- `generate_password()` - Secure password generation
- `log_exception()` - Exception logging
- `cookie_enabled()` - Check cookie consent
- `plain_text()`, `encode_uri_component()` - Text processing

#### Custom Casts (12 available)

Located in `src/Casts/`, implement `CastsAttributes`:

- **Encoded**: HTML entity encoding/decoding
- **PlainText**: Strip tags on set
- **PlainWords**: Extract plain words
- **PlainNumber**: Extract numbers only
- **PlainLowerText**: Lowercase plain text
- **PlainUpperText**: Uppercase plain text
- **Date**, **DateTime**, **Time**: Date/time formatting
- **Pence**: Store as pence (integer), return as pounds (float)
- **Domain**: Domain normalization
- **Checkbox**: Boolean checkbox handling

#### Enums (5 available)

PHP 8.1+ backed enums in `src/Enums/`:

**`BooleanEnum`** (int backed):
```php
case YES = 1;
case NO = 0;
```

**`StatusEnum`** (int backed):
```php
case ACTIVE = 1;
case DISABLED = 0;
```

Both implement:
- `ArrayInterface` - `toArray()` for select dropdowns
- `DefaultInterface` - `getDefault()` for default values
- Use `WithArray` trait for automatic array conversion

#### Schema.org Graph Generation

**`MetaSchema`** (`src/Schema/MetaSchema.php`) - Entry point for SEO graphs
- `graphForPage(Model $entity): string` - WebPage schema
- `graphForPost(Model $entity): string` - BlogPost schema
- `graphForProject(Model $entity): string` - Article schema

**Graph Classes** (`src/Schema/`):
- `PageGraph`, `PostGraph`, `ProjectGraph` - Entity-specific graphs
- Uses concerns from `src/Schema/Concerns/` for reusable schema components

**Schema Concerns** (20 available):
- `HandlesWebPage`, `HandlesBlogPost`, `HandlesArticle`
- `HandlesWebSite`, `HandlesLocalBusiness`, `HandlesOrganization`
- `HandlesSocialLinks`, `HandlesReviews`, `HandlesContactPoint`
- `HandlesPostalAddress`, `HandlesGeoCoordinates`, `HandlesPlace`
- `HandlesAuthor`, `HandlesFounder`, `HandlesEntity`
- `HandlesReferenceIds`, `HandlesOutput`

Usage:
```php
// In your blade template
{!! SEO::getMetaSchemaForPage($page) !!}
{!! SEO::getMetaSchemaForPost($post) !!}
{!! SEO::getMetaSchemaForProject($project) !!}
```

#### Middleware (11 available)

Key middleware in `src/Http/Middleware/`:
- **MinifyHtml**: Minify HTML output (enabled via config)
- **NoIndex**: Add noindex meta tag for admin/API routes
- Plus Laravel defaults: Authenticate, EncryptCookies, VerifyCsrfToken, TrimStrings, etc.

## How to Extend This Package

### Creating a New Bongo Package

1. **Create Service Provider** extending `AbstractServiceProvider`:

```php
namespace Bongo\MyPackage;

use Bongo\Framework\Providers\AbstractServiceProvider;

class MyPackageServiceProvider extends AbstractServiceProvider
{
    protected string $module = 'mypackage'; // Must match config file name

    protected array $middlewares = [
        'myMiddleware' => MyMiddleware::class,
    ];

    protected array $commands = [
        MyCommand::class,
    ];

    protected array $listeners = [
        MyEvent::class => [
            MyEventListener::class,
        ],
    ];

    protected array $composers = [
        MyComposer::class => [
            'mypackage::view.name',
        ],
    ];
}
```

2. **Create Config**: `src/Config/mypackage.php`
3. **Create Routes**: `src/Routes/backend.php`, `src/Routes/frontend.php`, etc.
4. **Create Views**: `src/Views/{module}/` (auto-loaded with namespace `mypackage::`)
5. **Create Migrations**: `src/Migrations/` (auto-loaded)
6. **Create Models** extending `AbstractModel`
7. **Create Controllers** extending `AbstractController` or `AbstractDatatableController`

### Using Framework Traits

```php
use Bongo\Framework\Models\AbstractModel;
use Bongo\Framework\Traits\HasSeo;
use Bongo\Framework\Traits\HasRecursive;
use Bongo\Framework\Traits\HasStatus;

class MyModel extends AbstractModel
{
    use HasSeo;      // Auto-generates: slug, meta_title, meta_description
    use HasRecursive; // Adds: parent/child relationships
    use HasStatus;    // Adds: status field with StatusEnum

    protected $fillable = ['name', 'content', 'status'];
}
```

### Using Custom Casts

```php
use Bongo\Framework\Casts\Encoded;
use Bongo\Framework\Casts\Pence;
use Bongo\Framework\Enums\BooleanEnum;
use Bongo\Framework\Enums\StatusEnum;

class MyModel extends AbstractModel
{
    protected $casts = [
        'description' => Encoded::class,       // HTML encode/decode
        'price' => Pence::class,               // Store as pence, return as pounds
        'is_featured' => BooleanEnum::class,   // 0/1 as enum
        'status' => StatusEnum::class,         // 0/1 as enum
    ];
}
```

### Building DataTable Endpoints

```php
use Bongo\Framework\Http\Controllers\AbstractDatatableController;

class MyDatatableController extends AbstractDatatableController
{
    protected function getBaseQuery()
    {
        return MyModel::query();
    }

    protected function applyFilters()
    {
        parent::applyFilters(); // status & type filters

        if ($category = $this->request->get('category')) {
            $this->query->where('category_id', $category);
        }
    }
}
```

## Configuration

**`config/settings.php`** - Main framework settings:
- `api_prefix`: API route prefix (default: 'api')
- `backend_prefix`: Admin route prefix (default: 'admin')
- `cache_default`: Default cache TTL in seconds (default: 300)
- `memory_limit`: PHP memory limit (default: '2048M')
- `install_complete`: Installation flag
- `minify_html_enabled`: Enable HTML minification
- `mail_from_name`, `mail_from_address`: Email defaults

**`config/schema.php`** - Schema.org configuration for structured data

**`config/cloudflare.php`** - Cloudflare integration settings

**`config/developer.php`** - Developer-specific settings

## Development Commands

### Testing
```bash
vendor/bin/phpunit
```

### Code Style
```bash
# Check style issues
vendor/bin/pint --test

# Fix style issues
vendor/bin/pint
```

### Dependencies
```bash
# Update dependencies
rm -f composer.lock && composer update -W

# Install dependencies
composer install
```

## Coding Conventions

### PHP Version & Style
- **PHP 8.2+** required
- Use `declare(strict_types=1);` for new files
- Laravel Pint for code style (Laravel preset)
- Type hints on all method parameters and return types
- Use PHP 8.1+ enums instead of constants

### Naming Conventions
- **Classes**: PascalCase (e.g., `AbstractServiceProvider`)
- **Methods**: camelCase (e.g., `getBaseQuery()`)
- **Properties**: camelCase (e.g., `$module`)
- **Database**: snake_case (e.g., `created_at`, `parent_id`)
- **Routes**: Prefix with module name (e.g., `backend.mypackage.index`)
- **Views**: Module namespace (e.g., `mypackage::backend.index`)
- **Config**: Module name (e.g., `config('mypackage.setting')`)

### Service Provider Pattern
- Always extend `AbstractServiceProvider`
- Set `$module` property (required)
- Use protected arrays for registration (`$middlewares`, `$commands`, etc.)
- No manual route registration needed (automatic via AbstractServiceProvider)
- Config files must match `$module` property name

### Model Pattern
- Extend `AbstractModel` for automatic audit trails
- Use framework traits for common functionality
- Use custom casts for data transformation
- Use enums for status/boolean fields
- Type cast relationships with return types

### Controller Pattern
- Extend `AbstractController` for standard controllers
- Extend `AbstractDatatableController` for DataTables endpoints
- Override `getBaseQuery()` and `applyFilters()` in datatables
- Use dependency injection in constructors
- Return typed responses (views, redirects, JSON)

### Middleware Registration
```php
protected array $middlewares = [
    'aliasName' => MiddlewareClass::class,
];
```

## Common Tasks

### Add a New Model Trait

1. Create trait in `src/Traits/MyTrait.php`
2. Add `initializeMyTrait()` for mergeFillable if needed
3. Use trait in models
4. Document in this file

### Add a New Custom Cast

1. Create cast in `src/Casts/MyCast.php`
2. Implement `CastsAttributes` interface
3. Define `get()` and `set()` methods
4. Use in model `$casts` array

### Add a New Enum

1. Create enum in `src/Enums/MyEnum.php`
2. Use backed enum (`: int` or `: string`)
3. Implement `ArrayInterface` and `DefaultInterface`
4. Use `WithArray` trait
5. Define cases and `getDefault()` method

### Add Schema.org Support for New Entity

1. Create graph class in `src/Schema/MyGraph.php`
2. Use concerns from `src/Schema/Concerns/`
3. Add method to `MetaSchema` class
4. Use in blade templates via `SEO::getMetaSchemaForMy($entity)`

### Register a New Package in Framework

1. Add to `loadCoreProviders()` if core package
2. Add to `loadPackages()` if standard package
3. Add to conditional loading if optional package
4. Ensure package extends `AbstractServiceProvider`

## Package Dependencies

**Runtime Dependencies:**
- `illuminate/contracts: ^10.0`
- `spatie/schema-org: ^3.23` - Schema.org structured data
- `maatwebsite/excel: ^3.1` - Excel export functionality

**Dev Dependencies:**
- `laravel/pint: ^1.0` - Code style fixer
- `orchestra/testbench: ^8.0` - Testing framework
- `phpunit/phpunit: ^10.0` - Unit testing
- `nunomaduro/collision: ^7.9` - CLI error reporting
- `nunomaduro/larastan: ^2.0.1` - Static analysis

## Testing

- Test files in `tests/Feature/` and `tests/Unit/`
- Extends Orchestra Testbench for package testing
- Run tests: `vendor/bin/phpunit`
- Test case base: `Bongo\Framework\Tests\TestCase`

## Important Notes

- This is the **foundation package** - all other Bongo packages depend on it
- Routes are auto-registered - never manually register routes in extending packages
- The `$module` property is **required** in all service providers
- Config files must match the `$module` property name
- View namespace is automatically set to `$module` value
- Migrations are auto-loaded from `src/Migrations/`
- Always use `AbstractModel` for audit trail functionality
- Use enums instead of magic numbers/strings
- Schema.org graphs use fluent method chaining
- Package manager controls conditional loading of optional packages
- Installation flow bypasses normal boot when `install_complete` is false

## Global Aliases

Registered via AliasLoader in FrameworkServiceProvider:
- `BooleanEnum` → `Bongo\Framework\Enums\BooleanEnum`
- `StatusEnum` → `Bongo\Framework\Enums\StatusEnum`
- `SEO` → `Bongo\Framework\Helpers\SEO`

## Related Documentation

- Main monorepo: `/CLAUDE.md`
- AbstractServiceProvider: Core of all Bongo packages
- See individual package documentation for usage examples
