# Phase 1 — Install Instructions

Run these **in order**, in your own terminal, in a fresh Laravel 12 project
(don't install this into the old reference app — this is the new system).

## 0. Create the fresh project (skip if you already have one)
```bash
composer create-project laravel/laravel newerp
cd newerp
```

## 1. Install required packages
```bash
composer require spatie/laravel-permission laravel/sanctum
```

## 2. Copy the files from this delivery into your project
Copy these folders/files from the zip into the matching paths in your project
(they won't overwrite anything in a fresh install):

```
app/Models/Company.php
app/Models/Branch.php
app/Models/Warehouse.php
app/Models/User.php                → overwrite the default one
app/Models/Scopes/CompanyScope.php
app/Traits/BelongsToCompany.php
app/Http/Middleware/EnsureCompanyIsActive.php
app/Http/Middleware/EnsureUserIsActive.php
app/Http/Middleware/SetPermissionsTeamContext.php
app/Policies/CompanyScopedPolicy.php
database/migrations/2026_08_12_*.php   (all 6 files)
database/seeders/RolesAndPermissionsSeeder.php
database/seeders/DemoCompanySeeder.php
```

## 3. Publish Sanctum + Permission migrations
```bash
php artisan install:api
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
```

## 4. Turn on "teams" mode in permissions BEFORE migrating
Open `config/permission.php`, find `'teams'` and `'team_foreign_key'`, set:
```php
'teams' => true,
'team_foreign_key' => 'company_id',
```
(See `config/permission-teams-snippet.php` in this delivery for the exact values.)

This makes every role/permission scoped per-company automatically — without
this step, Company A's "Cashier" role definition would leak into Company B.

## 5. Register middleware
In `bootstrap/app.php`, inside `->withMiddleware(function (Middleware $middleware) {...})` add:
```php
$middleware->alias([
    'company.active' => \App\Http\Middleware\EnsureCompanyIsActive::class,
    'user.active'    => \App\Http\Middleware\EnsureUserIsActive::class,
    'team.context'   => \App\Http\Middleware\SetPermissionsTeamContext::class,
]);

$middleware->appendToGroup('web', [
    \App\Http\Middleware\SetPermissionsTeamContext::class,
]);
```

## 6. Run migrations
```bash
php artisan migrate
```
Expected order: users → cache/jobs → sanctum tokens → companies → branches →
warehouses → tenant columns on users → owner FK → user_branch → permission tables.
If migrate fails on ordering, tell me the exact error — don't reorder files
by guessing, the FK dependencies are deliberate (companies before branches,
users before the owner FK, etc.).

## 7. Seed and test
```bash
php artisan db:seed --class="Database\Seeders\DemoCompanySeeder"
php artisan tinker
```
In tinker:
```php
$u = App\Models\User::first();
$u->company;              // should show "Demo Retail Co"
$u->hasRole('Company Admin'); // should be true (teams context needs setPermissionsTeamId — tinker won't auto-set it, that's expected; it works inside real HTTP requests via the middleware)
```

## What "done" looks like
- Migrations run clean.
- `DemoCompanySeeder` creates a company, branch, warehouse, and admin user with no errors.
- Any query against `Branch::all()` or `Warehouse::all()` run *as an authenticated
  user of a different company* returns zero rows — that's the tenant isolation working.

Report back what happened (clean run, or paste the exact error) and I'll fix
anything before we move to Phase 2 (design system) or Phase 3 (master data:
products, customers, suppliers) — whichever you'd rather do next.
