# Cursor Rules for bongo/package

## Project Overview
This Laravel package provides package management functionality for the Bongo framework. It enables tracking, loading, and managing packages within the system through a database-driven registry.

## Package Structure

```
src/
├── PackageServiceProvider.php        # Main service provider
├── Models/
│   └── Package.php                   # Package model with status/type/visibility
├── Services/
│   └── PackageManager.php            # Singleton service for package operations
├── Traits/
│   ├── HasType.php                   # Type scopes (standard/extended/custom)
│   └── SeedsPackage.php              # Helper for seeding package records
├── Migrations/
│   └── 2018_01_30_000001_create_packages_table.php
└── helpers.php                       # Global package() helper function
```

## Architecture Patterns

### Service Provider (PackageServiceProvider)
- Extends `Bongo\Framework\Providers\AbstractServiceProvider`
- Module name: `package` (used for automatic bootstrapping)
- Registers `PackageManager` as a singleton bound to `package_manager`
- Loads helper functions after app boot using `$this->app->booted()`

### Package Model
- Extends `Bongo\Framework\Models\AbstractModel`
- Uses framework traits: `HasKey`, `HasStatus`, `HasUUID`, `HasVisible`
- Uses package-specific trait: `HasType`
- Three package types: standard (vendor/bongo/*), extended, custom (app/*)
- Three status states: pending, active, inactive
- Visibility flag: visible (1) or hidden (0)
- Computed attributes: directory, namespace, service_provider, service_provider_file_path
- Dynamic URL generation via `getUrl()` checking route existence

### PackageManager Service
- Singleton service accessed via `app('package_manager')` or `package()` helper
- Loads all packages on construction with permanent caching (`Cache::rememberForever`)
- Methods:
  - `has(string $key): bool` - Check if package exists
  - `get(string $key): Package` - Get package by key
  - `all(): Collection` - Get all packages
  - `allActive(): array` - Get active + visible packages
  - `isEnabled(string $key): bool` - Check if package is active

## Constants

### Package Model Constants
```php
Package::VENDOR_NAME = 'bongo'
Package::VENDOR_FOLDER = 'vendor'

// Status
Package::PENDING = 'pending'
Package::ACTIVE = 'active'
Package::INACTIVE = 'inactive'

// Visibility
Package::VISIBLE = 1
Package::HIDDEN = 0

// Type
Package::STANDARD = 'standard'  // vendor/bongo packages
Package::EXTENDED = 'extended'
Package::CUSTOM = 'custom'      // app-level packages
```

## Database Schema

### packages table
- `id` - Auto-increment primary key
- `uuid` - UUID indexed
- `name` - Package name (e.g., "framework", "asset")
- `key` - Unique key (nullable, indexed)
- `route` - Route prefix for package (nullable)
- `icon` - Icon class/identifier (nullable)
- `status` - Enum: pending|active|inactive (default: pending)
- `type` - Enum: standard|extended|custom (default: standard)
- `is_visible` - Unsigned tiny int: 1|0 (default: 1)
- `created_at`, `updated_at`, `deleted_at` - Timestamps with soft deletes

## Coding Conventions

### Naming Conventions
- Models use singular names: `Package`
- Services use `Manager` suffix: `PackageManager`
- Traits describe capability: `HasType`, `SeedsPackage`
- Constants use UPPER_SNAKE_CASE
- Methods use camelCase with type hints

### Method Return Types
- Always declare return types on public methods
- Use bool for existence/status checks
- Use string for computed attributes
- Use Collection or array for multi-item returns
- Use nullable return types where appropriate: `?string`

### Code Style
- PHP 8.2+ syntax
- Strict types not enforced (package doesn't use declare(strict_types=1))
- Laravel 10+ conventions
- Use null coalescing operator for defaults: `$params['route'] ?? null`
- Prefer explicit comparisons: `$this->type === self::STANDARD`

## Common Tasks

### Check if a Package is Enabled
```php
if (package()->isEnabled('framework')) {
    // Package is active
}
```

### Get Package URL
```php
$package = package()->get('cms-page');
$url = $package->getUrl(); // Returns route URL or '#'
```

### Get All Active Packages
```php
$activePackages = package()->allActive();
```

### Seed Package Data (in Seeder)
```php
use Bongo\Package\Traits\SeedsPackage;

class PackageSeeder extends Seeder
{
    use SeedsPackage;

    public function run()
    {
        $this->package([
            'name' => 'framework',
            'route' => 'backend.framework',
            'icon' => 'fa-cog',
            'status' => Package::ACTIVE,
            'type' => Package::STANDARD,
            'is_visible' => Package::VISIBLE,
        ]);
    }
}
```

### Query Packages by Type
```php
Package::standard()->get();    // vendor/bongo/* packages
Package::extended()->get();    // Extended packages
Package::custom()->get();      // app/* packages
```

## Testing

### Running Tests
```bash
vendor/bin/phpunit
```

### Test Configuration
- Tests extend `Bongo\Package\Tests\TestCase`
- TestCase extends `Orchestra\Testbench\TestCase`
- Registers `PackageServiceProvider` automatically
- Uses SQLite in-memory database (DB_CONNECTION=testing)

## Important Notes

### Cache Management
- PackageManager caches all packages permanently on construction
- To clear package cache after database changes:
  ```php
  Cache::forget('packages');
  ```
- Consider adding cache clearing to package update operations

### Package Directory Resolution
- Standard packages → `base_path('vendor/bongo/{name}')`
- Extended/Custom packages → `app_path()`
- Service provider path: `{directory}{namespace}/{ServiceProvider}.php`

### No Configuration File
- Package does not include `src/Config/package.php`
- No publishable configuration needed
- All settings stored in database

### Framework Dependencies
- Requires `bongo/framework` ^3.0
- Uses framework's AbstractModel, AbstractServiceProvider
- Uses framework traits: HasKey, HasStatus, HasUUID, HasVisible

## Code Quality Commands

### Laravel Pint
```bash
# Check style issues
vendor/bin/pint --test

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

### Static Analysis
```bash
vendor/bin/phpstan analyse
```

## Extension Points

### Adding New Package Types
1. Add constant to `Package` model
2. Add enum value to migration (requires new migration)
3. Add scope methods to `HasType` trait
4. Update seeder methods if needed

### Custom Package Queries
Add scope methods to `Package` model or extend `PackageManager` service

### Additional Package Attributes
1. Add column to packages table via migration
2. Add to `$fillable` array in Package model
3. Create accessor if computed value needed
