# Bongo Document Package - Cursor Rules

## Project Overview

This is a Laravel package for managing document uploads (PDF, Office documents, images) within the Bongo framework ecosystem. It provides file upload, storage management, and document metadata tracking with UUID-based access.

**Package**: `bongo/document`
**Namespace**: `Bongo\Document`
**Dependencies**: `bongo/framework` ^3.0, PHP >=8.2, Laravel ^10.0

## Project Structure

```
src/
├── Actions/
│   └── MakeSureUploadsDirectoryExists.php  # Ensures upload directory exists
├── Config/
│   └── document.php                         # Configuration for paths and file types
├── Http/
│   ├── Controllers/
│   │   ├── Api/DocumentController.php       # API endpoints (CRUD)
│   │   └── Backend/DocumentController.php   # Admin interface endpoints
│   └── Requests/
│       └── StoreDocumentRequest.php         # Upload validation
├── Migrations/
│   └── 2021_01_01_000001_create_documents_table.php
├── Models/
│   └── Document.php                         # Main model with UUID, soft deletes
├── Routes/
│   ├── api.php                              # API routes (auth:sanctum)
│   └── backend.php                          # Admin routes (auth + employee)
├── Seeders/
│   └── PackageSeeder.php                    # Registers package in system
├── Translations/
│   └── en/document.php                      # English translations
├── Views/
│   └── backend/
│       └── index.blade.php                  # Vue component integration
└── DocumentServiceProvider.php              # Extends AbstractServiceProvider
tests/
└── TestCase.php                             # Orchestra Testbench setup
```

## Architecture Patterns

### Service Provider

Extends `Bongo\Framework\Providers\AbstractServiceProvider` which auto-bootstraps:
- **Config**: `src/Config/document.php` → `config('document.*')`
- **Routes**: Automatically registered from `src/Routes/`
- **Views**: Namespace `document::` → `src/Views/document/`
- **Migrations**: Auto-discovered and registered
- **Translations**: Namespace `document::` → `src/Translations/`

```php
class DocumentServiceProvider extends AbstractServiceProvider
{
    protected string $module = 'document'; // Required property
}
```

### Route Organization

**Backend Routes** (`src/Routes/backend.php`):
- Prefix: `/admin/documents`
- Route names: `backend.document.*`
- Middleware: `auth`, `employee` (applied automatically)
- Routes: `index`, `show/{uuid}`, `download/{uuid}`

**API Routes** (`src/Routes/api.php`):
- Prefix: `/api/documents`
- Route names: `api.document.*`
- Middleware: `auth:sanctum` (applied automatically)
- Routes: `index` (GET), `store` (POST), `destroy` (POST)

### Model Architecture

**Document Model** (`src/Models/Document.php`):
- Extends: `Bongo\Framework\Models\AbstractModel`
- Traits: `HasUUID`, `SoftDeletes`
- Primary key: `id` (auto-increment)
- UUID: Used for public-facing routes (security)
- Fillable: `name`, `title`, `path`, `ext`, `size`, `type`, `sort_order`, `created_by`, `updated_by`
- Appended attributes: `src` (full URL via `Storage::url()`)
- Computed attributes: `file_path` (combines path + name)

### Actions Pattern

Single-purpose action class for directory management:
```php
(new MakeSureUploadsDirectoryExists())->execute();
```
- Handles both local and remote storage drivers
- Called before any upload operation

## Coding Conventions

### File Upload Flow

1. **Request validation**: `StoreDocumentRequest` validates file type and size
2. **Directory creation**: `MakeSureUploadsDirectoryExists` action
3. **Filename generation**: Slug original name + uniqid + extension
4. **Storage**: `storePubliclyAs()` to configured path
5. **Record creation**: Save metadata to `documents` table

### Configuration Usage

Always use config values, never hardcode paths:
```php
config('document.public_path')        // 'public/'
config('document.tmp_path')           // 'public/tmp/'
config('document.allowed_document_types')  // MIME types string
```

### UUID Access Pattern

Public routes use UUID instead of ID for security:
```php
Document::where('uuid', $uuid)->firstOrFail();
```

### Storage Patterns

**File path construction**:
```php
$document->file_path  // Accessor: path + name
$document->src        // Accessor: full URL via Storage::url()
```

**Storage operations**:
```php
Storage::exists($document->file_path)
Storage::delete($document->file_path)
Storage::download($document->file_path)
```

### Return Type Declarations

Always declare return types:
```php
public function index(): JsonResponse
public function show($uuid)  // Legacy, should be RedirectResponse
public function isPdf(): bool
public function getSrcAttribute(): string
```

