Skip to main content
This guide walks through deploying the Millennium Potters application to production using CockroachDB for the database and your chosen hosting platform for the application.

Pre-Deployment Checklist

Before starting deployment, ensure:
  • All prerequisites are met
  • Environment variables are configured
  • Database is set up and tested
  • Code is committed to version control (Git)
  • Production secrets are generated and secure
  • Backup of current production database (if updating)
Feature Freeze: Stop all development on the deployment branch until deployment is complete.

Deployment Architecture

┌─────────────────┐
│  Users/Browser  │
└────────┬────────┘
         │ HTTPS

┌─────────────────┐
│  Frontend App   │  ← Next.js on Vercel/Netlify
│  (Next.js 14)   │
└────────┬────────┘
         │ API Calls

┌─────────────────┐
│  Backend API    │  ← Node.js on Render/Plesk
│  (Express)      │
└────┬───────┬────┘
     │       │
     │       └──────────────┐
     ▼                      ▼
┌────────────┐      ┌──────────────┐
│ CockroachDB│      │  Cloudinary  │
│  Database  │      │   Storage    │
└────────────┘      └──────────────┘

Phase 1: Database Migration

1.1 Backup Production Database

This step is mandatory before any production changes. It provides a rollback point if issues arise.
# Export production database to SQL file
pg_dump "$PRODUCTION_DATABASE_URL" \
  --no-owner \
  --no-acl \
  > prod_backup_$(date +%Y%m%d_%H%M%S).sql

# Verify backup file is not empty
ls -lh prod_backup_*.sql
If you have S3 configured:
cockroach sql --url "$PRODUCTION_DATABASE_URL" --execute="
  BACKUP TO 's3://your-bucket/backups/millennium_$(date +%Y%m%d)' 
  AS OF SYSTEM TIME '-10s';
"

1.2 Generate Migration Plan

This creates a SQL script showing exactly what will change:
cd backend

# Generate migration diff
npx prisma migrate diff \
  --from-url "$PRODUCTION_DIRECT_URL" \
  --to-schema-datamodel prisma/schema.prisma \
  --script > migration_plan_$(date +%Y%m%d).sql

1.3 Review Migration Script

Open migration_plan_YYYYMMDD.sql and look for:
  • CREATE TABLE - New features (e.g., ReportSession)
  • ALTER TABLE ... ADD COLUMN - New fields (e.g., User.supervisorId)
  • CREATE INDEX - Performance improvements
  • ALTER TABLE ... ADD CONSTRAINT - Data integrity
  • ALTER TABLE ... ALTER COLUMN - Type changes
  • ALTER TABLE ... DROP CONSTRAINT - Removing relationships
  • Any operation on tables with large datasets
  • DROP TABLE - Data loss
  • ALTER TABLE ... DROP COLUMN - Permanent deletion
  • TRUNCATE - Removes all data
If you see these: Investigate immediately before proceeding.

1.4 Apply Schema Changes

Once verified safe:
# Apply migration to production
npx prisma db execute \
  --url "$PRODUCTION_DIRECT_URL" \
  --file migration_plan_$(date +%Y%m%d).sql

# Verify schema is in sync
npx prisma generate
This approach is safer than prisma db push because it shows exactly what will change before applying.

Phase 2: Backend Deployment

2.1 Build Backend

cd backend

# Install production dependencies
npm install --production=false

# Generate Prisma Client
npx prisma generate

# Compile TypeScript
npm run build
This creates dist/ directory with compiled JavaScript.

2.2 Deploy to Hosting Platform

1

Configure Render service

In your Render dashboard:
  • Build Command: npm install && npx prisma generate && npm run build
  • Start Command: npm start
  • Node Version: 18 or higher
2

Set environment variables

Add all backend environment variables from Environment Configuration:
  • DATABASE_URL (with connection pooling)
  • DIRECT_URL
  • JWT_SECRET
  • CLOUDINARY_*
  • CORS_ORIGIN (set to your frontend URL)
3

Deploy

git push origin main
Render will automatically:
  1. Clone repository
  2. Run build command
  3. Start the service
4

Verify deployment

curl https://your-backend.onrender.com/health
Expected response:
{
  "status": "ok",
  "timestamp": "2026-03-11T10:00:00.000Z",
  "database": "connected"
}

2.3 Verify Backend Health

# Health check
curl https://your-api-domain.com/health

# Test authentication endpoint
curl -X POST https://your-api-domain.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"test"}'

Phase 3: Frontend Deployment

3.1 Build Frontend

cd frontend

# Install dependencies
npm install

# Build for production
npm run build
Next.js will build with Turbopack for optimized production bundles.

3.2 Deploy to Hosting Platform

3.3 Verify Frontend Deployment

1

Access application

