Legal Documents Deployment Guide
Overview
This guide covers deploying the Legal Documents Management System to various environments (development, staging, production).
Prerequisites
- Access to production database
- Admin panel deployed and accessible
- Clerk authentication configured
- Backend API running
- Frontend application deployed
Pre-Deployment Checklist
- All code reviewed and merged to main branch
- Tests passing locally
- Database migration file created
- Environment variables configured
- Admin sidebar updated with Legal Docs link
- API endpoints tested
- Admin pages tested
- User flows tested on staging
Database Migration
1. Create Migration File
The migration file should already exist:
packages/database/prisma/migrations/20241212_add_legal_documents/migration.sql
2. Deploy to Environment
Development (local):
cd packages/database
pnpm prisma migrate dev --name add_legal_documents
Staging:
cd packages/database
# Set DATABASE_URL for staging environment
DATABASE_URL="postgresql://..." pnpm prisma migrate deploy
Production:
cd packages/database
# Set DATABASE_URL for production environment
DATABASE_URL="postgresql://..." pnpm prisma migrate deploy
3. Verify Tables Created
-- Check legal_documents table
SELECT * FROM legal_documents LIMIT 1;
-- Check document_acceptances table
SELECT * FROM document_acceptances LIMIT 1;
-- Check indexes
SELECT * FROM information_schema.statistics
WHERE table_name IN ('legal_documents', 'document_acceptances');
Backend Deployment
1. Environment Variables
No new environment variables needed. Uses existing:
DATABASE_URL- Already configuredCLERK_SECRET_KEY- Already configured
2. Deploy Code
Option A: Docker (AWS ECS/Fargate)
# Build image
docker build -t civstart-backend:latest -f apps/backend/Dockerfile .
# Push to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com
docker tag civstart-backend:latest <ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/civstart-backend:latest
docker push <ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/civstart-backend:latest
Option B: Direct Node
cd apps/backend
npm install
npm run build
npm start
3. Verify API Endpoints
# Test GET endpoint
curl https://api.civstart.com/legal/current/terms
# Should return a document or 404 if none published yet
Frontend Deployment
1. Vercel Deployment (Recommended)
# Vercel auto-deploys from GitHub main branch
# Ensure environment variables set in Vercel dashboard
NEXT_PUBLIC_API_URL=https://api.civstart.com
2. Environment Variables
Add to Vercel dashboard:
NEXT_PUBLIC_API_URL=https://api.civstart.com
3. Test Frontend
- Navigate to
/settings - Check "Legal Agreements" section appears
- Verify "Review" button works
- Test TermsAcceptanceModal opens
Admin Panel Deployment
1. Vercel Deployment
Same as frontend deployment above.
2. Verify Admin Pages
Navigate to admin panel:
-
/legal- Document list loads -
/legal/new- Create page loads - Click "Create Document" button
- Form displays correctly
- All fields render
3. Test Admin Workflow
-
Create Document:
Admin → Legal Docs → Create Document
- Fill form
- Click Save & Publish
- Verify in list as Active -
View Details:
Admin → Legal Docs → Click Document
- See content
- See analytics
- Verify buttons available -
View Logs:
Admin → Legal Docs → Acceptances
- See empty log (no acceptances yet)
- Verify Export CSV button
Post-Deployment Steps
1. Create Initial Documents
Option A: Via API
# Create Terms of Service v1.0.0
curl -X POST https://api.civstart.com/legal/admin/documents \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "terms",
"version": "1.0.0",
"title": "Terms of Service",
"content": "[PASTE YOUR TERMS HERE]",
"effectiveDate": "2024-12-15T00:00:00Z",
"requiresImmediate": true,
"gracePeriodDays": 0
}'
# Publish it
curl -X POST https://api.civstart.com/legal/admin/documents/{ID}/publish \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requiresImmediate": true,
"gracePeriodDays": 0
}'
Option B: Via Admin Panel
- Navigate to
/legalin admin panel - Click "Create Document"
- Fill in Terms of Service details
- Click "Save & Publish"
- Repeat for Privacy Policy
2. Test User Flow
Create Test User:
- Sign up new user in staging
- User should see TermsAcceptanceModal
- Modal should show fetched content
- User checks checkbox and accepts
- Verify acceptance recorded in database:
SELECT * FROM document_acceptances
WHERE user_id = 'TEST_USER_ID';
3. Verify Settings Page
- Test user logs in
- Navigate to
/settings - Should see "Legal Agreements" section
- Should show:
- Terms: Accepted ✓ Version 1.0.0
- Privacy: Accepted ✓ Version 1.0.0
- "Review" button should open modal
4. Test Admin Features
Export CSV:
- Admin → Legal Docs → Acceptances
- Click "Export CSV"
- Should download
terms-acceptance-2024-12-15.csv - Verify headers and data
View Analytics:
- Admin → Legal Docs → Click document
- Click "Analytics" tab
- Should show:
- Total acceptances
- Total users
- Acceptance rate %
- Recent acceptances table
Monitoring & Verification
Database
-- Check document count
SELECT type, COUNT(*) as count, SUM(CASE WHEN is_active THEN 1 ELSE 0 END) as active
FROM legal_documents
GROUP BY type;
-- Check acceptance count
SELECT type, COUNT(*) as count
FROM document_acceptances da
JOIN legal_documents ld ON da.document_id = ld.id
GROUP BY ld.type;
-- Check for any errors
SELECT * FROM legal_documents WHERE published_at IS NULL;
API Health
# Test public endpoint
curl -v https://api.civstart.com/legal/current/terms
# Test authenticated endpoint
curl -v -H "Authorization: Bearer USER_TOKEN" \
https://api.civstart.com/legal/status
# Test admin endpoint
curl -v -H "Authorization: Bearer ADMIN_TOKEN" \
https://api.civstart.com/legal/admin/documents
Application Logs
Check for errors:
# Backend logs
docker logs CONTAINER_ID | grep -i legal
# Frontend errors
Check browser console on /legal and /settings pages
Rollback Plan
If issues occur:
1. Rollback Frontend
# Vercel: Revert to previous deployment
vercel rollback
# Or redeploy without legal changes
git revert <COMMIT_HASH>
git push
2. Rollback API
# ECS: Revert to previous task definition
aws ecs update-service \
--cluster civstart-production \
--service civstart-backend \
--task-definition civstart-backend:PREVIOUS_VERSION
# Or redeploy without legal changes
git revert <COMMIT_HASH>
# Rebuild and push image
3. Rollback Database
# WARNING: Only if absolutely necessary
# Create backup first!
# Migrate down (if needed)
pnpm prisma migrate resolve --rolled-back 20241212_add_legal_documents
# Or manually delete tables
DROP TABLE document_acceptances;
DROP TABLE legal_documents;
Common Issues & Solutions
Issue: Modal not fetching documents
Solution:
- Verify API endpoint is running
- Check CORS headers
- Check network tab in DevTools
- Verify API URL in environment variables
Issue: Acceptance not recorded
Solution:
- Verify user is authenticated
- Check POST
/legal/acceptreturns 201 - Verify database migration ran
- Check user table has new columns
Issue: Admin cannot see Legal Docs in sidebar
Solution:
- Verify sidebar component updated
- Clear browser cache and refresh
- Check admin.tsx imports ScrollText icon
- Verify user email in whitelist
Issue: Published document shows as draft
Solution:
- Check
publishedAtfield in database - Verify publish API call succeeded
- Check for validation errors in logs
- Manually update:
UPDATE legal_documents SET published_at = NOW() WHERE id = '...';
Performance Optimization
Database Indexes
Verify indexes are created:
SHOW INDEX FROM legal_documents;
SHOW INDEX FROM document_acceptances;
Query Optimization
For large datasets, ensure pagination:
- Acceptance logs: Default limit 100, max 500
- Add appropriate WHERE clauses
- Use indexes on:
type,is_active,published_at,user_id
Caching (Optional Future)
Consider Redis caching for:
- Current active documents (rarely change)
- User terms status (check once per login)
Security Verification
- Admin endpoints require authentication
- Non-admin users cannot access
/legal/admin/* - Acceptance records include IP address
- Published documents cannot be edited
- API rate limiting (if applicable)
- CORS properly configured
Communication Checklist
Before going live to production:
- Notify team of deployment
- Update status page
- Send welcome email to users explaining new requirement
- Schedule support team training
- Create FAQ for common questions
- Set up monitoring for acceptance rates
Go-Live Timeline
1-2 Weeks Before
- Complete all testing
- Brief support team
- Create user communication
1 Day Before
- Final verification on staging
- Backup production database
- Notify stakeholders
Deployment Day
- Deploy database migration
- Deploy backend
- Deploy frontend
- Deploy admin panel
- Create initial documents
- Monitor error logs
- Check acceptance rates
After Deployment
- Monitor for errors
- Check user feedback
- Follow up with support
- Update documentation
- Plan next iterations
Rollout Strategy
Option 1: Big Bang (Recommended)
- Deploy everything at once
- Create all documents
- All users see modal on next login
- Requires clear communication
Option 2: Phased
- Deploy code without publishing documents
- Create documents but don't publish
- Publish on scheduled date
- Users notified in advance
Option 3: Gradual
- Deploy to 10% of users first
- Monitor acceptance rates
- Gradually increase to 100%
- Requires feature flags