Skip to content

ashucfx/ClientForge

Repository files navigation

ClientForge by Ripple Nexus

Internal client operations workspace by Ripple Nexus. Today it powers Career Booster billing (payment links, multi-currency, branded emails) and is designed to expand into broader invoicing + client onboarding workflows.


πŸ—‚οΈ Folder Structure

ripple-nexus/
β”œβ”€β”€ .env.local                         # Environment variables (real keys inside)
β”œβ”€β”€ .env.example                       # Template for reference
β”œβ”€β”€ next.config.js
β”œβ”€β”€ tailwind.config.js
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ prisma/
β”‚   └── schema.prisma                  # PostgreSQL schema (Invoice + ExchangeRateCache)
└── src/
    β”œβ”€β”€ app/
    β”‚   β”œβ”€β”€ layout.tsx                 # Root layout (Plus Jakarta Sans font)
    β”‚   β”œβ”€β”€ globals.css                # Design tokens, animations
    β”‚   β”œβ”€β”€ page.tsx                   # πŸ“Š Dashboard β€” invoice list + stats
    β”‚   β”œβ”€β”€ invoices/
    β”‚   β”‚   β”œβ”€β”€ page.tsx               # Redirects β†’ /
    β”‚   β”‚   β”œβ”€β”€ new/
    β”‚   β”‚   β”‚   └── page.tsx           # βž• Create Invoice form (live pricing preview)
    β”‚   β”‚   └── [id]/
    β”‚   β”‚       └── page.tsx           # πŸ“„ Invoice detail view (full premium UI)
    β”‚   └── api/
    β”‚       β”œβ”€β”€ invoices/
    β”‚       β”‚   β”œβ”€β”€ route.ts           # GET list / POST create
    β”‚       β”‚   β”œβ”€β”€ stats/route.ts     # GET dashboard stats
    β”‚       β”‚   └── [id]/
    β”‚       β”‚       β”œβ”€β”€ route.ts       # GET single / PATCH update
    β”‚       β”‚       └── resend-email/
    β”‚       β”‚           └── route.ts   # POST resend invoice email
    β”‚       β”œβ”€β”€ currency/
    β”‚       β”‚   └── route.ts           # GET exchange rates + live pricing preview
    β”‚       └── razorpay/
    β”‚           β”œβ”€β”€ create-link/
    β”‚           β”‚   └── route.ts       # POST regenerate payment link
    β”‚           └── webhook/
    β”‚               └── route.ts       # POST Razorpay webhook (mark PAID)
    β”œβ”€β”€ lib/
    β”‚   β”œβ”€β”€ db.ts                      # Prisma singleton
    β”‚   β”œβ”€β”€ pricing.ts                 # Base prices, fee logic, calculator, formatter
    β”‚   β”œβ”€β”€ currency.ts                # Countryβ†’currency map, exchange rate fetcher
    β”‚   β”œβ”€β”€ razorpay.ts                # Payment link creation + webhook verification
    β”‚   └── email.ts                   # Resend integration + HTML email templates
    └── types/
        └── index.ts                   # Shared TypeScript types

⚑ Quick Start

1. Prerequisites

  • Node.js 18+
  • PostgreSQL (local or hosted β€” Supabase/Neon free tier works perfectly)
  • npm or pnpm

2. Install dependencies

cd ripple-nexus
npm install

3. Configure environment

.env.local is already populated with your live Razorpay keys:

RAZORPAY_KEY_ID=rzp_live_SajWG4jNWIcHmU
RAZORPAY_KEY_SECRET=f8yvo1nUfNfNdi3V7dsLc1TF

You still need to fill in:

# Your PostgreSQL connection string
DATABASE_URL=postgresql://user:password@host:5432/ripple_nexus

# Resend email API key β€” get free at https://resend.com
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Update this after setting webhook in Razorpay dashboard
RAZORPAY_WEBHOOK_SECRET=your_webhook_secret

# For production, set your actual domain
NEXT_PUBLIC_APP_URL=https://invoices.ripplenexus.com

4. Set up database

npx prisma generate      # Generate Prisma client
npx prisma db push       # Push schema to your PostgreSQL
# OR for migrations:
npx prisma migrate dev --name init

5. Run development server

npm run dev
# β†’ http://localhost:3000

πŸ”‘ Keys Already Configured

Service Key Status
Razorpay Key ID rzp_live_SajWG4jNWIcHmU βœ… Live
Razorpay Secret f8yvo1nUfNfNdi3V7dsLc1TF βœ… Live
Resend β€” ⚠️ Add yours
Exchange Rate API β€” βœ… Uses free fallback (open.er-api.com)

⚠️ Security: Never commit .env.local to Git. It's in .gitignore by default.


πŸ’³ Razorpay Webhook Setup

  1. Log in to Razorpay Dashboard
  2. Go to Settings β†’ Webhooks β†’ Add New Webhook
  3. Set URL: https://your-domain.com/api/razorpay/webhook
  4. Select events: payment_link.paid, payment_link.expired
  5. Copy the Webhook Secret β†’ paste into .env.local as RAZORPAY_WEBHOOK_SECRET

