|
| 1 | +# 🚀 EXTERNAL ACTIONS REQUIRED FOR MAPLETENDERS LAUNCH (V2) |
| 2 | + |
| 3 | +**CRITICAL: Complete these steps in EXACT ORDER to launch Mapletenders successfully** |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## 📋 PREREQUISITES CHECKLIST |
| 8 | + |
| 9 | +✅ **Analytics schema migration** - COMPLETED |
| 10 | +⚠️ **All other database schemas** - PENDING |
| 11 | +⚠️ **Environment variables setup** - PENDING |
| 12 | +⚠️ **External services configuration** - PENDING |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## 🗃️ STEP 1: DATABASE SCHEMA SETUP (CRITICAL) |
| 17 | + |
| 18 | +### **Execute in this EXACT ORDER:** |
| 19 | + |
| 20 | +**1.1 Create Core User Tables First** |
| 21 | +```sql |
| 22 | +-- Connect to your Supabase/PostgreSQL database and run: |
| 23 | + |
| 24 | +-- Create users table (if not exists from Supabase Auth) |
| 25 | +CREATE TABLE IF NOT EXISTS users ( |
| 26 | + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 27 | + email VARCHAR(255) UNIQUE NOT NULL, |
| 28 | + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| 29 | + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| 30 | +); |
| 31 | + |
| 32 | +-- Create user profiles table |
| 33 | +CREATE TABLE IF NOT EXISTS profiles ( |
| 34 | + id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, |
| 35 | + email VARCHAR(255), |
| 36 | + full_name VARCHAR(255), |
| 37 | + company_name VARCHAR(255), |
| 38 | + phone VARCHAR(20), |
| 39 | + subscription_tier VARCHAR(50) DEFAULT 'free', |
| 40 | + subscription_status VARCHAR(20) DEFAULT 'inactive', |
| 41 | + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| 42 | + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| 43 | +); |
| 44 | +``` |
| 45 | + |
| 46 | +**1.2 Create Tender Tables** |
| 47 | +```sql |
| 48 | +-- Create tenders table |
| 49 | +CREATE TABLE IF NOT EXISTS tenders ( |
| 50 | + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 51 | + title VARCHAR(500) NOT NULL, |
| 52 | + description TEXT, |
| 53 | + reference_number VARCHAR(255) UNIQUE, |
| 54 | + contracting_entity_name VARCHAR(255), |
| 55 | + category_primary VARCHAR(255), |
| 56 | + category_secondary VARCHAR(255), |
| 57 | + procurement_method VARCHAR(100), |
| 58 | + status VARCHAR(50) DEFAULT 'open', |
| 59 | + published_date TIMESTAMP WITH TIME ZONE, |
| 60 | + closing_date TIMESTAMP WITH TIME ZONE, |
| 61 | + delivery_location VARCHAR(255), |
| 62 | + estimated_value DECIMAL(15,2), |
| 63 | + currency VARCHAR(3) DEFAULT 'CAD', |
| 64 | + source_url VARCHAR(500), |
| 65 | + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| 66 | + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| 67 | +); |
| 68 | + |
| 69 | +-- Add indexes for tenders |
| 70 | +CREATE INDEX IF NOT EXISTS idx_tenders_status ON tenders(status); |
| 71 | +CREATE INDEX IF NOT EXISTS idx_tenders_closing_date ON tenders(closing_date); |
| 72 | +CREATE INDEX IF NOT EXISTS idx_tenders_published_date ON tenders(published_date); |
| 73 | +CREATE INDEX IF NOT EXISTS idx_tenders_category_primary ON tenders(category_primary); |
| 74 | +``` |
| 75 | + |
| 76 | +**1.3 Apply Analytics Schema (ALREADY DONE)** |
| 77 | +✅ You've already completed this step. |
| 78 | + |
| 79 | +**1.4 Create Saved Searches Schema** |
| 80 | +```sql |
| 81 | +-- Now run the saved searches schema (this was failing before) |
| 82 | +-- File: backend/sql/create_saved_searches_table.sql |
| 83 | +psql -h [your-db-host] -U [username] -d [database-name] -f backend/sql/create_saved_searches_table.sql |
| 84 | +``` |
| 85 | + |
| 86 | +**1.5 Create Bookmarks Schema** |
| 87 | +```sql |
| 88 | +-- Create bookmarks table |
| 89 | +CREATE TABLE IF NOT EXISTS bookmarks ( |
| 90 | + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| 91 | + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, |
| 92 | + tender_notice_id UUID NOT NULL REFERENCES tenders(id) ON DELETE CASCADE, |
| 93 | + notes TEXT, |
| 94 | + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| 95 | + UNIQUE(user_id, tender_notice_id) |
| 96 | +); |
| 97 | + |
| 98 | +CREATE INDEX IF NOT EXISTS idx_bookmarks_user_id ON bookmarks(user_id); |
| 99 | +CREATE INDEX IF NOT EXISTS idx_bookmarks_tender_id ON bookmarks(tender_notice_id); |
| 100 | +``` |
| 101 | + |
| 102 | +**1.6 Create Notifications Schema** |
| 103 | +```sql |
| 104 | +-- Run notifications schema |
| 105 | +psql -h [your-db-host] -U [username] -d [database-name] -f backend/sql/create_notifications_tables.sql |
| 106 | +``` |
| 107 | + |
| 108 | +**1.7 Create Calendar Integration Schema** |
| 109 | +```sql |
| 110 | +-- Run calendar schema |
| 111 | +psql -h [your-db-host] -U [username] -d [database-name] -f backend/sql/create_calendar_tables.sql |
| 112 | +``` |
| 113 | + |
| 114 | +**Verification Commands:** |
| 115 | +```sql |
| 116 | +-- Verify all tables exist |
| 117 | +\dt |
| 118 | + |
| 119 | +-- Test critical functions |
| 120 | +SELECT * FROM calculate_user_roi('test-user-id', '2024-01-01', '2024-12-31'); |
| 121 | +SELECT * FROM saved_searches LIMIT 1; |
| 122 | +SELECT * FROM bookmarks LIMIT 1; |
| 123 | +``` |
| 124 | + |
| 125 | +--- |
| 126 | + |
| 127 | +## 🔑 STEP 2: ENVIRONMENT VARIABLES SETUP |
| 128 | + |
| 129 | +### **2.1 Backend Environment Variables** |
| 130 | +Create/update your production `.env` file: |
| 131 | + |
| 132 | +```bash |
| 133 | +# Database |
| 134 | +SUPABASE_URL=your_supabase_project_url |
| 135 | +SUPABASE_ANON_KEY=your_supabase_anon_key |
| 136 | +SUPABASE_SERVICE_KEY=your_supabase_service_role_key |
| 137 | + |
| 138 | +# AI Services |
| 139 | +GEMINI_API_KEY=your_google_gemini_api_key |
| 140 | + |
| 141 | +# Payment Processing |
| 142 | +STRIPE_SECRET_KEY=your_stripe_secret_key |
| 143 | +STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret |
| 144 | + |
| 145 | +# Search Infrastructure |
| 146 | +ELASTICSEARCH_URL=your_elasticsearch_cluster_url |
| 147 | + |
| 148 | +# Application |
| 149 | +FRONTEND_URL=https://your-frontend-domain.com |
| 150 | +NODE_ENV=production |
| 151 | +PORT=4000 |
| 152 | + |
| 153 | +# Calendar Integration (NEW - REQUIRED) |
| 154 | +GOOGLE_CLIENT_ID=your_google_oauth_client_id |
| 155 | +GOOGLE_CLIENT_SECRET=your_google_oauth_client_secret |
| 156 | +GOOGLE_REDIRECT_URI=https://your-backend-api.com/calendar/google/callback |
| 157 | + |
| 158 | +# Notification Services (NEW - REQUIRED) |
| 159 | +RESEND_API_KEY=your_resend_api_key |
| 160 | +TWILIO_ACCOUNT_SID=your_twilio_sid |
| 161 | +TWILIO_AUTH_TOKEN=your_twilio_token |
| 162 | +TWILIO_PHONE_NUMBER=your_twilio_number |
| 163 | +``` |
| 164 | + |
| 165 | +### **2.2 Frontend Environment Variables** |
| 166 | +Create/update your production frontend `.env`: |
| 167 | + |
| 168 | +```bash |
| 169 | +VITE_API_BASE_URL=https://your-backend-api.com |
| 170 | +VITE_SUPABASE_URL=your_supabase_project_url |
| 171 | +VITE_SUPABASE_ANON_KEY=your_supabase_anon_key |
| 172 | +``` |
| 173 | + |
| 174 | +--- |
| 175 | + |
| 176 | +## 📅 STEP 3: GOOGLE CALENDAR OAUTH SETUP |
| 177 | + |
| 178 | +### **3.1 Google Cloud Console Setup** |
| 179 | +1. Go to https://console.cloud.google.com/ |
| 180 | +2. Create project or select existing project |
| 181 | +3. Enable Google Calendar API |
| 182 | +4. Go to "Credentials" → Create OAuth 2.0 Client IDs |
| 183 | +5. Set authorized redirect URIs: |
| 184 | + - `https://your-backend-api.com/calendar/google/callback` |
| 185 | + - `http://localhost:4000/calendar/google/callback` (for development) |
| 186 | + |
| 187 | +### **3.2 Required OAuth Scopes** |
| 188 | +``` |
| 189 | +https://www.googleapis.com/auth/calendar |
| 190 | +https://www.googleapis.com/auth/userinfo.email |
| 191 | +``` |
| 192 | + |
| 193 | +### **3.3 Test OAuth Flow** |
| 194 | +After deployment, visit: `https://your-backend-api.com/calendar/google/auth` |
| 195 | + |
| 196 | +--- |
| 197 | + |
| 198 | +## 🔍 STEP 4: ELASTICSEARCH SETUP |
| 199 | + |
| 200 | +### **4.1 Option A: Elasticsearch Cloud (RECOMMENDED)** |
| 201 | +1. Sign up at https://cloud.elastic.co/ |
| 202 | +2. Create deployment (Canada Central region) |
| 203 | +3. Note cluster URL and credentials |
| 204 | +4. Update `ELASTICSEARCH_URL` environment variable |
| 205 | + |
| 206 | +### **4.2 Required Index Mapping** |
| 207 | +```json |
| 208 | +{ |
| 209 | + "mappings": { |
| 210 | + "properties": { |
| 211 | + "title": {"type": "text", "analyzer": "standard"}, |
| 212 | + "description": {"type": "text", "analyzer": "standard"}, |
| 213 | + "category": {"type": "keyword"}, |
| 214 | + "location": {"type": "keyword"}, |
| 215 | + "value": {"type": "long"}, |
| 216 | + "closing_date": {"type": "date"}, |
| 217 | + "embedding": {"type": "dense_vector", "dims": 768} |
| 218 | + } |
| 219 | + } |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | +## 📧 STEP 5: NOTIFICATION SERVICES SETUP |
| 226 | + |
| 227 | +### **5.1 Resend Email (ALREADY CONFIGURED)** |
| 228 | +✅ Verify your sending domain |
| 229 | +✅ Check DKIM/SPF records |
| 230 | + |
| 231 | +### **5.2 Twilio SMS Setup** |
| 232 | +1. Sign up at https://twilio.com/ |
| 233 | +2. Get Account SID, Auth Token, and Phone Number |
| 234 | +3. Add to environment variables (Step 2.1) |
| 235 | + |
| 236 | +### **5.3 Slack/Teams Integration** |
| 237 | +1. Create Slack app at https://api.slack.com/apps |
| 238 | +2. Enable incoming webhooks |
| 239 | +3. Store webhook URLs in user preferences |
| 240 | + |
| 241 | +--- |
| 242 | + |
| 243 | +## 💳 STEP 6: STRIPE PRODUCTION SETUP |
| 244 | + |
| 245 | +### **6.1 Activate Stripe Account** |
| 246 | +1. Complete business verification |
| 247 | +2. Configure for Canada |
| 248 | +3. Set up tax collection (HST/GST) |
| 249 | +4. Configure subscription webhooks |
| 250 | + |
| 251 | +### **6.2 Test Payment Flows** |
| 252 | +- Test subscription signup |
| 253 | +- Test payment failures |
| 254 | +- Test webhook delivery |
| 255 | + |
| 256 | +--- |
| 257 | + |
| 258 | +## 🚀 STEP 7: DEPLOYMENT |
| 259 | + |
| 260 | +### **7.1 Backend Deployment** |
| 261 | +1. Deploy to your hosting provider (AWS, GCP, DigitalOcean) |
| 262 | +2. Configure Docker containers if using containers |
| 263 | +3. Set up load balancer |
| 264 | +4. Configure auto-scaling |
| 265 | + |
| 266 | +### **7.2 Frontend Deployment** |
| 267 | +1. Deploy to Vercel (recommended) or Netlify |
| 268 | +2. Configure custom domain |
| 269 | +3. Set up CDN for static assets |
| 270 | + |
| 271 | +### **7.3 Database Backup** |
| 272 | +1. Set up automated daily backups |
| 273 | +2. Test restore procedures |
| 274 | +3. Configure point-in-time recovery |
| 275 | + |
| 276 | +--- |
| 277 | + |
| 278 | +## 🔒 STEP 8: SECURITY & SSL |
| 279 | + |
| 280 | +### **8.1 SSL/HTTPS Setup** |
| 281 | +- Ensure HTTPS on all domains |
| 282 | +- Configure proper certificates |
| 283 | +- Set up HSTS headers |
| 284 | + |
| 285 | +### **8.2 Security Headers** |
| 286 | +Add to your web server config: |
| 287 | +```nginx |
| 288 | +add_header X-Frame-Options "SAMEORIGIN"; |
| 289 | +add_header X-Content-Type-Options "nosniff"; |
| 290 | +add_header X-XSS-Protection "1; mode=block"; |
| 291 | +add_header Strict-Transport-Security "max-age=31536000"; |
| 292 | +``` |
| 293 | + |
| 294 | +--- |
| 295 | + |
| 296 | +## 🧪 STEP 9: FINAL TESTING |
| 297 | + |
| 298 | +### **9.1 Critical Path Testing** |
| 299 | +1. User registration/login |
| 300 | +2. Search functionality |
| 301 | +3. Bookmark system |
| 302 | +4. Analytics dashboard |
| 303 | +5. Payment processing |
| 304 | +6. Calendar integration |
| 305 | + |
| 306 | +### **9.2 Load Testing** |
| 307 | +- Test with 100+ concurrent users |
| 308 | +- Verify database performance |
| 309 | +- Test search response times |
| 310 | + |
| 311 | +--- |
| 312 | + |
| 313 | +## ✅ COMPLETION CHECKLIST |
| 314 | + |
| 315 | +### **Infrastructure (Manual Setup Required)** |
| 316 | +- [ ] Database schemas created in correct order |
| 317 | +- [ ] Environment variables configured |
| 318 | +- [ ] Google Calendar OAuth configured |
| 319 | +- [ ] Elasticsearch cluster setup |
| 320 | +- [ ] Notification services configured |
| 321 | +- [ ] Stripe production setup |
| 322 | +- [ ] SSL/HTTPS configured |
| 323 | +- [ ] Backup procedures tested |
| 324 | + |
| 325 | +### **Technical (Automated - Already Complete)** |
| 326 | +- [x] Frontend builds successfully |
| 327 | +- [x] Backend builds successfully |
| 328 | +- [x] All APIs connected to real data |
| 329 | +- [x] Authentication working |
| 330 | +- [x] TypeScript compilation clean |
| 331 | +- [x] Critical bugs fixed |
| 332 | + |
| 333 | +--- |
| 334 | + |
| 335 | +## 🚀 LAUNCH TIMELINE |
| 336 | + |
| 337 | +### **Phase 1: Infrastructure (Days 1-2)** |
| 338 | +- [ ] Complete database setup (Step 1) |
| 339 | +- [ ] Configure environment variables (Step 2) |
| 340 | +- [ ] Set up Google OAuth (Step 3) |
| 341 | + |
| 342 | +### **Phase 2: Services (Days 2-3)** |
| 343 | +- [ ] Configure Elasticsearch (Step 4) |
| 344 | +- [ ] Set up notifications (Step 5) |
| 345 | +- [ ] Configure Stripe (Step 6) |
| 346 | + |
| 347 | +### **Phase 3: Deployment (Day 3)** |
| 348 | +- [ ] Deploy backend and frontend (Step 7) |
| 349 | +- [ ] Configure security (Step 8) |
| 350 | +- [ ] Run final testing (Step 9) |
| 351 | + |
| 352 | +--- |
| 353 | + |
| 354 | +## 🆘 TROUBLESHOOTING |
| 355 | + |
| 356 | +### **Common Issues:** |
| 357 | + |
| 358 | +**Database Schema Errors:** |
| 359 | +- Ensure tables are created in order (users → tenders → everything else) |
| 360 | +- Check Supabase auth tables exist first |
| 361 | + |
| 362 | +**Authentication Issues:** |
| 363 | +- Verify Supabase keys are correct |
| 364 | +- Check environment variables are loaded |
| 365 | + |
| 366 | +**API Connection Issues:** |
| 367 | +- Verify backend is running on correct port |
| 368 | +- Check CORS configuration |
| 369 | +- Ensure SSL certificates are valid |
| 370 | + |
| 371 | +--- |
| 372 | + |
| 373 | +**CURRENT STATUS: 99% Complete - Only Manual Setup Remaining** |
| 374 | + |
| 375 | +**Estimated Time to Launch: 2-3 Days** ⚡ |
| 376 | + |
| 377 | +*Last Updated: January 2025* |
0 commit comments