Skip to content

Latest commit

 

History

124 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Voteeq

Paid nominee voting and event ticketing platform for campus awards and live events (e.g. ASCES at UMaT). Paystack checkout, real-time leaderboards, nominee self-service dashboards, and admin tooling.

Live: voteeq.online · API: api.voteeq.online


System Design

flowchart LR
  Web[React SPA Vercel]
  API[Express API]
  WS[WebSocket Leaderboard]
  DB[(Turso libSQL)]
  Pay[Paystack]
  Email[Resend]

  Web --> API
  Web --> WS
  API --> DB
  API --> Pay
  Pay -->|webhook| API
  API --> Email
Loading
Flow Behavior
Vote purchase User selects nominee → Paystack hosted checkout → webhook marks vote paid → receipt email
Leaderboard WebSocket broadcast on vote confirmation
Ticketing Optional TICKETS_ENABLED module with QR scan at door
Nominee portal Self-upload photo, share cards, OG image generation (Sharp)

Stack

Layer Host Tech
Frontend Vercel React + Vite
API Render Express + WebSocket
Database Turso libSQL

Local development

Backend

cd backend
cp .env.example .env
# Edit .env with your Turso credentials (optional — falls back to local SQLite)
npm install
npm run dev

API runs at http://localhost:5000.

Frontend

cd frontend
npm install
npm run dev

App runs at http://localhost:5173. API URL defaults to http://localhost:5000.

Production environment variables

Render (voteeq-api)

Variable Required Notes
NODE_ENV Yes production
JWT_SECRET Yes Auto-generated in render.yaml
ADMIN_USERNAME Yes Admin login username
ADMIN_PASSWORD Yes Admin login password
TURSO_DATABASE_URL Yes libsql://... from Turso dashboard
TURSO_AUTH_TOKEN Yes Turso auth token
CORS_ORIGIN Yes Comma-separated, e.g. https://voteeq.online,https://www.voteeq.online,https://voteeq.vercel.app
FRONTEND_URL Yes Primary site URL for Paystack callbacks, e.g. https://www.voteeq.online
PAYSTACK_SECRET_KEY When live sk_live_... or sk_test_...backend only, never in git or Vercel

In the Paystack dashboard → Settings → API Keys & Webhooks:

  1. Add webhook URL: https://api.voteeq.online/api/payment/webhook
  2. Subscribe to charge.success
  3. Use the secret key (sk_...) as PAYSTACK_SECRET_KEY on Render, then redeploy

Callback vs webhook

Setting Required in Paystack menu? What Voteeq does
Callback URL No Sent on every checkout in API code → https://www.voteeq.online/payment-status?token=... (uses FRONTEND_URL on Render). Redirects the payer back to your site after payment.
Webhook URL Yes Paystack POSTs charge.success to your API so votes/tickets/registrations are marked paid. Without this, money can succeed but records stay pending.

The public key (pk_...) is not required — checkout uses Paystack’s hosted payment page.

Resend (email receipts)

Votes and tickets require a valid email. After Paystack confirms payment, Voteeq emails a receipt via Resend.

Variable Required Notes
RESEND_API_KEY For live email Create at Resend → API Keys (can reuse a key from another project or create a new one for Voteeq)
RESEND_FROM_EMAIL Recommended Default: Voteeq <onboarding@resend.dev> (testing — only delivers to your Resend account email). For production, add and verify voteeq.online in Resend, then e.g. Voteeq <receipts@voteeq.online>

Set both on Render alongside Paystack keys, then redeploy the API.

Vercel

Variable Value
VITE_API_URL https://api.voteeq.online
VITE_WS_URL wss://api.voteeq.online

Health check

GET /health — returns { status: "ok" } when the API and database are reachable.

EC2 deployment (always-on API, AWS credits)

Use when Render Free cold starts are unacceptable. Instance apex-server has Elastic IP 54.153.93.87.

  1. DNS (Namecheap): api.voteeq.onlineA record 54.153.93.87 (remove Render CNAME).
  2. On the EC2 instance (Ubuntu), run deploy/ec2-bootstrap.sh from the repo, or see deploy/ec2.env.example.
  3. SSL: sudo certbot --nginx -d api.voteeq.online
  4. Paystack webhook: https://api.voteeq.online/api/payment/webhook

Optional: EventBridge + Lambda pinging /health every 10 minutes can reduce Render Free sleep but is unreliable; EC2 avoids the problem entirely.

Security notes

  • Mock payment endpoints and USSD auto-complete are disabled in production.
  • Demo seed data (sample nominees/events) is development only.
  • Payment status lookups require a token query param returned at checkout.
  • Ticket lookup requires a ticket code (TIX-...) or payment reference + buyer email.

License

MIT · Author: iamroidev

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages