Scroll4Good
An Instagram Reels-like platform where people in need can post video requests for help and receive direct donations from donors worldwide.
Features
- Vertical Video Feed: Instagram Reels-style scrolling experience
- Video-Only Posts: Every post requires an MP4 video (no exceptions)
- Direct Donations: Stripe-powered secure payments
- Trust System: Verification, risk scoring, and reporting
- Following Feed: Stay updated on posts you care about
- Real-time Updates: Posters can add video updates to their campaigns
- Admin Dashboard: Review reports and manage trust status
Quick Start
Prerequisites
- Node.js 18+
- MongoDB 6+
- Stripe account (for payments)
Installation
Clone and install dependencies:
npm installSet up environment variables:
cp .env.example .env
Edit .env with your actual values:
- MongoDB connection string
- JWT secret (generate a strong random string)
- Stripe API keys (from Stripe Dashboard)
Start MongoDB:
# If using local MongoDB mongodSeed the database:
npm run seed
This creates:
- 1 admin user (admin@scroll4good.com / admin123)
- 2 needy users
- 1 donor user (donor@example.com / donor123)
- 12 demo posts with real video URLs
Start the server:
npm run devOpen your browser:
http://localhost:3000
Stripe Testing
Set up Stripe CLI for webhooks:
Install Stripe CLI: https://stripe.com/docs/stripe-cli
Login to Stripe:
stripe loginForward webhooks to local server:
stripe listen --forward-to localhost:3000/api/stripe/webhookCopy the webhook signing secret to
.env:STRIPE_WEBHOOK_SECRET=whsec_xxxxx
Test payment:
Use Stripe test cards:
- Success: 4242 4242 4242 4242
- Decline: 4000 0000 0000 0002
- Any future expiry date and any 3-digit CVC
User Roles
Donor
- Browse feed and discover posts
- Donate to campaigns
- Follow posts for updates
- Report suspicious content
Needy (People in Need)
- Create video posts requesting help
- Add video updates to campaigns
- Track donations received
Admin
- Review reported posts
- Verify or flag content
- Manage trust status
- Remove inappropriate posts
Project Structure
scroll4good/
├── client/
│ ├── index.html
│ ├── login.html
│ ├── register.html
│ ├── post.html
│ ├── create.html
│ ├── following.html
│ ├── profile.html
│ ├── admin.html
│ ├── success.html
│ └── src/
│ ├── api.js
│ ├── auth.js
│ ├── feed.js
│ ├── post.js
│ ├── create.js
│ ├── following.js
│ ├── admin.js
│ └── ui/
│ ├── reelCard.js
│ ├── modal.js
│ ├── toast.js
│ └── utils.js
├── server/
│ ├── index.js
│ ├── models/
│ ├── routes/
│ ├── middleware/
│ ├── utils/
│ ├── uploads/
│ └── scripts/
│ └── seed.js
└── package.json
API Endpoints
Authentication
- POST /api/auth/register - Register new user
- POST /api/auth/login - Login
- POST /api/auth/logout - Logout
- GET /api/auth/me - Get current user
Posts
- GET /api/posts - Get posts feed (cursor pagination)
- POST /api/posts - Create post (needy only, video required)
- GET /api/posts/:id - Get post details
- PATCH /api/posts/:id - Update post (limited)
Follows
- POST /api/posts/:id/follow - Follow a post
- DELETE /api/posts/:id/follow - Unfollow
- GET /api/posts/following - Get following feed
Updates
- GET /api/posts/:id/updates - Get post updates
- POST /api/posts/:id/updates - Add update (video required)
Donations
- POST /api/donations/checkout - Create Stripe checkout
- GET /api/donations/session/:id - Check session status
- POST /api/stripe/webhook - Stripe webhook handler
Reports
- POST /api/reports - Report a post
AI
- POST /api/ai/risk-score - Calculate risk score
Admin
- GET /api/admin/reports - Get all reports
- PATCH /api/admin/posts/:id/trust-status - Update trust
- PATCH /api/admin/posts/:id/status - Update status
- PATCH /api/admin/posts/:id/verify - Verify post
Uploads
- POST /api/uploads/video - Upload video (returns URL)
Tech Stack
Frontend:
- HTML5
- Vanilla JavaScript (ES Modules)
- Tailwind CSS (CDN)
- Fetch API
Backend:
- Node.js + Express
- MongoDB + Mongoose
- JWT (httpOnly cookies)
- Stripe Checkout + Webhooks
- Multer (file uploads)
Security Features
- JWT authentication with httpOnly cookies
- Password hashing with bcryptjs
- Request validation with Zod
- Rate limiting on sensitive endpoints
- CORS with credentials
- File type and size validation
- Role-based access control
Hard Constraints
- Only people in need can post (role must be "needy")
- Every post MUST include a video (mp4 required)
- Feed UI mimics Instagram Reels (vertical snap scrolling)
- No NGO accounts, no organization accounts
- No other content types (only help request videos)
Troubleshooting
MongoDB connection issues:
- Ensure MongoDB is running: mongod
- Check connection string in
.env
Video upload fails:
- Check MAX_VIDEO_SIZE_MB in
.env - Ensure
server/uploadsdirectory exists - Verify video is mp4 format
Stripe webhook not working:
- Run
stripe listen --forward-to localhost:3000/api/stripe/webhook - Copy webhook secret to
.env - Restart server after updating
.env
CORS errors:
- Ensure FRONTEND_URL matches your client URL
- Check that credentials are included in fetch requests
Postman Collection
Import postman_collection.json to test all API endpoints.
License
MIT
Built with love for a better world
Log in or sign up for Devpost to join the conversation.