# Democratic Fundraiser A local-first Democratic fundraising platform built with Next.js, Stripe Checkout + webhooks, Auth.js credentials login, Prisma, PostgreSQL, and a server-authoritative supporter wallet. The app is designed to make donating feel active instead of transactional: cinematic landing page, public momentum meter, issue narrative cards, impact planner, Blue Wave Token (BWT) supporter credits, `/raised` totals page, wallet rewards, raffle entries, and compliance placeholders that must be configured before real fundraising. ## Features - Stripe card donations through embedded Checkout Sessions. - Server-confirmed wallet credits from Stripe webhooks with idempotent ledger writes. - Blue Wave Token (BWT) supporter credits for rewards UX. BWT is not crypto and is not tradable. - Supporter wallet with digital perk redemptions and raffle ticket spending. - Public fundraising stats endpoint for raised total, donor count, and goal progress. - Campaign action center, impact planner, issue grid, accountability frame, and rewards preview. - Local LAN runtime on `0.0.0.0:8008`. ## Stack - Next.js App Router + TypeScript - React 19 - Tailwind CSS 4 - Prisma 7 + PostgreSQL - Auth.js / NextAuth credentials provider - Stripe SDK + Stripe React Elements - Framer Motion for motion and interaction polish ## Quick Start ```bash cd /root/fundraising-platform npm install cp .env.example .env npm run db:migrate npm run db:seed npm run dev ``` Open `http://127.0.0.1:8008` or `http://:8008`. ## Configuration Copy `.env.example` to `.env` and fill in the real local values. Do not commit `.env`. Required values: - `DATABASE_URL` - `NEXT_PUBLIC_SITE_URL` - `AUTH_URL` - `NEXTAUTH_URL` - `AUTH_SECRET` - `STRIPE_SECRET_KEY` - `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` - `STRIPE_WEBHOOK_SECRET` - `PUBLIC_CAMPAIGN_GOAL_USD` - `NEXT_PUBLIC_COMMITTEE_LEGAL_NAME_PLACEHOLDER` - `NEXT_PUBLIC_DISCLAIMER_TEXT` For local Stripe webhook forwarding: ```bash stripe listen --forward-to 127.0.0.1:8008/api/webhooks/stripe ``` ## Useful Commands ```bash npm run dev # Next dev server on 0.0.0.0:8008 npm run build # Production build npm run start # Serve production build on 0.0.0.0:8008 npm run db:migrate # Apply Prisma migrations in dev npm run db:seed # Seed demo users, wallet, perks, raffles npm run test:integration # DB and optional Stripe smoke checks npm run test:http # HTTP smoke checks against a running server npm run test:all # Validation script (prisma + smoke + production build) ``` ## Donation Flow 1. A signed-in supporter chooses an allowed donation tier. 2. The server creates an embedded Stripe Checkout Session and stores user + exchange snapshot metadata. 3. Stripe confirms the card payment for the session's PaymentIntent. 4. Stripe sends `payment_intent.succeeded` to `/api/webhooks/stripe`. 5. The webhook verifies the signature, checks idempotency, creates the donation, appends a ledger entry, and increments wallet credits exactly once. 6. The wallet reads the updated balance and enables rewards or raffle actions. ## Recent hardening updates - Login/register now preserve and sanitize `callbackUrl` so users return to the workflow they came from. - FAQ pending queue is visible only to signed-in users; public users see approved FAQ entries only. - Public fundraising stats now aggregate only `status = succeeded` donations for treasury consistency. - Movement meter writes now use serializable transactions with explicit conflict handling (`409` retry signal on concurrent races). - Casino pages now include the site footer/disclosure block for consistency. - Sitemap now includes `/vote/next-president`. ## Compliance Notes This repository is a technical demo until configured by qualified campaign counsel. Political fundraising can require FEC, state, donor eligibility, disclosure, reporting, refund, and payment processor review. Replace all committee placeholders and legal copy before accepting live contributions. Never commit secrets, live Stripe keys, donor exports, production database dumps, or private credentials.