Skip to content

Deployment Procedures

Safe deployment workflow cho 3 services


Architecture Overview

ServiceTypeDomainSource
LandingCloudflare Pagessalehay.comlanding/distsalehay-landing
AdminCloudflare Pagesapp.salehay.comadmin/distsalehay-admin
APICloudflare Workerapi.salehay.comapi/saleagent Worker
DocsCloudflare Pagesdev.salehay.comdocs/.vitepress/distsalehay-docs-internal
AffiliateCloudflare Pagesaff.salehay.comaff/distsalehay-aff

5-Phase Deployment Process

Phase 1: PREPARE

bash
# 1. Pull latest code
git pull origin main

# 2. Check for uncommitted changes
git status

# 3. Run test gate
cd api && npm run test:gate
cd ../admin && npm run test:gate
cd ../landing && npm run test:gate

Phase 2: BACKUP

bash
# Database: Neon auto-snapshots (check console)
# Config: Ensure wrangler.toml is committed
# Note: Cloudflare Pages keeps deployment history — easy rollback

Phase 3: DEPLOY

Deploy Order: API → Admin → Landing (dependencies first)

bash
# API (backend changes)
cd api && npx wrangler deploy

# Admin (admin UI changes)  
cd admin && npm run build && npx wrangler pages deploy dist \
  --project-name=salehay-admin --commit-dirty=true

# Landing (landing page changes)
cd landing && npm run build && npx wrangler pages deploy dist \
  --project-name=salehay-landing --commit-dirty=true

# Docs (documentation changes)
cd docs && npm run deploy:internal

Phase 4: VERIFY

CheckCommand/ActionExpected
API healthcurl https://api.salehay.com/api/health{"status":"ok"}
Landing pageOpen salehay.comHero text visible
Admin loginOpen app.salehay.com/loginLogin form loads
Affiliate portalOpen aff.salehay.comLogin form loads
CORS checkLogin from admin → no errorsNo CORS errors in console
Docs siteOpen dev.salehay.comDocs homepage loads

Phase 5: CONFIRM or ROLLBACK

If verification passes:

  • ✅ Confirm deployment
  • Update CHANGELOG.md if applicable
  • Notify team (if applicable)

If verification fails:

  • ❌ Rollback immediately via Cloudflare Pages dashboard → select previous deployment
  • For API Worker: cd api && npx wrangler rollback
  • Investigate before re-deploying

Service-Specific Notes

API Worker

  • Secrets: Set via npx wrangler secret put <NAME>
    • DATABASE_URL, JWT_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, RESEND_API_KEY, EMAIL_FROM
  • DO NOT add [assets] to wrangler.toml — API is API-only
  • DO NOT add salehay.com/* route — conflicts with Pages

Admin SPA

  • API_BASEhttps://api.salehay.com (in src/lib/api.js)
  • CORS must include app.salehay.com in API Worker

Landing Page

  • Login links → external <a> to https://app.salehay.com/login
  • Not <Link> (different SPA)

Emergency Procedures

ScenarioAction
API downCheck Cloudflare dashboard → Worker status. Rollback if needed.
Database errorCheck Neon console → branch health. Point-in-time recovery available.
CORS error after deployCheck ALLOWED_ORIGINS in api/src/index.js. Redeploy API.
Landing page 404Check Cloudflare Pages deployment logs. Ensure dist/ was correctly built.
Partial deploy (only 1 service)All services are independent — partial deploy is normal and expected.

Deploy Frequency

TypeFrequencyProcess
Hotfix (bug fix)As neededSkip test gate if critical, but verify after deploy
Feature release1-2x per weekFull 5-phase process
Content update (docs)Anytimenpm run deploy:internal only
Database migrationCarefulTest on Neon branch first, then merge

SaleHay Business — Internal Use Only