# Maestro CORE

Composer package **`maestro/core`** and npm package **`@maestro/core`**: a Laravel + Vue + PrimeVue SPA foundation for internal applications (auth session API, organization profile, users & roles with Spatie Permission, activity log route, shared layout and settings shell).

## Requirements

- PHP **8.3+**
- Laravel **13+** (via your host application)
- Node **20+** recommended for the SPA toolchain

## Create a new Laravel project

```bash
laravel new my-app --no-interaction --no-migration
cd my-app

composer config repositories.maestro composer http://maestro-packages.build2connect.nl
composer config secure-http false

composer require maestro/core
php artisan core:install

# Register host custom layer (once) in app/Providers/AppServiceProvider.php:
# $this->app->register(\App\Providers\CustomServiceProvider::class);

# 1) Base install: CORE tables + default users/navigation/module rows
php artisan migrate
php artisan db:seed

npm install
npm run dev
```

Then open Superadmin and enable the modules you want to use. After enabling modules, run migrations and seeders again so enabled modules can add their tables/default data:

```bash
# 2) After module activation in Superadmin
php artisan migrate
php artisan db:seed
```

Use Superadmin -> Installation health and Superadmin -> Modules to verify migration/seeding state per module.

Use a thin `App\Models\User` that extends `Maestro\Core\Models\User` (see [`stubs/app/Models/User.php`](stubs/app/Models/User.php)). Your `auth.providers.users.model` must stay in sync with route model binding so Spatie `model_has_roles.model_type` matches the logged-in user class.

### Microsoft SSO (optional)

Entra ID (Azure AD) sign-in uses Laravel Socialite and `socialiteproviders/microsoft`. Set `MICROSOFT_*` and `FRONTEND_URL` in `.env` (see `.env.example`). Users must already exist in your database with `microsoft_user_id` set to their Azure object id (oid); unknown accounts are rejected (no just-in-time provisioning).

Register **one** SPA catch-all in the host app ([`stubs/routes/web.php`](stubs/routes/web.php)); this package intentionally does **not** register a duplicate global `/{any?}` (see [`routes/core.php`](routes/core.php)).

Bootstrap the frontend from your managed `resources/js/app.js` (imports host `resources/js/maestro/boot.js`):

```javascript
import { bootCore } from "@maestro/core";
import { configureCustomApp } from "./maestro/boot.js";
bootCore(configureCustomApp).catch(console.error);
```

### Host custom layer

Project-specific features live in the **custom zone** (never overwritten by `core:install --force`):

| Area | Path |
|------|------|
| PHP | `app/Custom/Features/{Name}/` |
| Routes | `routes/custom/{kebab}.php` |
| Vue | `resources/js/modules/custom/{kebab}/` |
| SPA boot | `resources/js/maestro/boot.js` |
| Seeders | `database/seeders/CustomDatabaseSeeder.php` → feature seeders |
| Config | `config/custom.php` |

Scaffold a feature:

```bash
php artisan make:custom-feature Reservations --slug=my_reservations --api-prefix=reservations
```

Use folder name **`custom`** — not `customer` (conflicts with the CORE Customers module). Cursor: `.cursor/rules/maestro-host-custom-code.mdc` (published on install).

### Public Vue page on `/` (host project)

`php artisan core:install` now publishes a managed `routes/public.php` with a CORE controller-backed root route:

```php
Route::get('/', PublicHomeController::class)->name('public.home');
```

The route behavior is controlled in Superadmin -> Public homepage via `rootMode`:

- `login`: `/` redirects to `/auth/login`
- `dashboard`: `/` redirects to `/dashboard`
- `public`: `/` renders the CORE public homepage Blade + Vue mount

The installer also publishes `resources/js/public-home.js`. It mounts the shared core helper:

```javascript
import { mountPublicHome } from "@maestro/core";

void mountPublicHome().catch(console.error);
```

For a host-specific UI, switch mode to `customer_override` and edit `resources/js/maestro/publicHome.vue` (`resources/js/public-home.js` imports it when override mode is active).

## Develop this repository

```bash
composer install
npm install
composer test     # PHPUnit (Orchestra Testbench + Feature tests)
composer run check-style   # Pint
npm run build   # package asset build
```

## Release

[`release.sh`](release.sh) bumps Composer and npm versions, commits, tags, pushes, runs `npm publish`, and rebuilds Satis on the configured Forge host. Use `npm run release` for an interactive patch/minor/major prompt, or pass a bump/version explicitly.

### 1) Get the latest dependencies in this repository

```bash
composer install
npm install
```

### 2) Run a new release

```bash
npm run release
# Prompts: patch, minor, or major
```

```bash
# Or pass explicitly:
npm run release -- patch
npm run release -- minor
npm run release -- major

# Or set an exact version:
npm run release -- 1.0.71
```

### 3) Get the latest version in customer projects

```bash
composer update maestro/core
npm update @maestro/core
php artisan core:install --force
rm -rf node_modules/.vite
npm run dev
```

`--force` refreshes **managed** shells only (`app.js`, `DatabaseSeeder.php`, `vite.config.js`, …). Host code under `app/Custom/`, `CustomDatabaseSeeder`, and `resources/js/maestro/` is preserved. Use `--republish-config` only when you intend to reset `config/core.php` from the package.

## License

MIT
