Simple and robust v1 for internal cold-email operations:
- Pull inboxes from Smartlead
- Filter warmup-off inboxes
- Extract and dedupe domains
- Detect provider via waterfall: GoDaddy -> Porkbun -> Spaceship
- Show expiry/risk/pricing in UI
- Manual approve + execute renewals
- Record idempotent renewal runs in MongoDB
- Backend: Node.js + Express + MongoDB
- Frontend: Next.js
- Auth: single shared username/password -> JWT
- No queue/Redis in v1 (synchronous execution)
- Install dependencies
npm --prefix backend install
npm --prefix frontend install- Copy env template
cp backend/.env.example backend/.env- Set credentials in
backend/.env
APP_USERNAME,APP_PASSWORDMONGO_URISMARTLEAD_API_KEY- Provider keys for GoDaddy/Porkbun/Spaceship
- Start MongoDB locally (example)
docker run --name domain-renewal-mongo -p 27017:27017 -d mongo:7- Run backend
npm run dev:backend- Run frontend
NEXT_PUBLIC_API_BASE_URL=http://localhost:4000/api npm run dev:frontendThis is just the request/response shape between frontend and backend.
POST /api/auth/login- body:
{ "username": "...", "password": "..." } - response:
{ "token": "...", "username": "..." }
- body:
POST /api/scan/run- header:
Authorization: Bearer <token> - response:
{ "runId": "...", "totals": { ... }, "domains": [...] }
- header:
POST /api/renewals/quote- body:
{ "domains": ["example.com"], "termYears": 1 } - response:
{ "rows": [...], "totalEstimated": 100.0 }
- body:
POST /api/renewals/execute- body:
{ "domains": ["example.com"], "termYears": 1, "idempotencyKey": "renew-..." } - response:
{ "idempotentReplay": false, "run": { ... } }
- body:
GET /api/renewals/history- response:
[ { "idempotencyKey": "...", "status": "completed", "summary": { ... } } ]
- response:
- Porkbun renew is marked manual-only in this v1 adapter.
- Spaceship and GoDaddy quote/renew endpoint mappings should be validated in your exact account environment before production spend.
- Renewal execution currently runs inline in the API process for simplicity.
You can safely skip queue in v1 if:
- volume is small/moderate
- runs are manual and supervised
- occasional retries are acceptable
Move to queue later when you need background durability, retries across restarts, and higher throughput.