# Remove ReservationCompanion, Add Super-Admin Admin Creation, Clean API Routes

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Remove all remaining `reservationCompanion` references, add a route for super-admins to create admin users, and clean up redundant role-prefixed routes in `routes/api.php`.

**Architecture:** Delete stale test/docs references to the already-dropped `reservation_companions` table; add a dedicated `AdminController::store` under the existing admin route group but restricted to `super_admin`; remove the duplicated owner-prefixed employee update route because a top-level owner|employee route already covers the same controller method.

**Tech Stack:** Laravel 13.x, PHP 8.4, Laravel Sanctum, Spatie Laravel Permission, Pest PHP.

---

## Task 1: Remove ReservationCompanion References

**Files:**
- Modify: `tests/Unit/Authorization/ResourcePoliciesTest.php`
- Modify: `PROJECT_PROGRESS.md`
- Modify: `docs/superpowers/plans/2026-06-22-remaining-fixes-plan.md`

- [ ] **Step 1: Delete the ReservationCompanionPolicy test block**

  In `tests/Unit/Authorization/ResourcePoliciesTest.php`, remove:
  - `use App\Policies\ReservationCompanionPolicy;` import
  - The entire `describe('ReservationCompanionPolicy', function () { ... });` block (lines ~19 and ~319-346)

- [ ] **Step 2: Remove ReservationCompanion mentions from project docs**

  In `PROJECT_PROGRESS.md`, delete or strike through the line referencing `ReservationCompanionController`.

  In `docs/superpowers/plans/2026-06-22-remaining-fixes-plan.md`, remove Task 5 Step 4 and the ReservationCompanion row from the verification table.

- [ ] **Step 3: Verify no source references remain**

  Run:
  ```bash
  grep -ri "ReservationCompanion\|reservation_companion\|reservationCompanion" --include="*.php" --include="*.md" app/ database/ tests/ routes/ docs/ PROJECT_PROGRESS.md || echo "No references found"
  ```

  Expected: Only the drop migration should remain.

- [ ] **Step 4: Commit**

  ```bash
  git add tests/Unit/Authorization/ResourcePoliciesTest.php PROJECT_PROGRESS.md docs/superpowers/plans/2026-06-22-remaining-fixes-plan.md
  git commit -m "chore: remove remaining reservationCompanion references"
  ```

---

## Task 2: Add Super-Admin Admin Creation

**Files:**
- Create: `app/Http/Controllers/Api/Admin/AdminController.php`
- Create: `app/Http/Requests/Auth/RegisterAdminRequest.php`
- Create: `tests/Feature/Admin/AdminCreationTest.php`
- Modify: `routes/api.php`

- [ ] **Step 1: Create the admin registration request**

  Create `app/Http/Requests/Auth/RegisterAdminRequest.php`:

  ```php
  <?php

  namespace App\Http\Requests\Auth;

  use App\Rules\PhoneNumber;
  use Illuminate\Foundation\Http\FormRequest;
  use Illuminate\Validation\Rules\Password;

  class RegisterAdminRequest extends FormRequest
  {
      public function authorize(): bool
      {
          return true;
      }

      public function rules(): array
      {
          return [
              'name' => ['required', 'string', 'max:255'],
              'email' => ['required', 'string', 'email', 'unique:users,email'],
              'phone' => ['required', 'string', 'max:255', 'unique:users,phone', new PhoneNumber],
              'password' => ['required', 'string', Password::default(), 'confirmed'],
          ];
      }
  }
  ```

- [ ] **Step 2: Create the admin controller**

  Create `app/Http/Controllers/Api/Admin/AdminController.php`:

  ```php
  <?php

  namespace App\Http\Controllers\Api\Admin;

  use App\Http\Controllers\Controller;
  use App\Http\Requests\Auth\RegisterAdminRequest;
  use App\Http\Resources\UserResource;
  use App\Models\User;
  use Illuminate\Http\JsonResponse;
  use Illuminate\Support\Facades\Hash;

  class AdminController extends Controller
  {
      public function store(RegisterAdminRequest $request): JsonResponse
      {
          $data = $request->validated();

          $admin = User::create([
              'name' => $data['name'],
              'email' => $data['email'],
              'phone' => $data['phone'],
              'password' => Hash::make($data['password']),
              'is_verified' => true,
          ]);

          $admin->assignRole('admin');

          return response()->json([
              'message' => 'Admin created successfully.',
              'data' => UserResource::make($admin),
          ], 201);
      }
  }
  ```

- [ ] **Step 3: Register the route**

  In `routes/api.php`, add inside the existing admin group (after `Route::get('employees', ...)`):

  ```php
  Route::post('admins', [\App\Http\Controllers\Api\Admin\AdminController::class, 'store'])
      ->middleware('role:super_admin');
  ```

