# Notch ERP — Module Conventions

Modules live in `/modules/{Name}/` and are auto-discovered by `App\Modules\ModuleManager`
and booted by `App\Providers\ModuleServiceProvider` (only when `enabled` in the `modules` table).

## Directory layout
```
/modules/{Name}/
  module.json
  routes/web.php
  Controllers/
  Models/
  Views/                      ← blade, referenced as {slug}::path.to.view
  database/migrations/
  Providers/{Name}ServiceProvider.php
```

## module.json
```json
{
  "name": "Human Resources",
  "slug": "hr",
  "version": "1.0.0",
  "description": "Employees, attendance, leaves, payroll.",
  "icon": "users",
  "color": "#10b981",
  "core": false,
  "dependencies": [],
  "provider": "Modules\\HR\\Providers\\HRServiceProvider"
}
```

## Namespacing
- PSR-4 root: `Modules\` => `modules/` (configured in composer.json).
- So `modules/HR/Models/Employee.php` => `Modules\HR\Models\Employee`.
- Controllers => `Modules\HR\Controllers\...`.

## Provider
Extend `App\Modules\BaseModuleServiceProvider`. It auto-loads routes/web.php,
Views/ (namespaced under the slug), database/migrations/ and lang/.
Register navigation + permissions inside `registerModule()`:

```php
namespace Modules\HR\Providers;

use App\Modules\BaseModuleServiceProvider;
use App\Providers\CoreServiceProvider;

class HRServiceProvider extends BaseModuleServiceProvider
{
    protected function moduleSlug(): string { return 'hr'; }

    protected function registerModule(): void
    {
        CoreServiceProvider::addNavigation([
            'label' => 'HR', 'icon' => 'users', 'module' => 'hr', 'order' => 20,
            'children' => [
                ['label' => 'Employees', 'route' => 'hr.employees.index', 'permission' => 'hr.employees.view'],
            ],
        ]);
    }
}
```

## Views & layout
- Use the shared layout: `<x-app-layout title="...">...</x-app-layout>`.
- Reference module views as `{slug}::folder.view`, e.g. `view('hr::employees.index')`.
- Tailwind (CDN) + Alpine + Livewire are available globally. Primary color `#6366f1`.
- Use the shared partials/components: `<x-card>`, `<x-page-header>`, `<x-data-table>` where helpful;
  otherwise plain Tailwind matching the existing core pages is fine.

## Routes
Wrap routes in `auth` + permission middleware:
```php
Route::middleware(['auth'])->prefix('hr')->name('hr.')->group(function () {
    Route::get('employees', [EmployeeController::class, 'index'])
        ->name('employees.index')->middleware('permission:hr.employees.view');
});
```

## Permissions
Define permission slugs as `{slug}.{resource}.{action}` and seed them via the
module's migration (insert into `permissions`) or in `registerModule`. The
ModulePermissionSeeder pattern: insert rows into `permissions` with `module = slug`.

## Audit
Add `use App\Support\Concerns\Auditable;` trait to models that should be logged.

## Money / settings
Use `money($amount)` helper and `setting('key', default)`.