### Naming Conventions

- **Controllers**: Singular (DocumentController)
- **Models**: Singular (Document)
- **Tables**: Plural (documents)
- **Routes**: Plural prefix (documents), singular name (document.*)
- **Actions**: Imperative verb phrase (MakeSureUploadsDirectoryExists)

## Common Tasks

### Adding a New Document Type

1. Update `src/Config/document.php` → `allowed_document_types`
2. Test with `StoreDocumentRequest` validation

### Adding a New Route

**Backend route**:
```php
// src/Routes/backend.php
Route::get('custom/{uuid}', [DocumentController::class, 'custom'])
    ->name('custom');
```

**API route**:
```php
// src/Routes/api.php
Route::post('bulk-upload', [DocumentController::class, 'bulkUpload'])
    ->name('bulk-upload');
```

### Adding a Model Scope

```php
// src/Models/Document.php
public function scopeByExtension($query, string $ext)
{
    return $query->where('ext', $ext);
}

// Usage
Document::byExtension('pdf')->get();
```

### Adding a New Action

```php
// src/Actions/GenerateThumbnail.php
namespace Bongo\Document\Actions;

class GenerateThumbnail
{
    public function execute(Document $document): void
    {
        // Implementation
    }
}
```

### Adding Translations

```php
// src/Translations/en/document.php
return [
    'bulk_upload_success' => 'Documents successfully uploaded!',
];

// Usage in blade
@lang('document::document.bulk_upload_success')
```

## Testing

### Running Tests

```bash
vendor/bin/phpunit
```

### Test Structure

Tests use Orchestra Testbench:
```php
class MyTest extends \Bongo\Document\Tests\TestCase
{
    public function test_example()
    {
        // Test implementation
    }
}
```

### Configuration in Tests

TestCase automatically loads DocumentServiceProvider.

## Code Quality

### Laravel Pint

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

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

### Standards

- PSR-12 coding standard
- Laravel preset
- Strict types declaration (preferred but not enforced)

## Dependencies

### Bongo Framework Integration

This package depends on `bongo/framework` for:
- `AbstractServiceProvider` - Auto-bootstrapping
- `AbstractModel` - Base model functionality
- `AbstractController` - Backend controllers
- `AbstractApiController` - API controllers
- `HasUUID` trait - UUID generation

### Helper Functions

Framework provides helpers:
```php
user()  // Get current authenticated user
```

## Frontend Integration

### Vue Component

The backend view integrates a Vue component:
```blade
<document-manager
    index-url="{{ route('api.document.index') }}"
    store-url="{{ route('api.document.store') }}"
    show-url="{{ route('backend.document.show') }}"
    download-url="{{ route('backend.document.download') }}"
    delete-url="{{ route('api.document.destroy') }}"
></document-manager>
```

The component is provided by the framework/frontend system.

## Database Schema

**documents table**:
- `id` - Auto-increment primary key
- `uuid` - Unique identifier for public access
- `name` - Filename with extension
- `title` - Display title
- `path` - Storage directory path
- `ext` - File extension
- `size` - File size in bytes
- `type` - Document type/category
- `sort_order` - Optional ordering
- `created_by`, `updated_by`, `deleted_by` - Audit fields
- `timestamps`, `deleted_at` - Laravel timestamps

## Security Considerations

1. **UUID access**: Public routes use UUID, not sequential IDs
2. **File validation**: Type and size validated via StoreDocumentRequest
3. **Auth middleware**: Backend requires `auth` + `employee`, API requires `auth:sanctum`
4. **Storage security**: Files stored in configured storage disk
5. **Soft deletes**: Documents can be recovered after deletion

## Key Files Reference

| File | Purpose |
|------|---------|
| `src/DocumentServiceProvider.php` | Service provider (minimal, uses AbstractServiceProvider) |
| `src/Models/Document.php` | Main model with UUID, soft deletes, accessors |
| `src/Http/Controllers/Api/DocumentController.php` | API CRUD operations |
| `src/Http/Controllers/Backend/DocumentController.php` | Admin view/download |
| `src/Actions/MakeSureUploadsDirectoryExists.php` | Ensures upload directory |
| `src/Http/Requests/StoreDocumentRequest.php` | Upload validation |
| `src/Config/document.php` | Configuration (paths, allowed types) |

## Commands

From `composer.json`:
```bash
composer test      # Run PHPUnit tests
composer lint      # Check code style
composer fix       # Fix code style
```
