---
task: In ManageStoresAdmin, show Edit Store and Assign Store (to cooperative) action buttons for store_owner and store_manager accounts when they own/manage the store. Currently only the View button renders because user_can_manage is not returning true reliably for these account types.
cycles: 5
context: true
private: false
started: 2026-05-16T08:19:52Z
finished: 2026-05-16T08:20:30Z
---

## files
- resources/js/Pages/ManageStoresAdmin.vue [lines 1-260] — frontend; canModifyStore checks store.user_can_manage; edit/assign-products/delete buttons already exist behind that guard; needs "Assign to Cooperative" button added
- app/Http/Controllers/Market/StoreController.php [lines 1297-1353] — listStores_Admin; sets user_can_manage dynamically; non-Big3 branch may silently produce false for store_manager accounts linked only through pivot table
- app/Http/Controllers/Support/VueRouteMap.php [lines 137-180] — EditStoreUltimate allowedUserTypes includes 'store owner' but NOT 'store manager'; AddProductsToStore includes both; ManageStoresAdmin includes both
- routes/web.php [lines 519-523] — /Admin/Stores/List route

## steps

### 1. Fix user_can_manage for store_manager accounts (StoreController.php ~line 1319)
The non-Big3 branch fetches managers with `'managers:id,store_id,user_id'` then computes:
```php
$s->user_can_manage = in_array($s->owner_id, $allowedUserIds)
    || in_array($s->manager_id, $allowedUserIds)
    || $s->managers->pluck('user_id')->intersect($allowedUserIds)->isNotEmpty();
```
A store_manager logged in as $user will have $user->id in $allowedUserIds but may only be in the managers pivot (not in manager_id). Verify the `managers` relation is defined on Store model and returns rows correctly. If `$s->managers` is empty due to a missing/wrong relationship, the third condition fails and user_can_manage is false even though the store is shown (it passed the WHERE clause). Fix: ensure the Store model has `managers()` hasMany relationship to store_managers table. If it's missing or uses wrong foreign key, add/fix it.

### 2. Confirm user_can_manage serializes in JSON response
`$s->user_can_manage = value` sets a dynamic Eloquent attribute. Confirm it appears in the JSON response by checking if Store model has a `$visible` whitelist that would block it. If yes, add 'user_can_manage' to $appends or remove the whitelist restriction.

### 3. Add "Assign to Cooperative" button in ManageStoresAdmin.vue (line ~247)
"Assign Store" in context means assigning the store to a cooperative (the Cooperatives column is already displayed in the table). Add a new action button that navigates to EditStoreUltimate (which already has cooperative assignment UI) OR opens a dedicated cooperative-assignment modal. Use `navigate({ page: 'EditStoreUltimate', props: { target: store.hashkey, focus: 'cooperatives' } })` or simply navigate to edit page. Only show if `canModifyStore(store)`. Use icon `fas fa-building` or `fas fa-link` with title "Assign to Cooperative".

```html
<button v-if="canModifyStore(store)"
        @click="navigate({ page: 'EditStoreUltimate', props: { target: store.hashkey } })"
        class="btn btn-sm btn-icon btn-outline-warning"
        title="Assign to Cooperative">
    <i class="fas fa-building"></i>
</button>
```

### 4. Fix EditStoreUltimate allowedUserTypes to include store_manager (VueRouteMap.php line 139)
Currently `allowedUserTypes: ['ult', 'super operator', 'operator', 'store owner']` — missing 'store manager'. A store_manager navigating to EditStoreUltimate will be blocked. Add 'store manager' to the allowedUserTypes array. Confirm the EditStoreUltimate backend route/controller also permits store_manager to edit stores they manage.

### 5. Verify EditStoreUltimate backend allows store_manager
Check the backend controller that handles store edits (likely `StoreController@update` or similar). Ensure it doesn't reject store_manager accounts when they own/manage the target store.

## context

**canModifyStore (ManageStoresAdmin.vue:25-27):**
```js
const canModifyStore = (store) => {
    return !!store.user_can_manage
}
```

**listStores_Admin non-Big3 branch (StoreController.php:1316-1335):**
```php
$allowedUserIds = array_merge([$user->id], $user->getAllDescendants()->pluck('id')->toArray());

$stores = Store::with(['cooperatives:organizations.id,organizations.hashkey,organizations.name', 'managers:id,store_id,user_id'])
    ->select(['id','hashkey','name','category','subcategory','is_active','status','photourl','address','owner_id','manager_id'])
    ->where(function ($q) use ($allowedUserIds) {
        $q->whereIn('owner_id', $allowedUserIds)
          ->orWhereIn('manager_id', $allowedUserIds)
          ->orWhereHas('managers', function ($mq) use ($allowedUserIds) {
              $mq->whereIn('user_id', $allowedUserIds);
          });
    })
    ->orderBy('id', 'desc')
    ->get()
    ->each(function ($s) use ($allowedUserIds) {
        $s->user_can_manage = in_array($s->owner_id, $allowedUserIds)
            || in_array($s->manager_id, $allowedUserIds)
            || $s->managers->pluck('user_id')->intersect($allowedUserIds)->isNotEmpty();
        unset($s->managers);
    });
```

**VueRouteMap allowedUserTypes:**
- ManageStoresAdmin: `['ult', 'super operator', 'operator', 'store owner', 'store manager']` ✓
- EditStoreUltimate: `['ult', 'super operator', 'operator', 'store owner']` ← missing 'store manager'
- AddProductsToStore: `['ult', 'super operator', 'operator', 'store owner', 'store manager']` ✓

**Existing action buttons in template (ManageStoresAdmin.vue:245-256):**
```html
<button @click="viewStore(store)" class="btn btn-sm btn-icon btn-outline-info" title="View in Market">
    <i class="fas fa-eye"></i>
</button>
<button v-if="canModifyStore(store)" @click="navigate({ page: 'AddProductsToStore', props: { target: store.hashkey } })" class="btn btn-sm btn-icon btn-outline-success" title="Assign Products to Store">
    <i class="fas fa-boxes"></i>
</button>
<button v-if="canModifyStore(store)" @click="editStore(store)" class="btn btn-sm btn-icon btn-outline-primary" title="Edit">
    <i class="fas fa-edit"></i>
</button>
<button v-if="canModifyStore(store)" @click="deleteStore(store)" class="btn btn-sm btn-icon btn-outline-danger" title="Delete">
    <i class="fas fa-trash"></i>
</button>
```

## notes
- dictionary: ai-docs/dictionary.md
- linters: phpcs, eslint (check with tsc if TypeScript present — project is mostly JS/Vue/PHP)
- constraints: Store model table name is `str` per project dictionary (use in raw queries/validation). Definition-of-done checklist in CLAUDE.md must be verified before closing.
