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.
This commit is contained in:
@@ -51,6 +51,21 @@ async function main() {
|
||||
},
|
||||
})
|
||||
|
||||
// ── Demo user (for /login?demo=1 auto-login) ──
|
||||
const { hash } = await import("bcryptjs")
|
||||
const demoHash = await hash("demo1234", 12)
|
||||
await prisma.user.upsert({
|
||||
where: { email: "demo@pnpl.app" },
|
||||
update: { hashedPassword: demoHash, organizationId: org.id },
|
||||
create: {
|
||||
email: "demo@pnpl.app",
|
||||
name: "Demo User",
|
||||
hashedPassword: demoHash,
|
||||
role: "org_admin",
|
||||
organizationId: org.id,
|
||||
},
|
||||
})
|
||||
|
||||
// ── Events ──
|
||||
const galaEvent = await prisma.event.upsert({
|
||||
where: { organizationId_slug: { organizationId: org.id, slug: "ramadan-gala-2026" } },
|
||||
|
||||
Reference in New Issue
Block a user