- [ ] **Step 4: Add tests**

  Create `tests/Feature/Admin/AdminCreationTest.php`:

  ```php
  <?php

  use App\Models\User;
  use Database\Seeders\RolesAndPermissionsSeeder;
  use Illuminate\Support\Facades\Hash;

  beforeEach(function () {
      $this->seed(RolesAndPermissionsSeeder::class);
  });

  function adminCreationUser(string $role): array
  {
      $user = User::factory()->create([
          'password' => Hash::make('password'),
          'is_verified' => true,
      ]);
      $user->assignRole($role);

      return [$user, $user->createToken('api-token')->plainTextToken];
  }

  it('allows super admin to create an admin', function () {
      [, $token] = adminCreationUser('super_admin');

      $response = $this->withToken($token)
          ->postJson('/api/v1/admin/admins', [
              'name' => 'New Admin',
              'email' => 'newadmin@example.com',
              'phone' => '+12025550199',
              'password' => 'SecurePassword123!',
              'password_confirmation' => 'SecurePassword123!',
          ]);

      $response->assertCreated()
          ->assertJsonPath('data.email', 'newadmin@example.com');

      expect(User::where('email', 'newadmin@example.com')->first())
          ->isAdmin()->toBeTrue();
  });

  it('forbids regular admin from creating an admin', function () {
      [, $token] = adminCreationUser('admin');

      $this->withToken($token)
          ->postJson('/api/v1/admin/admins', [
              'name' => 'New Admin',
              'email' => 'newadmin2@example.com',
              'phone' => '+12025550198',
              'password' => 'SecurePassword123!',
              'password_confirmation' => 'SecurePassword123!',
          ])
          ->assertForbidden();
  });

  it('forbids non-admin users from creating an admin', function () {
      $owner = User::factory()->create(['is_verified' => true]);
      $owner->assignRole('owner');
      $token = $owner->createToken('api-token')->plainTextToken;

      $this->withToken($token)
          ->postJson('/api/v1/admin/admins', [
              'name' => 'New Admin',
              'email' => 'newadmin3@example.com',
              'phone' => '+12025550197',
              'password' => 'SecurePassword123!',
              'password_confirmation' => 'SecurePassword123!',
          ])
          ->assertForbidden();
  });
  ```

- [ ] **Step 5: Run the new tests**

  Run:
  ```bash
  php artisan test tests/Feature/Admin/AdminCreationTest.php
  ```

  Expected: PASS

- [ ] **Step 6: Commit**

  ```bash
  git add app/Http/Controllers/Api/Admin/AdminController.php app/Http/Requests/Auth/RegisterAdminRequest.php tests/Feature/Admin/AdminCreationTest.php routes/api.php
  git commit -m "feat(admin): allow super-admins to create admin users"
  ```

---

## Task 3: Clean Redundant Owner-Prefixed Route

**Files:**
- Modify: `routes/api.php`

- [ ] **Step 1: Remove duplicated owner-prefixed employee update**

  In `routes/api.php`, inside the owner group, the `can:manage_employees` block currently contains:

  ```php
  Route::apiResource('employees', EmployeeController::class)->except(['update']);
  Route::put('employees/{employee}', [EmployeeController::class, 'update']);
  ```

  Remove the second line. The top-level route at line 67 (`PUT /api/v1/employees/{employee}`, middleware `role:owner|employee`) already handles employee updates.

  After the change the block should be:

  ```php
  Route::middleware('can:manage_employees')->group(function () {
      Route::apiResource('employees', EmployeeController::class)->except(['update']);
  });
  ```

- [ ] **Step 2: Verify route list**

  Run:
  ```bash
  php artisan route:list | grep employees
  ```

  Expected: no `PUT /api/v1/owner/employees/{employee}` entry; `PUT /api/v1/employees/{employee}` remains.

- [ ] **Step 3: Run employee tests**

  Run:
  ```bash
  php artisan test tests/Feature/Owner/EmployeeUpdateTest.php
  ```

  Expected: PASS

- [ ] **Step 4: Commit**

  ```bash
  git add routes/api.php
  git commit -m "refactor(routes): remove duplicated owner-prefixed employee update route"
  ```

---

## Task 4: Final Verification

- [ ] **Step 1: Run targeted tests**

  ```bash
  php artisan test tests/Unit/Authorization/ResourcePoliciesTest.php tests/Feature/Owner/EmployeeUpdateTest.php tests/Feature/Admin/AdminCreationTest.php tests/Feature/Authorization/RouteMiddlewareTest.php
  ```

  Expected: PASS

- [ ] **Step 2: Run Pint**

  ```bash
  vendor/bin/pint
  ```

- [ ] **Step 3: Final grep check**

  ```bash
  grep -ri "ReservationCompanion\|reservation_companion\|reservationCompanion" --include="*.php" --include="*.md" app/ database/ tests/ routes/ docs/ PROJECT_PROGRESS.md || echo "Clean"
  ```

  Expected: Only the drop migration remains.
