From 94b03b49d91a384f73dbf55edb178681c9ee2cc4 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 12 Jan 2026 19:33:13 +0000 Subject: [PATCH] Add comprehensive Member Editor implementation plan Create detailed plan for building a Member Editor admin interface at /a/members. The plan follows the proven Tag Editor pattern and includes: - Complete route structure for CRUD operations - Full HTML template layout with modals and forms - JavaScript event handlers for edit/delete actions - Integration with existing Member API endpoints - Testing checklist and acceptance criteria All backend infrastructure (API, models, schemas) already exists. This is purely a web UI implementation task estimated at 2-3 hours. --- MEMBER_EDITOR_PLAN.md | 548 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 MEMBER_EDITOR_PLAN.md diff --git a/MEMBER_EDITOR_PLAN.md b/MEMBER_EDITOR_PLAN.md new file mode 100644 index 0000000..51e5dd1 --- /dev/null +++ b/MEMBER_EDITOR_PLAN.md @@ -0,0 +1,548 @@ +# Member Editor Implementation Plan + +## Overview + +Create a Member Editor admin interface at `/a/members` following the proven pattern established by the Tag Editor. All backend API infrastructure already exists; this is purely a web UI implementation. + +## Current State + +### ✅ Already Implemented + +| Component | Status | Location | +|-----------|--------|----------| +| Member Model | ✅ Complete | `common/models/member.py` | +| API Schemas | ✅ Complete | `common/schemas/members.py` | +| API CRUD Endpoints | ✅ Complete | `api/routes/members.py` | +| YAML Import | ✅ Complete | `collector/member_import.py` | +| Public Members Page | ✅ Complete | `web/routes/members.py` | +| Admin Foundation | ✅ Complete | `web/routes/admin.py` | + +### ❌ Missing - To Be Implemented + +1. Admin web routes for Member CRUD at `/a/members` +2. Admin template `admin/members.html` +3. Navigation card in admin index + +## Architecture Reference + +The Member Editor will follow the **exact same pattern** as the Tag Editor: + +``` +User visits /a/members + ↓ +Displays members table with actions + ↓ +User clicks: Create | Edit | Delete + ↓ +Modal opens with form + ↓ +Form submits via POST to /a/members/{action} + ↓ +Backend calls API endpoint + ↓ +Redirects back to /a/members with flash message +``` + +## Implementation Tasks + +### Task 1: Add Admin Web Routes + +**File:** `src/meshcore_hub/web/routes/admin.py` + +Add the following routes following the Tag Editor pattern: + +#### 1.1 Main Members Page (GET) +```python +@router.get("/members", response_class=HTMLResponse) +async def admin_members( + request: Request, + message: Optional[str] = Query(None), + error: Optional[str] = Query(None) +) -> HTMLResponse +``` + +**Responsibilities:** +- Check admin enabled via `_check_admin_enabled(request)` +- Get auth context via `_get_auth_context(request)` +- Fetch all members from `/api/v1/members?limit=1000` +- Sort members by name +- Render `admin/members.html` template + +#### 1.2 Create Member (POST) +```python +@router.post("/members", response_class=RedirectResponse) +async def admin_create_member( + request: Request, + name: str = Form(...), + member_id: str = Form(...), + callsign: Optional[str] = Form(None), + role: Optional[str] = Form(None), + description: Optional[str] = Form(None), + contact: Optional[str] = Form(None) +) -> RedirectResponse +``` + +**Responsibilities:** +- Check admin enabled and require auth +- POST to `/api/v1/members` with form data +- Handle success (201) → redirect with success message +- Handle errors (409 duplicate, 400 validation) → redirect with error +- Use `_build_redirect_url()` helper + +#### 1.3 Update Member (POST) +```python +@router.post("/members/update", response_class=RedirectResponse) +async def admin_update_member( + request: Request, + id: str = Form(...), + name: Optional[str] = Form(None), + member_id: Optional[str] = Form(None), + callsign: Optional[str] = Form(None), + role: Optional[str] = Form(None), + description: Optional[str] = Form(None), + contact: Optional[str] = Form(None) +) -> RedirectResponse +``` + +**Responsibilities:** +- Check admin enabled and require auth +- Build update payload (only non-None fields) +- PUT to `/api/v1/members/{id}` with update data +- Handle success (200) → redirect with success message +- Handle errors (404, 409, 400) → redirect with error + +#### 1.4 Delete Member (POST) +```python +@router.post("/members/delete", response_class=RedirectResponse) +async def admin_delete_member( + request: Request, + id: str = Form(...) +) -> RedirectResponse +``` + +**Responsibilities:** +- Check admin enabled and require auth +- DELETE to `/api/v1/members/{id}` +- Handle success (204) → redirect with success message +- Handle errors (404) → redirect with error + +### Task 2: Create Admin Template + +**File:** `src/meshcore_hub/web/templates/admin/members.html` + +Structure based on `admin/node_tags.html`: + +#### 2.1 Page Layout +```html +{% extends "base.html" %} + +{% block title %}Members - Admin{% endblock %} + +{% block breadcrumb %} + +{% endblock %} + +{% block content %} + + + + +{% endblock %} +``` + +#### 2.2 Flash Messages Section +```html +{% if message %} +
{{ message }}
+{% endif %} + +{% if error %} +
{{ error }}
+{% endif %} +``` + +#### 2.3 Members Table Card +```html +
+
+