For local testing, use ngrok:

ngrok http 3000
# Use the https URL as your webhook URL

πŸ“§ Email Setup (Resend)

  1. Sign up at resend.com (free: 3,000 emails/month)
  2. Add and verify your domain (ripplenexus.com)
  3. Create an API key β†’ paste as RESEND_API_KEY
  4. Set FROM_EMAIL=invoices@ripplenexus.com

🌍 Currency System

  • Auto-detection: Country selected β†’ currency auto-mapped (40+ countries)
  • Manual override: Admin can type any ISO 4217 code (e.g. AED, SGD)
  • Exchange rates: Fetched live from open.er-api.com (no key needed) or exchangerate-api.com (optional key for higher limits)
  • Cache: Rates cached in memory for 6 hours to avoid excessive API calls
  • INR payments: 2% processing fee
  • International: 3.5% processing fee
  • Locked on creation: Currency cannot change after invoice is generated

πŸ’° Pricing Reference

Client Type Resume (INR) LinkedIn (INR) Cover Letter
Fresher β‚Ή1,499 β‚Ή999 FREE
Mid-Career β‚Ή1,999 β‚Ή1,299 FREE
Executive β‚Ή3,499 β‚Ή1,999 FREE
Executive Plus β‚Ή4,999 β‚Ή2,499 FREE

All prices converted to client's local currency at live exchange rates.


πŸ—οΈ Key API Endpoints

Method Endpoint Description
GET /api/invoices List all invoices (filters: status, clientType)
POST /api/invoices Create new invoice
GET /api/invoices/:id Get single invoice
PATCH /api/invoices/:id Update invoice
POST /api/invoices/:id/resend-email Resend invoice email
GET /api/invoices/stats Dashboard statistics
GET /api/currency Get exchange rates + live pricing preview
POST /api/razorpay/create-link (Re)create Razorpay payment link
POST /api/razorpay/webhook Razorpay webhook (mark paid)

πŸ—„οΈ Database Schema

model Invoice {
  id                String        # cuid
  invoiceNumber     String        # e.g. RN-2404-8371
  clientName/Email/Phone/Type/Country
  currency          String        # ISO 4217, LOCKED on create
  currencySymbol    String
  exchangeRate      Float         # INR→currency rate at creation
  resumeBaseInr / linkedinBaseInr / coverLetterBaseInr
  resumeConverted / linkedinConverted / coverLetterConverted
  subtotalConverted / processingFeeRate / processingFeeConverted
  totalPayable      Float         # Final amount in client currency
  status            PENDING|PAID|CANCELLED|EXPIRED
  razorpayLinkId / razorpayLinkUrl / razorpayPaymentId
  paidAt            DateTime?
  emailSentAt / emailResendCount
  invoiceDate / dueDate (7 days)
}

πŸš€ Production Deployment

Vercel (Recommended)

npm install -g vercel
vercel --prod

Add all .env.local variables in Vercel dashboard under Settings β†’ Environment Variables.

Docker

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci && npm run build
EXPOSE 3000
CMD ["npm", "start"]

Database β€” Recommended Hosts

  • Supabase (free PostgreSQL, great DX): supabase.com
  • Neon (serverless PostgreSQL, generous free tier): neon.tech
  • PlanetScale (MySQL-compatible): planetscale.com

πŸ” Security Checklist

  • Razorpay webhook signature verified via HMAC-SHA256
  • Currency locked on invoice creation β€” cannot be changed
  • Razorpay amount matches invoice exactly (smallest unit)
  • Input validation via Zod on all POST routes
  • Admin-only access via middleware + login
  • Rate limit invoice creation endpoint
  • Add CORS headers for production

Admin Authentication

This app is private by default: all routes (including /api/*) are protected by middleware.ts, and access is granted only after signing in at /login.

Set these in production:

ADMIN_PASSWORD=your_admin_password
ADMIN_SESSION_SECRET=your_long_random_secret

πŸ› Troubleshooting

Prisma client not found

npx prisma generate

Exchange rate API failing The system automatically falls back to hardcoded approximate rates. For production, get a free key at exchangerate-api.com.

Razorpay "Currency not supported" Some currencies are not supported by Razorpay international payments. The system will create the payment link β€” if Razorpay rejects it, fall back to INR or USD.

Emails not sending

  • Verify Resend API key is correct
  • Confirm your sending domain is verified in Resend dashboard
  • Check FROM_EMAIL domain matches your verified domain

πŸ“ž Support

Built for Ripple Nexus internal use.
Razorpay Live Key: rzp_live_SajWG4jNWIcHmU

About

ClientForge is a global-ready invoice automation and client operations system by Ripple Nexus. It enables businesses to generate dynamic, multi-currency invoices, automate Razorpay payment links, and manage client transactions seamlessly - all from a clean, scalable internal dashboard.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors