--- task: Implement COOP_MEMBER and COOP_OFFICER account types with geographic chapter hierarchy cycles: 5 context: true private: false started: 2026-05-28T17:08:44Z finished: 2026-05-28T17:09:30Z --- ## files - `app/Enums/UserTypes.php` — add COOP_MEMBER and COOP_OFFICER cases - `app/Enums/UserActions.php` — add ViewChapterOrgChart, ManageChapterMembers, ViewScopedMemberReports, AssignChapterOfficer - `app/Http/Controllers/Helpers/Permissions/UserPermissions.php` lines 818–838 — add permission sets for new types; update UserTypeService::getAllowedUserTypes - `app/Models/Chapter.php` — add cooperative_id to fillable; add cooperative() relationship - `app/Models/ChapterMember.php` — add role field to fillable; add isOfficer() helper - `database/migrations/2026_04_19_100001_create_chapters_table.php` — reference only, do NOT modify; write new migration instead - `database/migrations/2026_04_19_100002_create_chapter_members_table.php` — reference only; write new migration for role column - `app/Http/Controllers/Market/CooperativeController.php` — update registerMember to set acct_type=COOP_MEMBER if user is currently USER - `app/Http/Controllers/Support/VueRouteMap.php` lines 217–311 — add new chapter pages; update existing coop pages to allow new types - `resources/js/utils/UserTypes.js` — add COOP_MEMBER and COOP_OFFICER constants - `resources/js/composables/Core/useAuth.js` lines 84–133 — add isCoopMember, isCoopOfficer computed properties - `resources/js/Pages/Home.vue` lines 73–111 — add v-else-if blocks for COOP_OFFICER and COOP_MEMBER before the User fallback - `resources/js/Pages/Fragments/Home/HomeCoopOfficer.vue` — NEW: officer dashboard showing chapter org chart + scoped member stats - `resources/js/Pages/Fragments/Home/HomeCoopMember.vue` — NEW: member dashboard showing membership card, chapter info, wallet, marketplace - `resources/js/Pages/ChapterOrgChart.vue` — NEW: org chart page filtered by officer's chapter level/geographic scope - `resources/js/composables/useChapters.js` — may need fetchOfficerScope() method ## steps ### 1. New migration — add cooperative_id to chapters Create `database/migrations/2026_05_28_000001_add_cooperative_id_to_chapters.php`: - `$table->unsignedBigInteger('cooperative_id')->nullable()->after('name');` - `$table->foreign('cooperative_id')->references('id')->on('organizations')->nullOnDelete();` - Add `$table->index('cooperative_id');` - Use Hypervel imports (NOT Illuminate): `use Hyperf\Database\Schema\Blueprint; use Hypervel\Database\Migrations\Migration; use Hypervel\Support\Facades\Schema;` ### 2. New migration — add role to chapter_members Create `database/migrations/2026_05_28_000002_add_role_to_chapter_members.php`: - `$table->string('role')->nullable()->after('position')->comment('Officer role: PRESIDENT, VICE_PRESIDENT, SECRETARY, TREASURER, AUDITOR, BOARD_MEMBER, MEMBER');` - The existing `position` field remains for free-text title; `role` is the canonical enum-like string - Use Hypervel imports ### 3. UserTypes PHP enum — app/Enums/UserTypes.php After `case COORDINATOR = 'coordinator';`, add: ```php case COOP_OFFICER = 'coop officer'; case COOP_MEMBER = 'coop member'; ``` ### 4. UserActions PHP enum — app/Enums/UserActions.php Add after the last existing case: ```php case ViewChapterOrgChart = 'viewchapterorgchart'; case ManageChapterMembers = 'managechaptermembers'; case ViewScopedMemberReports = 'viewscopedmemberreports'; case AssignChapterOfficer = 'assignchapterofficer'; ``` ### 5. UserPermissions — add new type permission sets In `UserPermissions::roles()` after the `UserTypes::USER->value` block (line 818), add: ```php UserTypes::COOP_MEMBER->value => [ UserActions::JoinCooperative, UserActions::ViewUserInfo, UserActions::ManageUserInfo, UserActions::ViewChapterOrgChart, ], UserTypes::COOP_OFFICER->value => [ UserActions::JoinCooperative, UserActions::ViewUserInfo, UserActions::ManageUserInfo, UserActions::ViewOrganizations, UserActions::ViewChapterOrgChart, UserActions::ManageChapterMembers, UserActions::ViewScopedMemberReports, UserActions::AssignChapterOfficer, UserActions::ViewAccountingReports, UserActions::CheckifMobileNumberExists, UserActions::CheckifUsernameExists, ], ``` Also add ViewChapterOrgChart, ManageChapterMembers, ViewScopedMemberReports, AssignChapterOfficer to `$RoleswithNoTargetUser` array. ### 6. UserPermissions — getAllowedUserTypes In `UserTypeService::getAllowedUserTypes()`, add COOP_OFFICER and COOP_MEMBER: - COORDINATOR can create COOP_OFFICER and COOP_MEMBER - COOP_OFFICER can create COOP_MEMBER - ULTIMATE/SUPER_OPERATOR/OPERATOR can create both (already implied by wildcard but add explicitly) ### 7. Chapter model — add cooperative_id In `app/Models/Chapter.php`, add `'cooperative_id'` to `$fillable` and add relationship: ```php public function cooperative() { return $this->belongsTo(\App\Models\Market\Organization::class, 'cooperative_id'); } ``` ### 8. ChapterMember model — add role to fillable In `app/Models/ChapterMember.php`, add `'role'` to `$fillable`. Add helper: ```php public function isOfficer(): bool { return !empty($this->role) && $this->role !== 'MEMBER'; } ``` ### 9. CooperativeController — update registerMember to set acct_type In `CooperativeController@registerMember` (and `publicRegisterMember`), after successfully creating/confirming the `cooperative_members` row, check: ```php if ($user->acct_type === UserTypes::USER) { $user->acct_type = UserTypes::COOP_MEMBER; $user->save(); } ``` This upgrades plain USER accounts to COOP_MEMBER on cooperative registration. Do not downgrade any existing type that is higher (COORDINATOR, OPERATOR, etc.). ### 10. Frontend UserTypes.js In `resources/js/utils/UserTypes.js`, add: ```js COOP_OFFICER: 'coop officer', COOP_MEMBER: 'coop member', ``` ### 11. useAuth.js — add computed helpers In `resources/js/composables/Core/useAuth.js`, after `isUser` (line 113), add: ```js const isCoopOfficer = computed(() => role.value === UserTypes.COOP_OFFICER); const isCoopMember = computed(() => role.value === UserTypes.COOP_MEMBER); ``` Export both from the return object. ### 12. Home.vue — add dashboard fragments for new types Import two new components at top of `