Network Members

+ + + + + + + + + + + + + + {% for member in members %} + + + + + + + + + {% else %} + + + + {% endfor %} + +
Member IDNameCallsignRoleContactActions
{{ member.member_id }}{{ member.name }} + {% if member.callsign %} + {{ member.callsign }} + {% endif %} + {{ member.role or '-' }}{{ member.contact or '-' }} + + +
+ No members configured yet +
+
+
+``` + +#### 2.4 Add Member Form Card +```html +
+
+

Add New Member

+ +
+
+
+ + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+
+``` + +#### 2.5 Edit Modal +```html + + + + +``` + +#### 2.6 Delete Modal +```html + + + + +``` + +#### 2.7 JavaScript Event Handlers +```html + +``` + +### Task 3: Update Admin Index + +**File:** `src/meshcore_hub/web/templates/admin/index.html` + +Add a new navigation card for the Member Editor after the existing Node Tags card: + +```html + +
+

+ + + + Members +

+

Manage network members and operators

+
+ +
+
+
+``` + +## Field Descriptions + +### Member Model Fields + +| Field | Type | Required | Description | Example | +|-------|------|----------|-------------|---------| +| `member_id` | string | Yes | Unique identifier for member | `walshie86` | +| `name` | string | Yes | Full display name | `John Smith` | +| `callsign` | string | No | Amateur radio callsign | `VK4ABC` | +| `role` | string | No | Member's role in network | `Network Coordinator` | +| `description` | text | No | Longer description of member | `Manages Brisbane nodes` | +| `contact` | string | No | Contact information | `john@example.com` | + +### Validation Rules + +- `member_id`: 1-50 chars, alphanumeric + underscore only +- `name`: 1-255 chars +- `callsign`: Max 20 chars +- `role`: Max 100 chars +- `contact`: Max 255 chars +- `description`: No limit (TEXT field) + +## Testing Checklist + +### Manual Testing + +- [ ] Access `/a/members` - displays empty state +- [ ] Create new member with all fields +- [ ] Create new member with only required fields +- [ ] Edit member - update single field +- [ ] Edit member - update all fields +- [ ] Delete member - confirm deletion +- [ ] Delete member - cancel deletion +- [ ] Try duplicate member_id - shows error +- [ ] Try empty required fields - shows validation error +- [ ] Verify flash messages appear on success/error +- [ ] Check mobile responsive layout +- [ ] Verify authentication required for POST actions +- [ ] Verify admin disabled shows 404 + +### API Integration Testing + +- [ ] Create via web → verify in API GET +- [ ] Update via web → verify in API GET +- [ ] Delete via web → verify 404 in API GET +- [ ] Check timestamps update correctly + +### UI/UX Testing + +- [ ] Table sorts properly +- [ ] Modals open/close correctly +- [ ] Form validation works +- [ ] Error messages are clear +- [ ] Success messages are clear +- [ ] Layout works on mobile +- [ ] Layout works on tablet +- [ ] Layout works on desktop + +## Acceptance Criteria + +✅ The Member Editor is complete when: + +1. **Create**: Admin can create new members via form +2. **Read**: Admin can view all members in a table +3. **Update**: Admin can edit member fields via modal +4. **Delete**: Admin can delete members with confirmation +5. **Navigation**: Admin index has working Members card +6. **Authentication**: All state-changing operations require auth +7. **Validation**: Form validation matches API schemas +8. **Error Handling**: Clear error messages for failures +9. **Success Feedback**: Flash messages confirm successful actions +10. **Mobile Responsive**: Works on all screen sizes + +## Future Enhancements (Out of Scope) + +- Bulk import members from web UI +- Export members to YAML +- Link member to multiple nodes +- Member activity history +- Search/filter members +- Pagination for large member lists + +## Implementation Order + +1. ✅ Review existing code (Tag Editor + Member API) +2. ⬜ Add admin web routes to `admin.py` +3. ⬜ Create `admin/members.html` template +4. ⬜ Update admin index navigation +5. ⬜ Test CRUD operations +6. ⬜ Test error cases +7. ⬜ Test responsive layout +8. ⬜ Commit and push changes + +## Estimated Complexity + +- **Routes**: Simple (follow existing pattern) +- **Template**: Medium (adapt from node_tags.html) +- **Testing**: Medium (comprehensive testing required) + +**Total Effort**: ~2-3 hours of focused development + +## Related Documentation + +- Tag Editor Reference: `src/meshcore_hub/web/routes/admin.py` (lines for node_tags routes) +- Tag Editor Template: `src/meshcore_hub/web/templates/admin/node_tags.html` +- Member API: `src/meshcore_hub/api/routes/members.py` +- Member Schemas: `src/meshcore_hub/common/schemas/members.py` +- Member Model: `src/meshcore_hub/common/models/member.py`