Navigate to your production URL (e.g., https://app.millenniumpotters.com)
2

Check browser console

  • No CORS errors
  • API requests succeeding
  • No 404 errors for static assets
3

Test login

  1. Go to login page
  2. Enter admin credentials
  3. Verify successful authentication
  4. Check dashboard loads correctly

Phase 4: Post-Deployment Verification

4.1 Functional Tests

  • Admin login works
  • Supervisor login works
  • Credit Officer login works
  • Logout works
  • Token refresh works (wait 5 minutes, refresh page)
  • User count matches pre-deployment
  • Loan count matches pre-deployment
  • Union count matches pre-deployment
  • Old loans display correctly
  • Old member profiles load
  • Create a test union
  • Create a test member
  • Create a test loan
  • Record a test repayment
  • Upload a test document
  • Generate a report
  • Dark mode toggle works
  • Mobile responsive design
  • Command Center tour launches
  • All pages load without errors

4.2 Performance Checks

# Test API response time
curl -w "@curl-format.txt" -o /dev/null -s https://your-api.com/health

# curl-format.txt contents:
# time_total: %{time_total}s
  • API Health Check: < 200ms
  • Dashboard Load: < 2s
  • Loan List Load: < 1s (for 100 loans)
  • Database Query: < 100ms (average)

4.3 Security Verification

1

Check HTTPS

  • All traffic uses HTTPS
  • HTTP redirects to HTTPS
  • SSL certificate is valid
2

Verify CORS

  • Only frontend domain allowed
  • API rejects requests from other origins
3

Test rate limiting

# Should get 429 after many requests
for i in {1..100}; do curl https://your-api.com/api/users; done

Maintenance Mode

For safe deployments, enable maintenance mode to prevent user actions during updates:

Enable Maintenance Mode

# Via API or database
UPDATE "CompanySetting" SET "maintenanceMode" = true WHERE id = 'default';
When enabled:
  • Non-admin users see “Under Maintenance” message
  • Admins can still access the system
  • All data modification endpoints return 503

Disable After Deployment

UPDATE "CompanySetting" SET "maintenanceMode" = false WHERE id = 'default';

Backup Strategy

Automated Backups

CockroachDB provides:
  • Hourly backups (automatic)
  • 30-day retention
  • Point-in-Time Recovery to any point in last 30 days

Application-Level Backups

The system includes built-in backup features:
  1. Go to: Dashboard → Settings → Backup
  2. Configure:
    • Frequency: Daily/Weekly/Monthly
    • Location: Cloud (Cloudinary)
    • Retention: 30 days (default)
  3. Manual Backup: Click “Backup Now”
Application backups are JSON exports stored in Cloudinary, separate from database backups.

Rollback Procedure

If deployment fails:
1

Enable maintenance mode

UPDATE "CompanySetting" SET "maintenanceMode" = true;
2

Restore database

# Restore from backup file
psql "$PRODUCTION_DATABASE_URL" < prod_backup_YYYYMMDD_HHMMSS.sql
3

Revert code

# Backend
git revert HEAD
git push

# Frontend (Vercel)
vercel rollback
4

Verify rollback

  • Test login
  • Check data integrity
  • Verify all features work
5

Disable maintenance mode

UPDATE "CompanySetting" SET "maintenanceMode" = false;

Monitoring and Logging

Health Monitoring

Set up uptime monitoring with:
  • UptimeRobot (free)
  • Pingdom
  • New Relic
Monitor:
  • /health endpoint every 5 minutes
  • Alert if down for > 2 minutes

Log Aggregation

For backend logs:
View logs in Render dashboard:
  • Go to your service
  • Click “Logs” tab
  • Filter by error level

Audit Logs

All user actions are logged in the AuditLog table:
SELECT 
  "action",
  "entityName",
  "createdAt",
  "actor"->>'firstName' as user_name
FROM "AuditLog"
ORDER BY "createdAt" DESC
LIMIT 100;

Troubleshooting

Possible Causes:
  • Database connection failed
  • Missing environment variables
  • Unhandled exceptions
Solutions:
  1. Check server logs
  2. Verify DATABASE_URL is correct
  3. Test database connection manually
  4. Check Prisma Client is generated
Symptoms: Browser console shows CORS errorsSolutions:
  • Verify CORS_ORIGIN matches frontend URL exactly
  • Include protocol (https://)
  • Remove trailing slashes
  • Restart backend after changing env vars
Symptoms: Schema out of sync errorsSolutions:
  1. Check migration SQL for errors
  2. Verify DIRECT_URL has no pooling params
  3. Manually apply migration via SQL client
  4. Run npx prisma db pull to sync schema
Symptoms: Vercel/Netlify build errorsSolutions:
  • Check Node version is 18+
  • Verify all dependencies are in package.json
  • Clear build cache and retry
  • Check for TypeScript errors locally first
Symptoms: Pages take > 5 seconds to loadSolutions:
  • Check database connection pool size
  • Increase connection_limit if needed
  • Check for N+1 query problems
  • Add indexes to frequently queried fields
  • Monitor CockroachDB dashboard for slow queries

Deployment Checklist

Use this checklist for each deployment:

Pre-Deployment

  • Feature freeze on deployment branch
  • All tests pass locally
  • Database backup created
  • Migration plan reviewed
  • Environment variables updated
  • Team notified of deployment window

During Deployment

  • Maintenance mode enabled
  • Database migration applied
  • Backend deployed and health check passes
  • Frontend deployed and loads correctly
  • Post-deployment tests pass

Post-Deployment

  • Maintenance mode disabled
  • Users notified deployment complete
  • Monitoring alerts configured
  • Deployment documented in changelog
  • Team debriefed on any issues

Performance Optimization

Connection Pooling

For optimal performance with 50-100 users:
DATABASE_URL="...?connection_limit=25&pool_timeout=20"

Caching

Consider implementing:
  • Redis for session storage
  • CDN for static assets
  • API response caching for reports

Database Indexing

The schema includes optimized indexes. Monitor slow queries in CockroachDB dashboard and add indexes as needed.

Next Steps

User Guide

Help users get started with the system

API Reference

API documentation for developers

Build docs developers (and LLMs) love