{"id":31771582,"url":"https://github.com/donartkins/rockbridge-backend-api","last_synced_at":"2026-05-04T11:34:24.114Z","repository":{"id":315047004,"uuid":"1057857833","full_name":"DonArtkins/rockbridge-backend-api","owner":"DonArtkins","description":"A high-performance, scalable donation processing API built for Rockbridge Ministries","archived":false,"fork":false,"pushed_at":"2025-09-16T12:38:33.000Z","size":15968,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T12:40:27.371Z","etag":null,"topics":["expressjs","mongodb","rest-api","stripe-payments"],"latest_commit_sha":null,"homepage":"https://rockbridge.up.railway.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DonArtkins.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-16T09:50:25.000Z","updated_at":"2025-09-16T12:38:36.000Z","dependencies_parsed_at":"2025-09-16T12:40:29.282Z","dependency_job_id":"8ef20254-85fd-4e20-b68b-a2b0d1a74ada","html_url":"https://github.com/DonArtkins/rockbridge-backend-api","commit_stats":null,"previous_names":["donartkins/rockbridge-backend-api"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/DonArtkins/rockbridge-backend-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonArtkins%2Frockbridge-backend-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonArtkins%2Frockbridge-backend-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonArtkins%2Frockbridge-backend-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonArtkins%2Frockbridge-backend-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DonArtkins","download_url":"https://codeload.github.com/DonArtkins/rockbridge-backend-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonArtkins%2Frockbridge-backend-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002615,"owners_count":26083425,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expressjs","mongodb","rest-api","stripe-payments"],"created_at":"2025-10-10T03:41:16.956Z","updated_at":"2025-10-10T03:41:18.271Z","avatar_url":"https://github.com/DonArtkins.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rockbridge Backend API\n\nA high-performance, scalable donation processing API built for Rockbridge Ministries. This microservice handles global payment processing through Stripe, MongoDB data storage, and automated email notifications with graceful handling of concurrent donations.\n\n## 🚀 Features\n\n- **High Concurrency**: Handle thousands of simultaneous donations globally\n- **Stripe Integration**: Secure payment processing with webhooks\n- **MongoDB**: Atomic transactions with optimistic locking\n- **Email Automation**: Receipt and notification system via Gmail SMTP\n- **Global Scale**: Multi-region support with proper timezone handling\n- **Real-time Analytics**: Campaign progress and donation tracking\n- **Rate Limiting**: Protection against spam and abuse\n- **Comprehensive Logging**: Winston-based logging with rotation\n- **Health Monitoring**: Built-in health checks and metrics\n\n## 🏗️ Architecture\n\n### Technology Stack\n\n- **Runtime**: Node.js 18+\n- **Framework**: Express.js\n- **Database**: MongoDB with Mongoose ODM\n- **Payments**: Stripe API\n- **Email**: Nodemailer with Gmail SMTP\n- **Validation**: Joi + Express Validator\n- **Logging**: Winston with daily rotation\n- **Testing**: Jest + Supertest\n\n### Design Principles\n\n- **Stateless**: Each request is independent\n- **Atomic Operations**: Database transactions ensure consistency\n- **Graceful Degradation**: Continues operation even if email fails\n- **Idempotency**: Safe to retry failed operations\n- **Horizontal Scaling**: Ready for load balancer deployment\n\n## 📁 Project Structure\n\n```\nrockbridge-backend-api/\n├── src/\n│   ├── config/           # Configuration files\n│   ├── models/           # MongoDB schemas\n│   ├── controllers/      # Request handlers\n│   ├── services/         # Business logic\n│   ├── middlewares/      # Express middlewares\n│   ├── routes/           # API endpoints\n│   ├── utils/            # Helper functions\n│   ├── templates/        # Email templates\n│   └── seeds/            # Database seeders\n├── tests/                # Test suites\n├── docs/                 # Documentation\n├── logs/                 # Application logs\n└── README.md\n```\n\n## 🛠️ Setup Instructions\n\n### Prerequisites\n\n- Node.js 18+ and npm 8+\n- MongoDB 6.0+ (local or Atlas)\n- Stripe account with API keys\n- Gmail account with App Password\n\n### Installation\n\n1. **Clone and setup project:**\n\n   ```bash\n   # Run the setup commands from the previous artifact\n   # This creates all folders and installs dependencies\n   ```\n\n2. **Environment Configuration:**\n\n   ```bash\n   cp .env.example .env\n   # Edit .env with your actual values\n   ```\n\n3. **Required Environment Variables:**\n\n   ```env\n   # Server\n   PORT=5000\n   NODE_ENV=development\n\n   # Database\n   MONGODB_URI=mongodb://localhost:27017/rockbridge-donations\n\n   # Stripe\n   STRIPE_PUBLISHABLE_KEY=pk_test_...\n   STRIPE_SECRET_KEY=sk_test_...\n   STRIPE_WEBHOOK_SECRET=whsec_...\n\n   # Email\n   GMAIL_USER=your-email@gmail.com\n   GMAIL_APP_PASSWORD=your-16-digit-app-password\n   ADMIN_EMAIL=admin@rockbridgeministries.org\n\n   # Security\n   RATE_LIMIT_WINDOW_MS=900000\n   RATE_LIMIT_MAX_REQUESTS=100\n   ```\n\n4. **Database Setup:**\n\n   ```bash\n   # Seed initial campaigns\n   npm run seed\n   ```\n\n5. **Start Development:**\n   ```bash\n   npm run dev\n   ```\n\n## 🔄 API Endpoints\n\n### Health Check\n\n```http\nGET /api/health\n```\n\n### Campaigns\n\n```http\nGET    /api/campaigns              # List all active campaigns\nGET    /api/campaigns/:slug        # Get campaign by slug\nGET    /api/campaigns/:id/stats    # Campaign statistics\n```\n\n### Donations\n\n```http\nPOST   /api/donations/intent       # Create payment intent\nPOST   /api/donations/confirm      # Confirm successful donation\nGET    /api/donations/:id          # Get donation details\n```\n\n### Payments (Stripe Webhooks)\n\n```http\nPOST   /api/webhooks/stripe        # Stripe webhook endpoint\n```\n\n## 💳 Payment Flow\n\n### 1. Create Donation Intent\n\n```javascript\nPOST /api/donations/intent\n{\n  \"campaignId\": \"campaign_id_here\",\n  \"amount\": 50.00,\n  \"currency\": \"USD\",\n  \"donorInfo\": {\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"email\": \"john@example.com\",\n    \"phone\": \"+1234567890\"\n  },\n  \"isRecurring\": false,\n  \"message\": \"God bless this mission!\"\n}\n\n// Response\n{\n  \"success\": true,\n  \"data\": {\n    \"clientSecret\": \"pi_xxx_secret_xxx\",\n    \"paymentIntentId\": \"pi_xxx\"\n  }\n}\n```\n\n### 2. Frontend Payment Processing\n\n```javascript\n// Your frontend uses Stripe Elements with clientSecret\nconst result = await stripe.confirmPayment({\n  elements,\n  confirmParams: {\n    return_url: \"https://yoursite.com/donation-success\",\n  },\n});\n```\n\n### 3. Confirm Donation\n\n```javascript\nPOST /api/donations/confirm\n{\n  \"paymentIntentId\": \"pi_xxx\",\n  \"campaignId\": \"campaign_id_here\",\n  \"donorInfo\": { /* same as step 1 */ },\n  \"amount\": 50.00,\n  \"currency\": \"USD\"\n}\n\n// Response\n{\n  \"success\": true,\n  \"data\": {\n    \"donationId\": \"donation_id_here\",\n    \"message\": \"Donation confirmed successfully\"\n  }\n}\n```\n\n## 🌍 Handling Global Concurrent Donations\n\n### Database Transactions\n\n```javascript\n// Atomic campaign update with optimistic locking\nconst session = await mongoose.startSession();\ntry {\n  await session.withTransaction(async () =\u003e {\n    // Update campaign stats atomically\n    const campaign = await Campaign.findByIdAndUpdate(\n      campaignId,\n      {\n        $inc: {\n          raisedAmount: amount,\n          donorCount: 1,\n        },\n      },\n      { session, new: true }\n    );\n\n    // Create donation record\n    const donation = await new Donation(donationData).save({ session });\n\n    // Update/create donor record\n    await Donor.findOneAndUpdate(\n      { email: donorInfo.email },\n      { $inc: { totalDonated: amount, donationCount: 1 } },\n      { session, upsert: true }\n    );\n  });\n} finally {\n  await session.endSession();\n}\n```\n\n### Rate Limiting Strategy\n\n```javascript\n// Different limits for different endpoints\nconst donationLimiter = rateLimit({\n  windowMs: 15 * 60 * 1000, // 15 minutes\n  max: 5, // 5 donations per IP per 15min\n  message: \"Too many donation attempts\",\n});\n\nconst campaignLimiter = rateLimit({\n  windowMs: 1 * 60 * 1000, // 1 minute\n  max: 100, // 100 requests per minute\n  message: \"Rate limit exceeded\",\n});\n```\n\n### Stripe Webhook Handling\n\n```javascript\n// Idempotent webhook processing\napp.post(\n  \"/api/webhooks/stripe\",\n  express.raw({ type: \"application/json\" }),\n  async (req, res) =\u003e {\n    const sig = req.headers[\"stripe-signature\"];\n    let event;\n\n    try {\n      event = stripe.webhooks.constructEvent(\n        req.body,\n        sig,\n        process.env.STRIPE_WEBHOOK_SECRET\n      );\n    } catch (err) {\n      console.log(\"Webhook signature verification failed:\", err.message);\n      return res.status(400).send(`Webhook Error: ${err.message}`);\n    }\n\n    // Handle the event idempotently\n    try {\n      await processWebhookEvent(event);\n      res.json({ received: true });\n    } catch (error) {\n      console.error(\"Webhook processing failed:\", error);\n      res.status(500).json({ error: \"Webhook processing failed\" });\n    }\n  }\n);\n```\n\n## 📧 Email System\n\n### Automated Email Flow\n\n1. **Donation Receipt**: Sent immediately after successful payment\n2. **Thank You Email**: Sent after donation confirmation\n3. **Admin Notification**: Sent to ministry administrators\n\n### Email Queue (Future Enhancement)\n\nFor high volume, consider implementing:\n\n- Redis-based email queue\n- Retry mechanism for failed emails\n- Email template caching\n\n## 🔒 Security Measures\n\n- **Rate Limiting**: Prevents donation spam\n- **Input Validation**: Joi schemas for all inputs\n- **MongoDB Injection**: Express-mongo-sanitize\n- **CORS**: Restricted to your domains\n- **Helmet**: Security headers\n- **Webhook Verification**: Stripe signature validation\n\n## 📊 Monitoring \u0026 Logging\n\n### Winston Logging Configuration\n\n```javascript\n// Structured logging with rotation\nconst logger = winston.createLogger({\n  level: \"info\",\n  format: winston.format.combine(\n    winston.format.timestamp(),\n    winston.format.errors({ stack: true }),\n    winston.format.json()\n  ),\n  transports: [\n    new winston.transports.DailyRotateFile({\n      filename: \"logs/error-%DATE%.log\",\n      datePattern: \"YYYY-MM-DD\",\n      level: \"error\",\n    }),\n    new winston.transports.DailyRotateFile({\n      filename: \"logs/combined-%DATE%.log\",\n      datePattern: \"YYYY-MM-DD\",\n    }),\n  ],\n});\n```\n\n### Health Check Endpoint\n\n```http\nGET /api/health\n\n{\n  \"status\": \"healthy\",\n  \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n  \"version\": \"1.0.0\",\n  \"database\": \"connected\",\n  \"stripe\": \"configured\",\n  \"uptime\": 3600\n}\n```\n\n## 🧪 Testing\n\n### Run Tests\n\n```bash\nnpm test              # Run all tests\nnpm run test:watch    # Watch mode\nnpm run test:coverage # Coverage report\n```\n\n### Test Categories\n\n- **Unit Tests**: Individual functions and services\n- **Integration Tests**: API endpoints and database\n- **E2E Tests**: Complete donation flows\n\n## 🚀 Deployment\n\n### Environment Setup\n\n1. **Staging**: Test with Stripe test keys\n2. **Production**: Use Stripe live keys, MongoDB Atlas\n\n### Recommended Hosting\n\n- **Railway**: Easy deployment, MongoDB add-on\n- **Render**: Free tier available\n- **Heroku**: Mature platform\n- **DigitalOcean**: App Platform\n\n### Docker Support\n\n```bash\ndocker build -t rockbridge-api .\ndocker run -p 5000:5000 rockbridge-api\n```\n\n## 📈 Performance Optimizations\n\n### Database Indexing\n\n```javascript\n// Campaign indexes\ncampaignSchema.index({ status: 1, category: 1 });\n\n// Donation indexes\ndonationSchema.index({ \"donorInfo.email\": 1 });\ndonationSchema.index({ campaignId: 1, createdAt: -1 });\ndonationSchema.index({ paymentStatus: 1 });\n```\n\n### Connection Pooling\n\n```javascript\n// MongoDB connection with pooling\nmongoose.connect(MONGODB_URI, {\n  maxPoolSize: 50, // Maximum connections\n  minPoolSize: 5, // Minimum connections\n  maxIdleTimeMS: 30000, // Close after 30s idle\n  serverSelectionTimeoutMS: 5000,\n});\n```\n\n## 🔧 Development Commands\n\n```bash\nnpm run dev           # Development server with hot reload\nnpm run lint          # ESLint code checking\nnpm run lint:fix      # Auto-fix linting issues\nnpm run seed          # Populate database with sample data\n```\n\n## 📚 Additional Documentation\n\n- [API Documentation](docs/API.md)\n- [Deployment Guide](docs/DEPLOYMENT.md)\n- [Stripe Setup](docs/STRIPE_SETUP.md)\n\n## 🆘 Troubleshooting\n\n### Common Issues\n\n1. **MongoDB Connection Failed**\n\n   ```bash\n   # Check if MongoDB is running\n   mongosh\n   # Or check Atlas connection string\n   ```\n\n2. **Stripe Webhook Failing**\n\n   ```bash\n   # Test webhook locally with Stripe CLI\n   stripe listen --forward-to localhost:5000/api/webhooks/stripe\n   ```\n\n3. **Email Not Sending**\n   ```bash\n   # Verify Gmail App Password (not regular password)\n   # Check 2FA is enabled on Gmail account\n   ```\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create feature branch: `git checkout -b feature/amazing-feature`\n3. Commit changes: `git commit -m 'Add amazing feature'`\n4. Push branch: `git push origin feature/amazing-feature`\n5. Open Pull Request\n\n## 📄 License\n\nMIT License - see LICENSE file for details\n\n---\n\n**Support**: For technical support, contact the development team or create an issue in the repository.\n\n**Rockbridge Ministries** - Spreading hope through technology 🙏\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonartkins%2Frockbridge-backend-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonartkins%2Frockbridge-backend-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonartkins%2Frockbridge-backend-api/lists"}