Deployment Overview
This guide covers deploying the MyNATCA platform applications on Vercel, including the Discord bot web interface, Member Hub, and other Next.js/Vue.js applications.
Prerequisites
Required Accounts
- Vercel Account: Pro plan recommended for production
- GitHub Account: For repository integration
- Custom Domain: For production deployments
Required Setup
- Applications pushed to GitHub repositories
- Environment variables documented
- Database connections configured
- Auth0 applications set up
Project Structure for Vercel
Discord Bot Application
mynatca-discord/
├── pages/ # Next.js pages (API routes)
│ ├── api/
│ │ ├── auth/ # Auth0 callback handlers
│ │ ├── verify/ # Verification endpoints
│ │ └── webhook/ # Discord webhooks
│ ├── verify/ # Verification UI pages
│ └── _app.js # App configuration
├── vercel.json # Vercel configuration
├── next.config.js # Next.js configuration
└── package.json # Dependencies and scriptsPlatform API Application
mynatca-platform/
├── pages/
│ └── api/ # API endpoints
│ ├── sync/ # Data sync endpoints
│ ├── health/ # Health check endpoints
│ └── admin/ # Administrative endpoints
├── vercel.json # Vercel configuration
└── package.json # Dependencies and scriptsVercel Configuration
Discord Bot Configuration
Create vercel.json in the Discord bot repository:
{
"version": 2,
"name": "mynatca-discord",
"alias": ["discord.mynatca.org"],
"builds": [
{
"src": "package.json",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "/api/$1"
},
{
"src": "/verify/(.*)",
"dest": "/verify/$1"
},
{
"src": "/(.*)",
"dest": "/index.html"
}
],
"env": {
"NODE_ENV": "production"
},
"functions": {
"pages/api/**/*.js": {
"maxDuration": 30
}
},
"headers": [
{
"source": "/api/(.*)",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "https://discord.mynatca.org"
},
{
"key": "Access-Control-Allow-Methods",
"value": "GET, POST, PUT, DELETE, OPTIONS"
},
{
"key": "Access-Control-Allow-Headers",
"value": "X-Requested-With, Content-Type, Authorization"
}
]
}
],
"redirects": [
{
"source": "/",
"destination": "/verify",
"permanent": false
}
]
}Platform API Configuration
Create vercel.json in the platform repository:
{
"version": 2,
"name": "mynatca-platform-api",
"alias": ["api.mynatca.org"],
"builds": [
{
"src": "package.json",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "/api/$1"
}
],
"env": {
"NODE_ENV": "production"
},
"functions": {
"pages/api/**/*.js": {
"maxDuration": 60
},
"pages/api/sync/**/*.js": {
"maxDuration": 300
}
},
"crons": [
{
"path": "/api/sync/scheduled",
"schedule": "0 */6 * * *"
},
{
"path": "/api/health/check",
"schedule": "*/15 * * * *"
}
]
}Environment Variables Setup
Discord Bot Environment Variables
# Core Discord Configuration
DISCORD_TOKEN=your_discord_bot_token
DISCORD_CLIENT_ID=your_discord_application_id
DISCORD_GUILD_ID=your_discord_server_id
# Auth0 Configuration
AUTH0_DOMAIN=natca-prod.us.auth0.com
AUTH0_CLIENT_ID=your_auth0_client_id
AUTH0_CLIENT_SECRET=your_auth0_client_secret
# ⚠️ CRITICAL: AUTH0_SECRET is REQUIRED for NextJS Auth0 SDK
# Generate with: openssl rand -hex 32
AUTH0_SECRET=your_auth0_secret_32_chars_minimum
AUTH0_BASE_URL=https://discord.mynatca.org
AUTH0_ISSUER_BASE_URL=https://natca-prod.us.auth0.com
AUTH0_SCOPE=openid profile email
# Database Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_supabase_service_key
# ⚠️ CRITICAL: Supabase Schema Exposure Required
# In Supabase Dashboard > Settings > API > Exposed schemas
# Add both 'discord' and 'discord_dev' schemas to exposed schemas list
# This allows Discord bot to access verification tables directly
# MySQL Configuration (for sync operations)
MYSQL_HOST=your_mysql_host
MYSQL_USER=your_mysql_username
MYSQL_PASS=your_mysql_password
MYSQL_DB=your_mysql_database
# Application Configuration
NODE_ENV=production
VERCEL_URL=discord.mynatca.org
WEBHOOK_SECRET=your_webhook_secret
# Monitoring
SENTRY_DSN=your_sentry_dsn
LOG_LEVEL=infoPlatform API Environment Variables
# Database Configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your_supabase_service_key
# MySQL Configuration
MYSQL_HOST=your_mysql_host
MYSQL_USER=your_mysql_username
MYSQL_PASS=your_mysql_password
MYSQL_DB=your_mysql_database
# Auth0 Management API
AUTH0_DOMAIN=natca-prod.us.auth0.com
AUTH0_M2M_CLIENT_ID=your_m2m_client_id
AUTH0_M2M_CLIENT_SECRET=your_m2m_client_secret
# Session Management (CRITICAL)
SESSION_SECRET=your_long_random_secret_min_32_chars
REDIS_URL=redis://redis:6379
# Note: Generate with: openssl rand -base64 32
# Application Configuration
NODE_ENV=production
API_SECRET=your_api_secret
WEBHOOK_SECRET=your_webhook_secret
# CRITICAL: Trust proxy setting (required for reverse proxy deployments)
TRUST_PROXY=1
# Rackspace Email Integration
RACKSPACE_API_KEY=your_rackspace_api_key
RACKSPACE_SECRET_KEY=your_rackspace_secret_key
RACKSPACE_CUSTOMER_ID=123456
# Intercom Integration
INTERCOM_ACCESS_TOKEN=your_intercom_access_token
# Sync Configuration
SYNC_BATCH_SIZE=1000
SYNC_RETRY_COUNT=3
SYNC_TIMEOUT=300000
# Monitoring
SENTRY_DSN=your_sentry_dsn
LOG_LEVEL=infoDeployment Process
Initial Setup
1. Install Vercel CLI
npm install -g vercel2. Login to Vercel
vercel login3. Link Projects
# In Discord bot repository
cd mynatca-discord
vercel link
# In platform repository
cd mynatca-platform
vercel linkDeploy Discord Bot
1. Configure Project Settings
# Set project settings
vercel --prod --confirm
# Configure environment variables
vercel env add NODE_ENV production
vercel env add AUTH0_DOMAIN natca-prod.us.auth0.com
vercel env add AUTH0_CLIENT_ID
vercel env add AUTH0_CLIENT_SECRET
# ⚠️ CRITICAL: AUTH0_SECRET must be added or deployment will fail
# Generate with: openssl rand -hex 32
vercel env add AUTH0_SECRET
vercel env add AUTH0_BASE_URL https://discord.mynatca.org
vercel env add AUTH0_ISSUER_BASE_URL https://natca-prod.us.auth0.com
vercel env add DISCORD_TOKEN
vercel env add DISCORD_CLIENT_ID
vercel env add DISCORD_GUILD_ID
vercel env add SUPABASE_URL
vercel env add SUPABASE_KEY
vercel env add MYSQL_HOST
vercel env add MYSQL_USER
vercel env add MYSQL_PASS
vercel env add MYSQL_DB2. Deploy Application
# Pre-deployment verification
vercel env ls | grep AUTH0_SECRET # Ensure AUTH0_SECRET is set
# Production deployment
vercel --prod
# Verify deployment
curl https://discord.mynatca.org/api/health
# Test authentication endpoint
curl -I https://discord.mynatca.org/api/auth/loginDeploy Platform API
1. Configure Environment Variables
# In platform repository
vercel env add NODE_ENV production
vercel env add SUPABASE_URL
vercel env add SUPABASE_KEY
vercel env add MYSQL_HOST
vercel env add MYSQL_USER
vercel env add MYSQL_PASS
vercel env add MYSQL_DB
vercel env add AUTH0_DOMAIN
vercel env add AUTH0_M2M_CLIENT_ID
vercel env add AUTH0_M2M_CLIENT_SECRET
vercel env add API_SECRET
vercel env add SYNC_BATCH_SIZE 1000
vercel env add SYNC_RETRY_COUNT 32. Deploy Application
# Production deployment
vercel --prod
# Verify deployment
curl https://api.mynatca.org/api/healthCustom Domain Configuration
DNS Configuration
# DNS Records (Configure in your DNS provider)
Type: CNAME
Name: discord
Value: cname.vercel-dns.com
Type: CNAME
Name: api
Value: cname.vercel-dns.com
Type: CNAME
Name: hub
Value: cname.vercel-dns.comSSL Certificate
Vercel automatically provisions SSL certificates for custom domains:
- Let's Encrypt certificates
- Automatic renewal
- Wildcard support for subdomains
Domain Verification
# Add domain to Vercel project
vercel domains add discord.mynatca.org
vercel domains add api.mynatca.org
vercel domains add hub.mynatca.org
# Verify domain ownership
vercel domains verify discord.mynatca.orgIntegration with External Services
Auth0 Callback URLs
Update Auth0 applications with production URLs:
Discord Bot Application:
- Allowed Callback URLs: https://discord.mynatca.org/api/auth/callback
- Allowed Logout URLs: https://discord.mynatca.org/api/auth/logout
- Allowed Web Origins: https://discord.mynatca.org
Member Hub Application:
- Allowed Callback URLs: https://hub.mynatca.org/callback
- Allowed Logout URLs: https://hub.mynatca.org
- Allowed Web Origins: https://hub.mynatca.orgDiscord Application Configuration
Update Discord application settings:
OAuth2 Redirect URLs:
- https://discord.mynatca.org/api/auth/callback
Interactions Endpoint URL:
- https://discord.mynatca.org/api/interactionsDeployment Automation
GitHub Actions Workflow
# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
vercel-args: '--prod'
if: github.ref == 'refs/heads/main'Environment Promotion Script
#!/bin/bash
# scripts/promote-to-production.sh
echo "🚀 Promoting to production..."
# Run pre-deployment checks
npm run test
npm run lint
npm run security-audit
# Deploy to Vercel
vercel --prod --confirm
# Update Auth0 settings
node scripts/update-auth0-production.js
# Verify deployment
npm run verify-production
echo "✅ Production deployment complete!"Pre-Deployment Checklist
🔍 Environment Variables Verification
Before deploying to production, verify all required environment variables are set:
# Critical Auth0 variables
vercel env ls | grep AUTH0_SECRET # Must be present
vercel env ls | grep AUTH0_CLIENT_ID # Must be present
vercel env ls | grep AUTH0_CLIENT_SECRET # Must be present
vercel env ls | grep AUTH0_DOMAIN # Must be present
vercel env ls | grep AUTH0_BASE_URL # Must match deployment URL
# Database variables
vercel env ls | grep SUPABASE_URL # Must be present
vercel env ls | grep SUPABASE_KEY # Must be present
# Discord variables (for Discord bot)
vercel env ls | grep DISCORD_TOKEN # Must be present
vercel env ls | grep DISCORD_CLIENT_ID # Must be present
vercel env ls | grep DISCORD_GUILD_ID # Must be present✅ Required Environment Variables Checklist
Discord Bot Application
-
AUTH0_SECRET- CRITICAL: Generate withopenssl rand -hex 32 -
AUTH0_DOMAIN- Set tonatca-prod.us.auth0.com -
AUTH0_CLIENT_ID- From Auth0 dashboard -
AUTH0_CLIENT_SECRET- From Auth0 dashboard -
AUTH0_BASE_URL- Set to deployment URL -
AUTH0_ISSUER_BASE_URL- Set tohttps://natca-prod.us.auth0.com -
DISCORD_TOKEN- Bot token from Discord Developer Portal -
DISCORD_CLIENT_ID- Application ID from Discord Developer Portal -
DISCORD_GUILD_ID- Server ID where bot will operate -
SUPABASE_URL- Supabase project URL -
SUPABASE_KEY- Supabase service role key -
NODE_ENV- Set toproduction
Platform API Application
-
SUPABASE_URL- Supabase project URL -
SUPABASE_KEY- Supabase service role key -
MYSQL_HOST- MySQL host address -
MYSQL_USER- MySQL username -
MYSQL_PASS- MySQL password -
MYSQL_DB- MySQL database name -
NODE_ENV- Set toproduction -
RACKSPACE_API_KEY- Rackspace Email API key -
RACKSPACE_SECRET_KEY- Rackspace Email secret key -
RACKSPACE_CUSTOMER_ID- Rackspace customer account number -
INTERCOM_ACCESS_TOKEN- Intercom API access token
🔧 Configuration Verification
Auth0 Application Settings
- Callback URLs include production URL:
https://discord.mynatca.org/api/auth/callback - Logout URLs include production URL:
https://discord.mynatca.org/api/auth/logout - Web Origins include production URL:
https://discord.mynatca.org - Grant Types include Authorization Code and Refresh Token
Discord Application Settings
- OAuth2 Redirect URLs include:
https://discord.mynatca.org/api/auth/callback - Interactions Endpoint URL set to:
https://discord.mynatca.org/api/interactions - Bot Token is valid and has required permissions
- Application ID matches
DISCORD_CLIENT_ID
Database Configuration
- Supabase project is accessible from production
- Exposed schemas include
discordanddiscord_devin Supabase Dashboard > Settings > API - MySQL connection works from deployment environment
- Row Level Security policies are configured correctly
- Database schema matches latest migrations
- Schema organization properly separated (dev, discord_dev, public, discord)
- Production schema migrations applied for positions table (enddate column, unique constraint)
- Data sync completed from MySQL to Supabase production schema
🚀 Deployment Process Verification
Pre-Deployment Tests
# 1. Verify environment variables
vercel env ls | grep -E "(AUTH0_SECRET|DISCORD_TOKEN|SUPABASE)"
# 2. Test configuration locally
vercel dev --listen 3000
curl http://localhost:3000/api/health
# 3. Run deployment with verification
vercel --prod --confirm
# 4. Wait for deployment to complete
# 5. Verify deployment URL is accessible
curl -I https://discord.mynatca.org/api/healthPost-Deployment Verification
# 1. Health check
curl https://discord.mynatca.org/api/health
# Expected: 200 OK with health status
# 2. Auth endpoints
curl -I https://discord.mynatca.org/api/auth/login
# Expected: 302 redirect to Auth0
# 3. Database connectivity
curl https://discord.mynatca.org/api/sync/status
# Expected: 200 OK with sync status
# 4. Discord bot functionality
# Test /register command in Discord
# Verify verification flow works end-to-end❌ Common Deployment Failures
"secret" is required Error
Cause: Missing AUTH0_SECRET environment variable
Solution: Generate and set AUTH0_SECRET:
openssl rand -hex 32
vercel env add AUTH0_SECRET productionSessions Not Persisting After Login (CRITICAL)
Cause: Missing trust proxy configuration when deployed behind reverse proxy
Symptoms:
- Users authenticate successfully but immediately logged out
- Sessions work on localhost but fail on production
- Secure cookies not being set
Solution: Add trust proxy configuration to server.js:
// Add BEFORE session middleware
app.set('trust proxy', 1);For Digital Ocean App Platform:
// server.js
const app = express();
// Trust Digital Ocean's reverse proxy
app.set('trust proxy', 1);
app.use(session({
cookie: {
secure: process.env.NODE_ENV === 'production' // Now works correctly
}
}));Verification:
# Test that secure cookie is set
curl -c cookies.txt -v https://platform.natca.org/api/auth/login 2>&1 | grep -i set-cookie
# Should see: Set-Cookie: platform.session=...; Secure; HttpOnlyDatabase Connection Failures
Cause: Incorrect database credentials or network access Solution: Verify database environment variables and network access
Discord Bot Not Responding
Cause: Incorrect Discord token or permissions
Solution: Verify DISCORD_TOKEN and bot permissions in Discord server
Auth0 Callback Errors
Cause: Misconfigured callback URLs in Auth0 dashboard Solution: Update Auth0 application settings with production URLs
Discord Bot Schema Access Errors
Cause: Discord/discord_dev schemas not exposed in Supabase Symptoms:
- "relation 'discord.verification_requests' does not exist"
- Discord bot cannot access verification tables
- 404 errors when querying Discord-specific tables
Solution: Expose required schemas in Supabase:
- Navigate to Supabase Dashboard > Settings > API
- Scroll to "Exposed schemas" section
- Add
discordanddiscord_devto the list - Save changes and redeploy Discord bot
Verification:
# Test schema access
curl https://your-project.supabase.co/rest/v1/discord.verification_requests \
-H "apikey: your_anon_key" \
-H "Authorization: Bearer your_service_key"
# Should return data or empty array, not 404🔒 Security Verification
Environment Security
- Different secrets for staging and production environments
- Secure random generation for
AUTH0_SECRET(minimum 32 characters) - No hardcoded secrets in source code
- Production-only access to production databases
Network Security
- HTTPS enabled for all production URLs
- Secure headers configured in deployment
- CORS settings properly configured
- Rate limiting enabled for API endpoints
📋 Database Migration and Sync Checklist
Before deploying to production, ensure database schema is up-to-date and data is synced:
Migration Rebaseline Process (October 2025)
The MyNATCA platform underwent a migration rebaseline to clean up old migration files and establish a fresh baseline from production.
What Changed:
- Removed old migration files that were already applied to production
- Created new baseline migration from production schema:
20251024122438_remote_schema.sql - Enables clean
supabase db pushworkflow going forward - Prevents accidental schema changes from old migrations
Migration Strategy:
# 1. Pull current production schema as baseline
supabase db pull
# This creates: supabase/migrations/20251024122438_remote_schema.sql
# This file represents the CURRENT production database state
# 2. For new schema changes, create new migrations after this baseline
supabase migration new add_new_feature
# 3. Apply new migrations to production
supabase db pushImportant Notes:
- Old migrations before
20251024122438_remote_schema.sqlhave been removed - The baseline migration contains the complete production schema as of October 24, 2025
- New migrations should be created after this baseline
- Never manually edit the baseline migration file
Production Schema Migrations
Positions Table Migrations:
These migrations are now included in the baseline, but documented here for reference:
-- 1. Add enddate column (already in baseline)
ALTER TABLE public.positions
ADD COLUMN IF NOT EXISTS enddate DATE;
-- 2. Add unique constraint (already in baseline)
ALTER TABLE public.positions
ADD CONSTRAINT positions_member_position_unique
UNIQUE (membernumber, positiontype);Running Migrations:
# Option 1: Using Supabase CLI (Recommended)
supabase db push
# Option 2: Using psql
psql "postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres" \
-f migrations/add_positions_enddate.sql
# Option 3: Using Supabase SQL Editor
# Navigate to Dashboard > SQL Editor > New Query
# Paste migration SQL and executeVerification:
# Verify enddate column exists
psql -c "\d public.positions"
# Verify unique constraint exists
psql -c "SELECT conname FROM pg_constraint WHERE conrelid = 'public.positions'::regclass;"
# Check migration history
supabase migration listMigration Workflow After Rebaseline:
# 1. Make schema changes locally
# Edit your Supabase schema as needed
# 2. Create a new migration
supabase migration new descriptive_name_of_change
# 3. Test locally
supabase db reset # Applies all migrations including new one
npm run dev # Test your application
# 4. Deploy to production
git add supabase/migrations/
git commit -m "Add new schema migration"
git push
# 5. Apply migration to production
supabase db push --linkedData Synchronization
Initial Production Sync:
# Navigate to platform directory
cd platform
# Run full production sync
node sync/sync-all.js --env=prodExpected Output:
🎯 Syncing to public schema
Syncing regions...
✓ Synced 10 regions
Syncing facilities...
✓ Synced 342 facilities
Syncing members...
✓ Synced 15,234 members
Syncing positions...
✓ Synced 1,247 positions
Syncing teams...
✓ Synced 89 teams
All syncs completed successfully!Individual Table Sync (after initial sync):
# Sync only positions (fast, skips dependencies)
node sync/sync-all.js positions --skip-deps --env=prod
# Sync only members
node sync/sync-all.js members --skip-deps --env=prod
# Sync only teams
node sync/sync-all.js teams --skip-deps --env=prodSync Verification:
# Check record counts
psql -c "SELECT COUNT(*) FROM public.members;"
psql -c "SELECT COUNT(*) FROM public.positions;"
psql -c "SELECT COUNT(*) FROM public.teams;"
# Verify recent sync timestamp
psql -c "SELECT MAX(updated_at) FROM public.members;"📊 Monitoring Setup
Health Monitoring
- Health endpoints accessible:
/api/health - Monitoring alerts configured for downtime
- Performance monitoring enabled
- Error tracking configured (Sentry, etc.)
- Data sync monitoring configured to alert on sync failures
Logging Configuration (Updated October 2025)
- JSON-structured logging enabled on all services
- OpenSearch configured for log aggregation
- Log shipping configured (Filebeat, Fluentd, or direct streaming)
- Index patterns created in OpenSearch Dashboards
- Error logging captures stack traces with context
- Access logs for security monitoring
- Database query logs for performance monitoring
OpenSearch Logging Setup
1. JSON Logging Enabled
Verify all services output JSON logs:
# Discord Bot
docker logs discord-bot | head -1
# Should output: {"timestamp":"...","level":"info","service":"discord-bot",...}
# Platform
docker logs platform | head -1
# Should output: {"timestamp":"...","level":"info","service":"platform",...}2. Log Shipping Configuration
Option A: Filebeat (Recommended)
# filebeat.yml
filebeat.inputs:
- type: container
paths:
- '/var/lib/docker/containers/*/*.log'
json.keys_under_root: true
json.add_error_key: true
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
output.elasticsearch:
hosts: ["opensearch:9200"]
username: "admin"
password: "${OPENSEARCH_PASSWORD}"
indices:
- index: "discord-bot-logs-%{+yyyy.MM.dd}"
when.contains:
container.labels.service: "discord-bot"
- index: "platform-logs-%{+yyyy.MM.dd}"
when.contains:
container.labels.service: "platform"Option B: Fluentd
# fluent.conf
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.pos
tag docker.*
format json
time_key timestamp
time_format %Y-%m-%dT%H:%M:%S.%LZ
</source>
<match docker.**>
@type opensearch
host opensearch
port 9200
user admin
password ${OPENSEARCH_PASSWORD}
index_name logs
logstash_format true
logstash_prefix logs
</match>3. OpenSearch Index Patterns
Create index patterns in OpenSearch Dashboards:
// Discord Bot Index Pattern
{
"index_patterns": ["discord-bot-logs-*"],
"mappings": {
"properties": {
"timestamp": { "type": "date" },
"level": { "type": "keyword" },
"service": { "type": "keyword" },
"message": { "type": "text" },
"context": { "type": "object" },
"error.message": { "type": "text" },
"error.stack": { "type": "text" }
}
}
}
// Platform Index Pattern
{
"index_patterns": ["platform-logs-*"],
"mappings": {
"properties": {
"timestamp": { "type": "date" },
"level": { "type": "keyword" },
"service": { "type": "keyword" },
"message": { "type": "text" },
"context": { "type": "object" },
"error.message": { "type": "text" },
"error.stack": { "type": "text" }
}
}
}4. Verify Log Collection
# Check OpenSearch receiving logs
curl -u admin:password http://opensearch:9200/_cat/indices?v | grep logs
# Query recent logs
curl -u admin:password -X GET "http://opensearch:9200/discord-bot-logs-*/_search?size=10&sort=timestamp:desc"
# Check log count by service
curl -u admin:password -X GET "http://opensearch:9200/logs-*/_search" -H 'Content-Type: application/json' -d'
{
"size": 0,
"aggs": {
"by_service": {
"terms": { "field": "service" }
}
}
}'5. OpenSearch Dashboards
Create visualization dashboards:
- Error Rate: Line chart of error logs over time
- Response Times: Histogram of API response times from context
- Authentication Metrics: Login success/failure rates
- Service Health: Status checks and uptime metrics
Environment Variables for OpenSearch:
# OpenSearch Configuration
OPENSEARCH_HOST=opensearch.natca.org
OPENSEARCH_PORT=9200
OPENSEARCH_USER=admin
OPENSEARCH_PASSWORD=secure_password
OPENSEARCH_INDEX_PREFIX=mynatca-logsCommon Deployment Commands (Updated October 2025)
Platform Commands
Data Synchronization:
# Full production sync (all tables in correct dependency order)
node sync/sync-all.js --env=prod
# Individual table sync with dependencies (syncs base tables first)
node sync/sync-all.js positions --env=prod
node sync/sync-all.js members --env=prod
node sync/sync-all.js teams --env=prod
# Fast re-sync without dependencies (New October 2025)
# Use after initial full sync when only specific table needs updating
node sync/sync-all.js positions --skip-deps --env=prod
node sync/sync-all.js members --skip-deps --env=prod
# View sync help and options
node sync/sync-all.js --helpDevelopment Sync:
# Sync to dev schema (default)
node sync/sync-all.js
# Individual table sync to dev
node sync/sync-all.js positions
node sync/sync-all.js members
node sync/sync-all.js teams
# Fast re-sync to dev without dependencies
node sync/sync-all.js positions --skip-depsSync Command Improvements (October 2025):
- Environment-aware positions sync: Now correctly syncs to
publicschema with--env=prod - Skip dependencies flag: New
--skip-depsoption for faster re-syncs - Schema logging: All syncs now log target schema for verification
- Consistent pattern: All sync scripts follow same environment detection pattern
Discord Bot Commands
Testing:
# Run command test suite
npm test
# Run tests with detailed output
npm run test:verboseDeployment:
# Deploy slash commands to Discord
npm run deploy
# Start bot in production
npm start
# Start bot in development
npm run devTroubleshooting
Common Issues
Data Sync Issues
Sync Targeting Wrong Schema:
# Symptom: Production sync writes to dev schema
# Solution: Verify script respects --env=prod flag
# Check sync output for schema confirmation
node sync/sync-all.js positions --env=prod
# Should show: "🎯 Syncing to public schema"Missing Columns or Constraints:
# Symptom: Sync fails with "column does not exist"
# Solution: Run required migrations first
# Check if migrations needed
psql -c "\d public.positions"
# Run migrations
psql -f migrations/add_positions_enddate.sql
psql -f migrations/add_positions_unique_constraint.sqlForeign Key Constraint Failures:
# Symptom: Sync fails with foreign key violation
# Solution: Sync base tables first or use full sync
# Wrong: Syncing dependent table first
node sync/sync-all.js positions --skip-deps --env=prod # Fails if members not synced
# Correct: Full sync respects dependencies
node sync/sync-all.js --env=prod # Syncs in correct orderDiscord Bot Issues
Commands Not Working for Staff/RNAV:
# Symptom: /status fails for Staff (membertypeid=8) or RNAV (membertypeid=10)
# Solution: Verify query includes all member types
# Correct query should use .in('membertypeid', [6, 8, 10])
# Not .eq('membertypeid', 6)Test Suite Failures:
# Run tests with verbose output
npm run test:verbose
# Check for missing mock data
# Verify test-commands.js has Staff and RNAV test casesFunction Timeout
// Increase timeout in vercel.json
{
"functions": {
"pages/api/sync/**/*.js": {
"maxDuration": 300
}
}
}Environment Variable Issues
# Check environment variables
vercel env ls
# Pull environment variables locally
vercel env pull .env.local
# Add missing variables
vercel env add VARIABLE_NAMEBuild Failures
# Check build logs
vercel logs <deployment-url>
# Debug locally
vercel dev
# Clear build cache
vercel --forceThis comprehensive Vercel deployment guide ensures reliable, scalable deployment of the MyNATCA platform with proper monitoring, security, and performance optimization.