Skip to content

CodeEnthusiast09/proposly-backend

Repository files navigation

Proposly — Backend

NestJS REST API powering the Proposly proposal management platform.

Stack

  • Framework: NestJS v11 (TypeScript)
  • Database: PostgreSQL via TypeORM
  • Auth: JWT + Passport (local + Google OAuth)
  • AI: Anthropic Claude SDK (claude-opus-4-5 for generation, claude-haiku-4-5 for edits)
  • Payments: Stripe (international) + Paystack (Nigeria)
  • Email: @nestjs-modules/mailer with Handlebars templates
  • PDF: Puppeteer + marked (markdown → HTML → PDF)
  • Rate limiting: @nestjs/throttler

Getting started

Prerequisites

  • Node.js 20+
  • PostgreSQL running locally

Install

npm install

Environment

cp .env.example .env

Fill in all values — see Environment variables below.

Run

# Development (watch mode)
npm run start:dev

# Production
npm run build && npm run start:prod

Server starts on http://localhost:3001. All routes are prefixed with /api.


Environment variables

Variable Description
PORT Server port (default 3001)
NODE_ENV development or production
DB_HOST PostgreSQL host
DB_PORT PostgreSQL port (default 5432)
DB_USERNAME Database user
DB_PASSWORD Database password
DB_NAME Database name
JWT_SECRET Secret used to sign JWT tokens
JWT_EXPIRY Token expiry e.g. 7d
ANTHROPIC_API_KEY Anthropic API key for Claude
FREE_AI_GENERATIONS_LIMIT Max AI generations for free users (default 3)
GOOGLE_CLIENT_ID Google OAuth client ID
GOOGLE_CLIENT_SECRET Google OAuth client secret
GOOGLE_CALLBACK_URL OAuth callback — e.g. http://localhost:3001/api/auth/google/callback
STRIPE_SECRET_KEY Stripe secret key
STRIPE_WEBHOOK_SECRET Stripe webhook signing secret
STRIPE_PRO_PRICE_ID Stripe Price ID for the Pro plan
PAYSTACK_SECRET_KEY Paystack secret key (also used for webhook HMAC verification)
PAYSTACK_BASE_URL Paystack API base (default https://api.paystack.co)
PAYSTACK_PRO_PLAN_CODE Paystack Plan code for the Pro subscription
MAIL_HOST SMTP host
MAIL_PORT SMTP port
MAIL_USER SMTP username
MAIL_PASSWORD SMTP password
MAIL_FROM Sender address
MAIL_FROM_NAME Sender display name
FRONTEND_URL Frontend origin — used in email links and OAuth redirects

synchronize: true is enabled in development so TypeORM applies schema changes automatically. Never use this in production.


API reference

All routes require Authorization: Bearer <token> unless marked Public.

Auth /api/auth

Method Path Auth Description
POST /register Public Register with email + password
POST /login Public Login, returns JWT + user
GET /verify-email?token= Public Verify email address
POST /forgot-password Public Send password reset link
POST /reset-password Public Reset password with token
POST /resend-verification Public Resend verification email
GET /google Public Initiate Google OAuth
GET /google/callback Public Google OAuth callback
GET /me JWT Get current user

Users /api/users

Method Path Description
PATCH /me Update profile (name, profession, country)
GET /me/notifications Get notification preferences
PATCH /me/notifications Update notification preferences

Proposals /api/proposals

Method Path Description
POST / Create proposal
GET / List proposals — filterable by clientId, status
GET /:id Get single proposal
PATCH /:id Update proposal
DELETE /:id Delete proposal
POST /:id/generate AI-generate content (free tier limited)
POST /:id/send Email proposal to client + mark as sent
POST /:id/polish AI-polish full document — Pro only
GET /:id/export/pdf Download as PDF

Clients /api/clients

Method Path Description
POST / Create client
GET / List clients
GET /:id Get client
PATCH /:id Update client
DELETE /:id Delete client

AI /api/ai

Method Path Description
POST /rewrite Rewrite selected text with instruction — Pro only

Instructions: rewrite shorten formal fix

Billing /api/billing

Method Path Auth Description
POST /stripe/checkout JWT Create Stripe checkout session
POST /stripe/portal JWT Open Stripe customer portal
POST /stripe/webhook Public Stripe webhook (raw body + signature)
POST /paystack/initialize JWT Initialize Paystack transaction
POST /paystack/webhook Public Paystack webhook (HMAC-SHA512)

Plans

Feature Free Pro
AI proposal generation Up to FREE_AI_GENERATIONS_LIMIT Unlimited
AI Polish
Inline AI editing
PDF export
Send to client

Project structure

src/
├── modules/
│   ├── auth/          # JWT, Google OAuth, password reset, email verification
│   ├── users/         # Profile update, notification preferences
│   ├── clients/       # Client CRUD
│   ├── proposals/     # Proposal CRUD, AI generation, send email, polish, PDF export
│   ├── ai/            # Anthropic Claude wrapper
│   ├── billing/       # Stripe + Paystack checkout and webhooks
│   └── mail/          # Handlebars email templates
├── common/
│   ├── filters/       # Global HTTP exception filter
│   ├── guards/        # JwtAuthGuard, GoogleAuthGuard
│   ├── decorators/    # @CurrentUser()
│   └── utils/         # successResponse / errorResponse helpers
└── config/            # Typed environment loader

Testing webhooks locally

Stripe:

stripe listen --forward-to localhost:3001/api/billing/webhook

Paystack: Use Paystack's test dashboard to trigger test events, or send a manual POST to /api/billing/paystack/webhook with a valid HMAC signature.

About

REST API for Proposly — NestJS, PostgreSQL, TypeORM, Claude AI, Stripe, Paystack

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors