Files
calvana/ADMIN_PANEL_AUDIT.md
Omair Saleh fcfae1c1a4 Ship all P0/P1/P2 gaps + 11 AI features
P0 Critical (7):
- STOP/UNSUBSCRIBE keyword → CANCEL (PECR compliance)
- Rate limiting on pledge creation (10/IP/5min)
- Terms of Service + Privacy Policy pages
- WhatsApp onboarding gate (persistent dashboard banner)
- Demo account seeding (demo@pnpl.app)
- Footer legal links
- Basic accessibility (aria labels on donor flow)

P1 Within 2 Weeks (8):
- Pledge editing by staff (PATCH amount, name, email, phone, rail)
- Donor self-cancel page (/p/cancel) + API
- Donor 'My Pledges' lookup page (/p/my-pledges)
- Bulk QR code download (print-ready HTML)
- Public event progress bar (/e/[slug]/progress)
- Email-only donor handling (honest status + WhatsApp fallback)
- Email verification (format + disposable domain blocking)
- Organisations page rewrite (multi-campaign, not multi-org)

P2 Within First Month (10):
- Event cloning with QR sources
- Account deletion (GDPR Article 17)
- Daily digest cron via WhatsApp
- AI-6 Smart reminder timing (due date anchoring, cultural sensitivity)
- H1 Duplicate donor detection (email, phone, Jaro-Winkler name)
- H5 Bank CSV format presets (10 UK banks)
- H16 Partial payment matching (underpay, overpay, instalment)
- H10 Activity logging (audit trail for staff actions)
- AI nudge endpoint + AI column mapping + AI event setup wizard
- AI anomaly detection wired into daily digest

AI Features (11): smart reconciliation, social proof, auto column mapper,
daily digest, impact storyteller, smart timing, nudge composer, event wizard,
NLU concierge, anomaly detection, bank presets

22 new files, 15 modified files, 0 TypeScript errors, clean build.
2026-03-04 20:10:34 +08:00

287 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CharityRight Admin Panel — Full Audit & Overhaul Plan
**Date:** 4 March 2026
**Auditor:** Claude (via pi)
**Stack:** Laravel 11 + Filament v3.3.26 + PHP 8.3 + DigitalOcean
---
## 1. Current State Inventory
### Navigation Groups & Resources
| Group | Resource | Model | Records | Notes |
|-------|----------|-------|---------|-------|
| **Management** | Customers | Customer | 21,558 | Basic CRUD, no search filters |
| | Users | User | 20,189 | Hidden from Admin role, minimal form |
| | Snowdon Registrations | SnowdonRegistration | 112 | Legacy event, still in nav |
| | Campaign Registrations | CampaignRegistration | 115 | T365/Ramadan, hardcoded title |
| **Donations** | General | Donation | 30,497 | Main donation view, good filters |
| | Scheduled | ScheduledGivingDonation | 2,841 | Separate resource from general |
| | URL Builder | (page) | — | Utility page for donation links |
| **Campaigns** | Appeals | Appeal | 8,914 | Core resource, complex |
| | Approvals | ApprovalQueue | 1,934 | Queue for appeal changes |
| | Scheduled Campaigns | ScheduledGivingCampaign | 3 | Very few records |
| | Words of Hope | WOHMessage | 817 | Form submissions |
| **Allocation** | Donation Items | DonationType | 30 | Hidden from Admin role |
| | Countries | DonationCountry | 12 | Hidden from Admin role |
| | Fund Dimensions | EngageFundDimension | — | N3O Engage sync |
| | Attribution Dimensions | EngageAttributionDimension | — | N3O Engage sync |
| **Misc** | Settings | (page) | — | Global settings, hidden from Admin |
| | Event Logs | EventLog | 2,276,079 | ⚠️ 2.2M rows, no cleanup |
### Roles & Permissions
| Role | Permissions | Can See |
|------|-------------|---------|
| Superadmin | All (via Gate::before) | Everything |
| Admin | Full CRUD on customers, donations, appeals, campaigns | Most things, hidden: Users, Settings, DonationType, DonationCountry |
| Appeal Manager | view/edit/delete appeal | Appeals only |
| Finance Manager | view/edit/delete donation + donation-item | Donations only |
| User | (none) | Nothing in admin |
---
## 2. Critical Issues Found
### 🔴 A. No Dashboard — Zero At-a-Glance Intelligence
The admin panel has **no widgets, no dashboard, no KPIs**. When staff log in they see a blank page with navigation. They have no idea:
- How many donations came in today/this week/this month
- Total revenue
- Active campaigns and their progress
- Pending approvals count
- Failed/errored donations
- Scheduled giving health
### 🔴 B. No Supporter/Care View
There is **zero support workflow**. A support agent can't:
- Search for a donor by email/name/phone and see everything about them in one place
- See a donor's full history (all donations, scheduled giving, appeals, gift aid status)
- Issue refunds or resend receipts easily
- Add notes/tags to a customer record
- Merge duplicate customer records (21K customers vs 20K users = many duplicates)
- See a timeline/activity log for a customer
### 🔴 C. Customer ↔ User Confusion
Two separate models (`User` = login account, `Customer` = donation record) with no unified view. Staff must:
1. Search Users to find the login account
2. Search Customers to find donation records
3. Mentally link them (via `customer.user_id`)
4. No way to see "this person's full picture"
### 🔴 D. Event Logs — 2.2 Million Rows, No Cleanup
`EventLog` table has 2.2M rows with no pruning, no auto-archive, no summary view. This:
- Slows down the admin panel
- Makes the "Event Logs" page unusable (loads millions of rows)
- No alerting on errors
- No way to filter by severity or recent errors only
### 🔴 E. Hardcoded Emails for Export Access
```php
->visible(function () {
$authedEmail = auth()->user()->email;
return $authedEmail == 'omair.saleh@charityright.org.uk' || $authedEmail == 'development@verge.digital';
})
```
Export functionality is locked to specific email addresses instead of using the permission system.
---
## 3. UX Issues
### 🟠 F. Top Navigation is Overcrowded
`->topNavigation()` with 5 groups × 3-5 items = 15+ items in a horizontal bar. With long names like "Scheduled Giving Campaigns", this overflows on most screens. Many items are rarely used (Snowdon Registrations, Fund Dimensions, Attribution Dimensions).
### 🟠 G. Deprecated Code Patterns (Partially Fixed)
- `->reactive()` instead of `->live()` — fixed for Appeal resources, but **DonationResource, CustomerResource, ScheduledGivingDonationResource** still use `->reactive()` and `callable $get`
- `HtmlString` used extensively for simple formatting (should use Filament's native badge/formatting)
### 🟠 H. No Global Search
No `->globalSearch()` configured. Staff can't type a donor email in the search bar and find them. They must navigate to Customers, then search.
### 🟠 I. Donation Edit Form is Read-Only Placeholders
The DonationResource edit form is **entirely Placeholder components** — nothing is actually editable. The form pretends to be an edit page but is really a view page. Should use ViewAction or a proper view page.
### 🟠 J. No Inline Links Between Resources
- Viewing a Donation doesn't link to the Customer
- Viewing a Customer doesn't link to their User account
- Viewing an Appeal doesn't link to the parent appeal in a clickable way
- `view_customer` action exists but has no URL attached
### 🟠 K. Inconsistent Form Patterns
- AppealResource defines the form schema TWICE (in `AppealResource::form()` AND `EditAppeal::form()`) — 100% duplicated
- Some resources use `ViewAction`, others use `EditAction` for the same purpose
- Some tables have bulk actions, others don't
- Inconsistent use of `->collapsible()->collapsed()` vs not
### 🟠 L. Legacy/Dead Resources in Navigation
- **Snowdon Registrations** (112 records, likely a past event)
- **Campaign Registrations** with hardcoded "T365 / Ramadan Challenge" title
- Both clutter the Management group for daily users
---
## 4. Functional Gaps
### 🟡 M. No Refund Workflow
No ability to process or record refunds from the admin panel. Support staff need to go to Stripe dashboard.
### 🟡 N. No Donation Notes/Comments
No way to add internal notes to a donation (e.g., "Donor called, wants to change allocation" or "Refunded via Stripe on 2024-01-15").
### 🟡 O. No Customer Merge Tool
With 21K customers and 20K users, there are certainly duplicates. No tool to merge them.
### 🟡 P. No Scheduled Giving Management
Can't pause, cancel, or modify a scheduled giving subscription from the admin. The edit page exists but fields are placeholder-only.
### 🟡 Q. No Bulk Operations for Appeals
Can't bulk-approve, bulk-reject, or bulk-publish appeals. Approval queue exists but it's a basic list.
### 🟡 R. No Communication/Email Log
No record of emails sent to donors (receipts, confirmations). Can't tell if a receipt was sent or if it bounced.
### 🟡 S. No Gift Aid Reporting
Gift Aid is tracked per donation but there's no aggregated report view for HMRC claims.
### 🟡 T. Missing Filters on Key Resources
- **Customers**: No filters at all (no date range, no donation count, no total donated)
- **Appeals**: No status filter, no date filter, no "has donations" filter
- **Users**: No role filter, no activity filter
---
## 5. Overhaul Plan — Phases
### Phase 1: Dashboard & Navigation (High Impact, Quick Win)
1. **Build a Dashboard** with widgets:
- Today's donations (count + total £)
- This week/month revenue chart
- Pending approvals badge
- Active campaigns progress bars
- Recent errors count (from EventLog)
- Scheduled giving health (active/paused/failed)
2. **Fix Navigation Structure:**
```
Dashboard (home)
├── Supporter Care (new)
│ ├── Donors (unified Customer+User view)
│ └── Donor Lookup (global search page)
├── Donations
│ ├── All Donations
│ ├── Scheduled Giving
│ └── URL Builder
├── Campaigns
│ ├── Appeals
│ ├── Approvals (with badge count)
│ ├── Scheduled Campaigns
│ └── Registrations (merge Snowdon + Campaign)
├── Configuration (collapsible, for admins)
│ ├── Donation Items
│ ├── Countries
│ ├── Fund Dimensions
│ ├── Attribution Dimensions
│ └── Settings
├── Logs & System
│ └── Event Logs (with cleanup)
```
3. **Switch from Top Nav to Sidebar** — Too many items for top nav. Sidebar with collapsible groups is standard for admin panels this size.
4. **Enable Global Search** across Customers, Donations, Appeals.
### Phase 2: Supporter Care Hub (Highest Business Value)
1. **Unified Donor Profile Page** — Single page showing:
- Customer details + linked User account
- All donations (one-off + scheduled) in a timeline
- All appeals they've donated to
- Gift aid status across all donations
- Address history
- Internal notes (new feature)
- Communication log (new feature)
- Quick actions: Send receipt, Add note, View in Stripe
2. **Donor Search Widget** — Search by email, name, phone, donation reference, provider reference. Returns unified results.
3. **Internal Notes System** — Polymorphic `notes` table: add notes to Customers, Donations, Appeals.
### Phase 3: Operational Improvements
1. **Fix DonationResource** — Make it a proper ViewRecord page, not a fake edit page with Placeholders
2. **Add missing filters** to all key resources
3. **Replace hardcoded email checks** with proper permissions (`can-export` permission)
4. **Add cross-resource links** (Donation → Customer, Customer → User, Appeal → Parent)
5. **Deduplicate AppealResource form** (remove from `AppealResource::form()`, keep only in `EditAppeal::form()`)
6. **Archive/hide legacy resources** (Snowdon, or move to a "Legacy" group)
### Phase 4: Reporting & Data Health
1. **Gift Aid Report Page** — Aggregate view for HMRC claims
2. **Donation Summary Report** — By type, country, period
3. **EventLog Cleanup** — Auto-prune entries older than 90 days, add severity indicators
4. **Scheduled Giving Health Dashboard** — Failed payments, retries, cancellations
---
## 6. Technical Recommendations
| Item | Current | Recommended |
|------|---------|-------------|
| Navigation | `->topNavigation()` | `->sidebarCollapsibleOnDesktop()` |
| Global Search | None | Enable on Customer, Donation, Appeal |
| Dashboard | Blank | Custom widgets page |
| Form pattern | `->reactive()` + `callable $get` | `->live()` + `\Filament\Forms\Get $get` |
| Export access | Hardcoded emails | Permission-based (`can-export`) |
| EventLog | 2.2M unmanaged rows | Pruning schedule + summary widget |
| Donation form | Placeholder-only edit page | ViewRecord page |
| Customer-User | Separate resources | Unified Donor resource |
---
## 7. Priority Matrix
| Priority | Item | Effort | Impact |
|----------|------|--------|--------|
| 🔴 P0 | Dashboard widgets | Medium | Very High |
| 🔴 P0 | Fix navigation (sidebar + groups) | Low | High |
| 🔴 P0 | Global search | Low | High |
| 🔴 P0 | Supporter Care donor profile | High | Very High |
| 🟠 P1 | Internal notes system | Medium | High |
| 🟠 P1 | Fix donation view page | Low | Medium |
| 🟠 P1 | Add missing filters | Low | Medium |
| 🟠 P1 | Cross-resource links | Low | Medium |
| 🟠 P1 | Replace hardcoded email checks | Low | Medium |
| 🟡 P2 | Gift Aid report | Medium | Medium |
| 🟡 P2 | EventLog cleanup | Medium | Medium |
| 🟡 P2 | Customer merge tool | High | Medium |
| 🟡 P2 | Communication log | Medium | Medium |
| 🟡 P2 | Archive legacy resources | Low | Low |
---
## Ready to execute. Say "go" with a phase number, or "go all" to start from Phase 1.