initial: bootstrap from BukidBountyApp base
This commit is contained in:
77
.claude/plans/9407eb3f723064594aef12202c29e320-complete.md
Normal file
77
.claude/plans/9407eb3f723064594aef12202c29e320-complete.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
task: ManageStoresAdmin page — show Delete and Assign Products actions for STORE_OWNER account type on stores they own
|
||||
cycles: 5
|
||||
context: true
|
||||
private: false
|
||||
started: 2026-05-17T08:00:00Z
|
||||
finished: 2026-05-17T08:01:30Z
|
||||
---
|
||||
|
||||
## files
|
||||
- resources/js/Pages/ManageStoresAdmin.vue [lines 1-28, 88-125, 127-148, 242-263] — main page; action buttons gated by `canModifyStore(store)` → `!!store.user_can_manage`; currently only imports `isUltimate, isSuperOperator, isOperator` from useAuth; does not import `isStoreOwner`
|
||||
- app/Http/Controllers/Market/StoreController.php [lines 1299-1350] — `listStores_Admin`: for non-Big3 users sets `$s->user_can_manage` as dynamic attribute via `->each()`; dynamic Eloquent attributes may not serialize reliably in Hypervel
|
||||
- resources/js/composables/Core/useAuth.js [lines 106, 118-141] — exports `isStoreOwner` computed (role === STORE_OWNER); already available but not used in ManageStoresAdmin
|
||||
|
||||
## steps
|
||||
1. In `ManageStoresAdmin.vue` line 16, add `isStoreOwner` to destructured `useAuth()` return
|
||||
2. In `ManageStoresAdmin.vue`, update `canModifyStore` to also return true when `isStoreOwner.value` AND `store.user_can_manage` is truthy — or add a separate `isOwnerOf(store)` helper that checks `isStoreOwner.value && !!store.user_can_manage` as secondary gate on the action buttons
|
||||
3. In `ManageStoresAdmin.vue` action buttons column (lines 247-254), change the `v-if` on Delete and Assign Products buttons to: `v-if="canModifyStore(store) || isStoreOwner"` is NOT correct (too broad); instead ensure `canModifyStore` works by fixing step 4 below
|
||||
4. In `StoreController.php` `listStores_Admin` (around line 1317 and 1333), replace dynamic attribute assignment `$s->user_can_manage = ...` with `$s->setAttribute('user_can_manage', ...)` to guarantee it lands in the model's `$attributes` array and is included in the JSON response
|
||||
5. Verify `listStores_Admin` correctly includes store owner stores: `$allowedUserIds = [$user->id, ...$user->getAllDescendants()]` — `owner_id` of the store must be in this list for store owners who created stores; no change needed if logic is already correct
|
||||
|
||||
## context
|
||||
**ManageStoresAdmin.vue — useAuth import (line 16):**
|
||||
```js
|
||||
const { isUltimate, isSuperOperator, isOperator, user } = useAuth()
|
||||
// missing: isStoreOwner
|
||||
```
|
||||
|
||||
**canModifyStore function (lines 25-27):**
|
||||
```js
|
||||
const canModifyStore = (store) => {
|
||||
return !!store.user_can_manage
|
||||
}
|
||||
```
|
||||
|
||||
**Action buttons (lines 242-254):**
|
||||
```vue
|
||||
<div class="d-flex justify-content-end gap-2">
|
||||
<button @click="viewStore(store)" ...> <!-- no v-if, always shows -->
|
||||
<button v-if="canModifyStore(store)" @click="navigate({page:'AddProductsToStore',...})"> <!-- Assign Products -->
|
||||
<button v-if="canModifyStore(store)" @click="editStore(store)"> <!-- Edit -->
|
||||
<button v-if="canModifyStore(store)" @click="deleteStore(store)"> <!-- Delete -->
|
||||
</div>
|
||||
```
|
||||
|
||||
**Backend listStores_Admin — non-Big3 path (StoreController.php ~1333):**
|
||||
```php
|
||||
->each(function ($s) use ($allowedUserIds) {
|
||||
$s->user_can_manage = in_array($s->owner_id, $allowedUserIds) // dynamic property — may not serialize
|
||||
|| in_array($s->manager_id, $allowedUserIds)
|
||||
|| $s->managers->pluck('user_id')->intersect($allowedUserIds)->isNotEmpty();
|
||||
unset($s->managers);
|
||||
});
|
||||
```
|
||||
|
||||
Fix: use `setAttribute`:
|
||||
```php
|
||||
$s->setAttribute('user_can_manage',
|
||||
in_array($s->owner_id, $allowedUserIds)
|
||||
|| in_array($s->manager_id, $allowedUserIds)
|
||||
|| $s->managers->pluck('user_id')->intersect($allowedUserIds)->isNotEmpty()
|
||||
);
|
||||
```
|
||||
|
||||
Also fix the Big3 path (~line 1317):
|
||||
```php
|
||||
->each(fn($s) => $s->user_can_manage = true);
|
||||
// change to:
|
||||
->each(fn($s) => $s->setAttribute('user_can_manage', true));
|
||||
```
|
||||
|
||||
## notes
|
||||
- dictionary: none
|
||||
- linters: eslint, tsc (check with `npm run type-check` or `tsc --noEmit` if available)
|
||||
- constraints: Do not change route access control — store owners already have access to `/Admin/Stores/List`, `/Admin/Store/Delete`, `/Admin/Store/ToggleStatus` routes (middleware is only `module:stores`, not role-gated)
|
||||
- The `deleteStore` and `assignProducts` functions in ManageStoresAdmin already handle the STORE_OWNER case correctly via `canModifyStore` guard — no logic change needed there
|
||||
- `MyStores.vue` (at `/my-stores`) is a separate page not linked from HomeStoreOwner; ignore it for this task
|
||||
Reference in New Issue
Block a user