@gv-sh/specgen-app 0.6.6 โ†’ 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SpecGen App - Complete Platform
2
2
 
3
- [![Version](https://img.shields.io/badge/version-0.6.6-blue.svg)](https://github.com/gv-sh/specgen-app)
3
+ [![Version](https://img.shields.io/badge/version-0.6.7-blue.svg)](https://github.com/gv-sh/specgen-app)
4
4
 
5
5
  A unified deployment package for the SpecGen speculative fiction generator platform. **Optimized for port 8080 deployment with low memory usage.**
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gv-sh/specgen-app",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "Complete SpecGen application with server, admin, and user interfaces",
5
5
  "main": "index.js",
6
6
  "bin": {
package/scripts/deploy.sh CHANGED
@@ -25,13 +25,7 @@ check_port() {
25
25
  }
26
26
 
27
27
  # Get absolute path of current working directory
28
- # In dry-run, use the actual working directory, not NPX cache
29
- if [ "$DRY_RUN" = true ]; then
30
- PROJECT_DIR=$(pwd)
31
- else
32
- PROJECT_DIR=$(pwd)
33
- fi
34
-
28
+ PROJECT_DIR=$(pwd)
35
29
  echo "๐Ÿ“‚ Project directory: $PROJECT_DIR"
36
30
 
37
31
  # ========================================
@@ -43,14 +37,19 @@ PLATFORM=$(uname -s)
43
37
  if [ "$PLATFORM" = "Darwin" ]; then
44
38
  echo "๐ŸŽ Detected macOS"
45
39
  PM2_CMD="npx pm2"
40
+ BIND_HOST="127.0.0.1" # macOS - bind to localhost for testing
46
41
  elif [ "$PLATFORM" = "Linux" ]; then
47
42
  echo "๐Ÿง Detected Linux"
48
43
  PM2_CMD="npx pm2"
44
+ BIND_HOST="0.0.0.0" # Linux - bind to all interfaces for public access
49
45
  else
50
46
  echo "โš ๏ธ Unknown platform: $PLATFORM"
51
47
  PM2_CMD="npx pm2"
48
+ BIND_HOST="0.0.0.0"
52
49
  fi
53
50
 
51
+ echo "๐ŸŒ Server will bind to: $BIND_HOST"
52
+
54
53
  # ========================================
55
54
  # CLEANUP (Skip in dry-run for safety)
56
55
  # ========================================
@@ -79,7 +78,6 @@ if [ "$DRY_RUN" = false ]; then
79
78
  rm -rf logs/* 2>/dev/null || true
80
79
  else
81
80
  echo "๐Ÿงช DRY RUN: Skipping cleanup (existing processes will remain)"
82
- echo " This is a safe test that won't affect your system"
83
81
  fi
84
82
 
85
83
  # ========================================
@@ -88,74 +86,39 @@ fi
88
86
 
89
87
  echo "๐Ÿ” Checking prerequisites..."
90
88
 
91
- # Check Node.js version (more lenient for dry-run)
89
+ # Check Node.js version
92
90
  NODE_VERSION=$(node --version | sed 's/v//' | cut -d. -f1)
93
91
  if [ "$DRY_RUN" = true ]; then
94
- # More lenient for dry-run testing
95
92
  if [ "$NODE_VERSION" -lt 18 ]; then
96
93
  echo "โŒ Node.js 18+ required for testing. Current version: $(node --version)"
97
- if [ "$PLATFORM" = "Darwin" ]; then
98
- echo "Install with: brew install node"
99
- fi
100
94
  exit 1
101
95
  else
102
- echo "โœ… Node.js version: $(node --version) (sufficient for testing)"
103
- if [ "$NODE_VERSION" -lt 20 ]; then
104
- echo " โš ๏ธ Note: Production deployment requires Node.js 20+"
105
- fi
96
+ echo "โœ… Node.js version: $(node --version)"
106
97
  fi
107
98
  else
108
- # Strict for production
109
99
  if [ "$NODE_VERSION" -lt 20 ]; then
110
100
  echo "โŒ Node.js 20+ required for production. Current version: $(node --version)"
111
- if [ "$PLATFORM" = "Darwin" ]; then
112
- echo "Install with: brew install node@20"
113
- else
114
- echo "Install with: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs"
115
- fi
116
101
  exit 1
117
102
  else
118
103
  echo "โœ… Node.js version: $(node --version)"
119
104
  fi
120
105
  fi
121
106
 
122
- # Check npm
123
107
  echo "โœ… npm version: $(npm --version)"
124
108
 
125
- # Check available memory
126
- if [ "$PLATFORM" = "Darwin" ]; then
127
- MEMORY_GB=$(sysctl -n hw.memsize | awk '{print int($1/1024/1024/1024)}')
128
- echo "โœ… Available memory: ${MEMORY_GB}GB"
129
- if [ "$MEMORY_GB" -lt 4 ]; then
130
- echo "โš ๏ธ Warning: Less than 4GB RAM detected. Builds may be slow."
131
- fi
132
- elif [ "$PLATFORM" = "Linux" ]; then
133
- MEMORY_GB=$(free -g | awk '/^Mem:/{print $2}')
134
- echo "โœ… Available memory: ${MEMORY_GB}GB"
135
- if [ "$MEMORY_GB" -lt 1 ]; then
136
- echo "โš ๏ธ Warning: Less than 1GB RAM detected. Consider adding swap space."
137
- fi
138
- fi
139
-
140
- # Check if we have required tools
141
- echo "โœ… Platform tools:"
142
- echo " curl: $(which curl >/dev/null && echo "available" || echo "missing")"
143
- echo " tar: $(which tar >/dev/null && echo "available" || echo "missing")"
144
- echo " lsof: $(which lsof >/dev/null && echo "available" || echo "missing")"
145
-
146
109
  # ========================================
147
110
  # SETUP OPENAI API KEY
148
111
  # ========================================
149
112
 
150
113
  echo "๐Ÿ”‘ Setting up OpenAI API key..."
151
114
 
152
- # In dry-run mode, always use a test key
153
115
  if [ "$DRY_RUN" = true ]; then
154
116
  echo "๐Ÿงช DRY RUN: Using test API key"
155
117
  mkdir -p "$PROJECT_DIR/server"
156
118
  echo "OPENAI_API_KEY=sk-test1234567890abcdef" > "$PROJECT_DIR/server/.env"
157
119
  echo "NODE_ENV=production" >> "$PROJECT_DIR/server/.env"
158
120
  echo "PORT=8080" >> "$PROJECT_DIR/server/.env"
121
+ echo "HOST=$BIND_HOST" >> "$PROJECT_DIR/server/.env"
159
122
  elif [ ! -f "$PROJECT_DIR/server/.env" ] || grep -q "your_openai_api_key_here" "$PROJECT_DIR/server/.env" 2>/dev/null; then
160
123
  if [ "$CI" = "true" ]; then
161
124
  echo "CI mode - using test API key"
@@ -163,6 +126,7 @@ elif [ ! -f "$PROJECT_DIR/server/.env" ] || grep -q "your_openai_api_key_here" "
163
126
  echo "OPENAI_API_KEY=sk-test1234" > "$PROJECT_DIR/server/.env"
164
127
  echo "NODE_ENV=production" >> "$PROJECT_DIR/server/.env"
165
128
  echo "PORT=8080" >> "$PROJECT_DIR/server/.env"
129
+ echo "HOST=$BIND_HOST" >> "$PROJECT_DIR/server/.env"
166
130
  else
167
131
  echo "โš ๏ธ OpenAI API key required for SpecGen to work."
168
132
  echo "Enter your OpenAI API key (or press Enter to use test key): "
@@ -177,6 +141,7 @@ elif [ ! -f "$PROJECT_DIR/server/.env" ] || grep -q "your_openai_api_key_here" "
177
141
  echo "OPENAI_API_KEY=$OPENAI_KEY" > "$PROJECT_DIR/server/.env"
178
142
  echo "NODE_ENV=production" >> "$PROJECT_DIR/server/.env"
179
143
  echo "PORT=8080" >> "$PROJECT_DIR/server/.env"
144
+ echo "HOST=$BIND_HOST" >> "$PROJECT_DIR/server/.env"
180
145
  echo "โœ… API key saved"
181
146
  fi
182
147
  fi
@@ -186,57 +151,34 @@ fi
186
151
  # ========================================
187
152
 
188
153
  echo "๐Ÿ—๏ธ Building application components..."
189
-
190
- # Navigate to project directory
191
154
  cd "$PROJECT_DIR"
192
155
 
193
- # Install and build server with better extraction
156
+ # Install and build server
194
157
  if [ ! -f "server/index.js" ]; then
195
158
  echo "๐Ÿ“ฆ Setting up server..."
196
159
 
197
- # Clean up any existing server directory
198
160
  rm -rf server
199
-
200
- # Download and extract server
201
- echo " Downloading server package..."
202
161
  npm pack @gv-sh/specgen-server --loglevel=warn
203
-
204
- echo " Extracting server package..."
205
162
  tar -xzf gv-sh-specgen-server-*.tgz
206
163
 
207
- # Move the extracted package to server directory
208
164
  if [ -d "package" ]; then
209
165
  mv package server
166
+ rm gv-sh-specgen-server-*.tgz
210
167
  echo "โœ… Server extracted successfully"
211
168
  else
212
169
  echo "โŒ Failed to extract server package"
213
- ls -la
214
170
  exit 1
215
171
  fi
216
172
 
217
- # Clean up the tar file
218
- rm gv-sh-specgen-server-*.tgz
219
-
220
- # Install server dependencies
221
- echo " Installing server dependencies..."
222
173
  cd server
223
174
  echo "engine-strict=false" > .npmrc
224
175
  npm install --no-fund --no-audit --production --maxsockets=2 --loglevel=warn
225
-
226
- # Verify server files
227
- if [ ! -f "index.js" ]; then
228
- echo "โŒ Server index.js not found after installation"
229
- echo "Server directory contents:"
230
- ls -la
231
- exit 1
232
- fi
233
-
234
176
  cd "$PROJECT_DIR"
235
177
 
236
- # Replace with unified server that serves static files
237
- echo " ๐Ÿ”ง Installing unified server for port 8080..."
178
+ # Install unified server that binds to 0.0.0.0
179
+ echo " ๐Ÿ”ง Installing unified server (binds to all interfaces)..."
238
180
  cat > server/index.js << 'EOF'
239
- // index.js - Unified server for port 8080 with proper routing
181
+ // index.js - Unified server for port 8080 with public binding
240
182
  /* global process */
241
183
  require('dotenv').config();
242
184
  const express = require('express');
@@ -246,7 +188,8 @@ const errorHandler = require('./middleware/errorHandler');
246
188
 
247
189
  // Initialize Express app
248
190
  const app = express();
249
- let PORT = process.env.PORT || 8080;
191
+ const PORT = process.env.PORT || 8080;
192
+ const HOST = process.env.HOST || '0.0.0.0'; // Bind to all interfaces by default
250
193
 
251
194
  // Middleware
252
195
  app.use(cors());
@@ -258,34 +201,32 @@ const adminBuildPath = path.join(__dirname, '../admin/build');
258
201
  const fs = require('fs');
259
202
  if (fs.existsSync(adminBuildPath)) {
260
203
  app.use('/admin', express.static(adminBuildPath));
261
- // Handle React Router for admin (catch all admin routes)
262
204
  app.get('/admin/*', (req, res) => {
263
205
  res.sendFile(path.join(adminBuildPath, 'index.html'));
264
206
  });
265
207
  console.log('โœ… Admin interface available at /admin');
266
208
  } else {
267
- console.log('โš ๏ธ Admin build not found at', adminBuildPath);
209
+ console.log('โš ๏ธ Admin build not found');
268
210
  }
269
211
 
270
212
  // Serve static files for user interface at /app
271
213
  const userBuildPath = path.join(__dirname, '../user/build');
272
214
  if (fs.existsSync(userBuildPath)) {
273
215
  app.use('/app', express.static(userBuildPath));
274
- // Handle React Router for user app (catch all app routes)
275
216
  app.get('/app/*', (req, res) => {
276
217
  res.sendFile(path.join(userBuildPath, 'index.html'));
277
218
  });
278
219
  console.log('โœ… User interface available at /app');
279
220
  } else {
280
- console.log('โš ๏ธ User build not found at', userBuildPath);
221
+ console.log('โš ๏ธ User build not found');
281
222
  }
282
223
 
283
- // Serve user interface as default at root (/) as well
224
+ // Serve user interface as default at root
284
225
  if (fs.existsSync(userBuildPath)) {
285
226
  app.use('/', express.static(userBuildPath, { index: false }));
286
227
  }
287
228
 
288
- // Routes
229
+ // API Routes
289
230
  const categoryRoutes = require('./routes/categories');
290
231
  const parameterRoutes = require('./routes/parameters');
291
232
  const generateRoutes = require('./routes/generate');
@@ -293,7 +234,6 @@ const databaseRoutes = require('./routes/database');
293
234
  const contentRoutes = require('./routes/content');
294
235
  const settingsRoutes = require('./routes/settings');
295
236
 
296
- // API Routes
297
237
  app.use('/api/categories', categoryRoutes);
298
238
  app.use('/api/parameters', parameterRoutes);
299
239
  app.use('/api/generate', generateRoutes);
@@ -301,28 +241,24 @@ app.use('/api/database', databaseRoutes);
301
241
  app.use('/api/content', contentRoutes);
302
242
  app.use('/api/settings', settingsRoutes);
303
243
 
304
- // Only add Swagger in non-test environment
305
244
  if (process.env.NODE_ENV !== 'test') {
306
245
  const swaggerRoutes = require('./routes/swagger');
307
246
  app.use('/api-docs', swaggerRoutes);
308
247
  }
309
248
 
310
- // Health check routes
311
249
  const healthRoutes = require('./routes/health');
312
250
  app.use('/api/health', healthRoutes);
313
251
 
314
- // Root route - serve user app or provide navigation
252
+ // Root route
315
253
  app.get('/', (req, res) => {
316
- // If user build exists, serve it
317
254
  if (fs.existsSync(userBuildPath)) {
318
255
  res.sendFile(path.join(userBuildPath, 'index.html'));
319
256
  } else {
320
- // Fallback navigation page
321
257
  const html = `
322
258
  <!DOCTYPE html>
323
259
  <html>
324
260
  <head>
325
- <title>SpecGen - API & Applications</title>
261
+ <title>SpecGen - Running on ${HOST}:${PORT}</title>
326
262
  <style>
327
263
  body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; background: #f8f9fa; }
328
264
  .nav-card { border: 1px solid #dee2e6; border-radius: 8px; padding: 20px; margin: 15px 0; background: white; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
@@ -330,43 +266,35 @@ app.get('/', (req, res) => {
330
266
  a { text-decoration: none; color: #007bff; }
331
267
  h1 { color: #343a40; text-align: center; }
332
268
  .status { color: #28a745; font-weight: bold; text-align: center; background: #d4edda; padding: 10px; border-radius: 5px; margin: 20px 0; }
333
- .footer { text-align: center; margin-top: 30px; color: #6c757d; font-size: 14px; }
334
- .warning { background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; border-radius: 5px; margin: 20px 0; }
269
+ .binding { background: #e3f2fd; border: 1px solid #2196f3; padding: 15px; border-radius: 5px; margin: 20px 0; }
335
270
  </style>
336
271
  </head>
337
272
  <body>
338
273
  <h1>๐Ÿš€ SpecGen Platform</h1>
339
- <div class="status">โœ… All services running on port ${PORT}</div>
274
+ <div class="status">โœ… Server running on ${HOST}:${PORT}</div>
340
275
 
341
- <div class="warning">
342
- <strong>๐Ÿ”’ AWS Security Group Note:</strong> If you can't access this from outside,
343
- add port ${PORT} to your AWS Security Group inbound rules.
276
+ <div class="binding">
277
+ <strong>๐ŸŒ Network Binding:</strong> ${HOST === '0.0.0.0' ? 'Public access enabled (0.0.0.0)' : 'Local access only (' + HOST + ')'}
344
278
  </div>
345
279
 
346
280
  <div class="nav-card">
347
281
  <h3><a href="/app">๐Ÿ“ฑ User Application</a></h3>
348
- <p>Main SpecGen user interface for creating and managing specifications</p>
282
+ <p>Main SpecGen user interface</p>
349
283
  </div>
350
284
 
351
285
  <div class="nav-card">
352
286
  <h3><a href="/admin">โš™๏ธ Admin Panel</a></h3>
353
- <p>Administrative interface for system management and configuration</p>
287
+ <p>Administrative interface</p>
354
288
  </div>
355
289
 
356
290
  <div class="nav-card">
357
291
  <h3><a href="/api-docs">๐Ÿ“š API Documentation</a></h3>
358
- <p>Interactive API documentation and testing interface</p>
292
+ <p>Interactive API documentation</p>
359
293
  </div>
360
294
 
361
295
  <div class="nav-card">
362
296
  <h3><a href="/api/health">โค๏ธ Health Check</a></h3>
363
- <p>System health and status monitoring endpoint</p>
364
- </div>
365
-
366
- <div class="footer">
367
- <p><strong>API Base URL:</strong> <code>http://your-server:${PORT}/api</code></p>
368
- <p><strong>Environment:</strong> ${process.env.NODE_ENV || 'development'}</p>
369
- <p><strong>Server Time:</strong> ${new Date().toISOString()}</p>
297
+ <p>System health monitoring</p>
370
298
  </div>
371
299
  </body>
372
300
  </html>`;
@@ -374,234 +302,103 @@ app.get('/', (req, res) => {
374
302
  }
375
303
  });
376
304
 
377
- // Error handling middleware
378
305
  app.use(errorHandler);
379
306
 
380
307
  if (require.main === module) {
381
- app.listen(PORT, () => {
382
- console.log(`๐Ÿš€ SpecGen unified server running on port ${PORT}`);
383
- console.log(`๐Ÿ“ฑ User App: http://localhost:${PORT}/app`);
384
- console.log(`โš™๏ธ Admin Panel: http://localhost:${PORT}/admin`);
385
- console.log(`๐Ÿ“š API Docs: http://localhost:${PORT}/api-docs`);
386
- console.log(`โค๏ธ Health Check: http://localhost:${PORT}/api/health`);
387
- console.log(`๐Ÿ  Main Page: http://localhost:${PORT}/`);
388
- console.log(`๐Ÿ”’ AWS Note: Ensure port ${PORT} is open in Security Groups`);
389
- if (process.env.NODE_ENV !== 'test') {
390
- console.log(`- API Documentation: http://localhost:${PORT}/api-docs`);
308
+ app.listen(PORT, HOST, () => {
309
+ console.log(`๐Ÿš€ SpecGen server running on ${HOST}:${PORT}`);
310
+ console.log(`๐Ÿ“ฑ User App: http://${HOST}:${PORT}/app`);
311
+ console.log(`โš™๏ธ Admin Panel: http://${HOST}:${PORT}/admin`);
312
+ console.log(`๐Ÿ“š API Docs: http://${HOST}:${PORT}/api-docs`);
313
+ console.log(`โค๏ธ Health Check: http://${HOST}:${PORT}/api/health`);
314
+
315
+ if (HOST === '0.0.0.0') {
316
+ console.log(`๐ŸŒ Accessible from any IP address`);
317
+ } else {
318
+ console.log(`๐Ÿ  Local access only (${HOST})`);
391
319
  }
392
- console.log(`- API is ready for use`);
393
320
  });
394
321
  }
395
322
 
396
323
  module.exports = app;
397
324
  EOF
398
- echo "โœ… Unified server installed"
325
+ echo "โœ… Unified server installed with public binding"
399
326
  fi
400
327
 
401
- # Install and build admin
402
- if [ ! -d "admin/build" ]; then
403
- echo "๐Ÿ“ฑ Building admin interface..."
404
-
405
- if [ ! -d "admin" ]; then
406
- # Clean up any existing admin directory
407
- rm -rf admin
408
-
409
- echo " Downloading admin package..."
410
- npm pack @gv-sh/specgen-admin --loglevel=warn
411
- tar -xzf gv-sh-specgen-admin-*.tgz
328
+ # Build admin and user (shortened for brevity)
329
+ for component in admin user; do
330
+ if [ ! -d "$component/build" ]; then
331
+ echo "๐Ÿ“ฑ Building $component interface..."
412
332
 
413
- if [ -d "package" ]; then
414
- mv package admin
415
- echo "โœ… Admin extracted successfully"
416
- else
417
- echo "โŒ Failed to extract admin package"
418
- exit 1
333
+ if [ ! -d "$component" ]; then
334
+ npm pack @gv-sh/specgen-$component --loglevel=warn
335
+ tar -xzf gv-sh-specgen-$component-*.tgz
336
+ mv package $component
337
+ rm gv-sh-specgen-$component-*.tgz
419
338
  fi
420
339
 
421
- rm gv-sh-specgen-admin-*.tgz
422
- fi
423
-
424
- echo " Installing admin dependencies..."
425
- cd admin
426
- echo "engine-strict=false" > .npmrc
427
- # Install ALL dependencies for build process
428
- npm install --no-fund --no-audit --maxsockets=2 --loglevel=warn
429
- echo " Building admin interface..."
430
- # Build with proper environment variables
431
- GENERATE_SOURCEMAP=false SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/admin npm run build
432
- cd "$PROJECT_DIR"
433
- fi
434
-
435
- # Install and build user
436
- if [ ! -d "user/build" ]; then
437
- echo "๐Ÿ‘ค Building user interface..."
438
-
439
- if [ ! -d "user" ]; then
440
- # Clean up any existing user directory
441
- rm -rf user
442
-
443
- echo " Downloading user package..."
444
- npm pack @gv-sh/specgen-user --loglevel=warn
445
- tar -xzf gv-sh-specgen-user-*.tgz
340
+ cd $component
341
+ echo "engine-strict=false" > .npmrc
342
+ npm install --no-fund --no-audit --maxsockets=2 --loglevel=warn
446
343
 
447
- if [ -d "package" ]; then
448
- mv package user
449
- echo "โœ… User extracted successfully"
344
+ if [ "$component" = "admin" ]; then
345
+ GENERATE_SOURCEMAP=false SKIP_PREFLIGHT_CHECK=true PUBLIC_URL=/admin npm run build
450
346
  else
451
- echo "โŒ Failed to extract user package"
452
- exit 1
347
+ GENERATE_SOURCEMAP=false SKIP_PREFLIGHT_CHECK=true REACT_APP_API_URL=/api PUBLIC_URL=/app npm run build
453
348
  fi
454
-
455
- rm gv-sh-specgen-user-*.tgz
349
+ cd "$PROJECT_DIR"
456
350
  fi
457
-
458
- echo " Installing user dependencies..."
459
- cd user
460
- echo "engine-strict=false" > .npmrc
461
- # Install ALL dependencies for build process
462
- npm install --no-fund --no-audit --maxsockets=2 --loglevel=warn
463
- echo " Building user interface..."
464
- # Build with proper environment variables
465
- GENERATE_SOURCEMAP=false SKIP_PREFLIGHT_CHECK=true REACT_APP_API_URL=/api PUBLIC_URL=/app npm run build
466
- cd "$PROJECT_DIR"
467
- fi
351
+ done
468
352
 
469
353
  # ========================================
470
354
  # VERIFY BUILDS
471
355
  # ========================================
472
356
 
473
357
  echo "โœ… Verifying builds..."
474
-
475
- # Check admin build
476
- if [ ! -d "$PROJECT_DIR/admin/build" ]; then
477
- echo "โŒ Admin build failed"
478
- ls -la "$PROJECT_DIR/admin/" || echo "Admin directory not found"
358
+ if [ ! -d "admin/build" ] || [ ! -d "user/build" ] || [ ! -f "server/index.js" ]; then
359
+ echo "โŒ Build verification failed"
479
360
  exit 1
480
361
  fi
481
362
 
482
- # Check user build
483
- if [ ! -d "$PROJECT_DIR/user/build" ]; then
484
- echo "โŒ User build failed"
485
- ls -la "$PROJECT_DIR/user/" || echo "User directory not found"
486
- exit 1
487
- fi
488
-
489
- # Check server
490
- if [ ! -f "$PROJECT_DIR/server/index.js" ]; then
491
- echo "โŒ Server index.js not found"
492
- echo "Server directory contents:"
493
- ls -la "$PROJECT_DIR/server/" || echo "Server directory not found"
494
- exit 1
495
- fi
496
-
497
- echo "๐Ÿ“ Build verification:"
498
- echo " Admin build: $(ls -la "$PROJECT_DIR/admin/build/" | wc -l) files"
499
- echo " User build: $(ls -la "$PROJECT_DIR/user/build/" | wc -l) files"
500
- echo " Server files: $(ls -la "$PROJECT_DIR/server/" | wc -l) files"
501
- echo " โœ… Server script: $PROJECT_DIR/server/index.js"
502
-
503
- # Show some sample files to verify builds
504
- echo "๐Ÿ“„ Key files found:"
505
- echo " Admin: $(ls "$PROJECT_DIR/admin/build/" | grep -E '\.(html|js|css)$' | head -3 | tr '\n' ' ')"
506
- echo " User: $(ls "$PROJECT_DIR/user/build/" | grep -E '\.(html|js|css)$' | head -3 | tr '\n' ' ')"
507
- echo " Server: $(ls "$PROJECT_DIR/server/" | grep -E '\.(js|json)$' | head -3 | tr '\n' ' ')"
363
+ echo "๐Ÿ“ All builds completed successfully"
508
364
 
509
365
  # ========================================
510
- # DEPLOYMENT / TEST SERVER
366
+ # DEPLOYMENT
511
367
  # ========================================
512
368
 
513
369
  if [ "$DRY_RUN" = true ]; then
514
- echo ""
515
370
  echo "๐Ÿงช DRY RUN: Testing server startup..."
516
-
517
- # Test if the server can start
518
371
  cd "$PROJECT_DIR"
372
+ cp server/.env .env 2>/dev/null || true
519
373
 
520
- # Copy environment
521
- cp "$PROJECT_DIR/server/.env" "$PROJECT_DIR/.env" 2>/dev/null || true
522
-
523
- # Check if port 8080 is available for testing
524
- if ! check_port 8080; then
525
- echo " โš ๏ธ Port 8080 is in use, testing on port 8081 instead"
374
+ TEST_PORT=8080
375
+ if ! check_port $TEST_PORT; then
526
376
  TEST_PORT=8081
527
- sed -i.bak 's/PORT=8080/PORT=8081/' "$PROJECT_DIR/server/.env"
528
- else
529
- TEST_PORT=8080
530
377
  fi
531
378
 
532
- echo " Starting test server on port $TEST_PORT for 10 seconds..."
533
-
534
- # Start server in background
535
- (cd server && NODE_ENV=production PORT=$TEST_PORT node index.js) &
379
+ echo " Starting test server on $BIND_HOST:$TEST_PORT for 10 seconds..."
380
+ (cd server && NODE_ENV=production PORT=$TEST_PORT HOST=$BIND_HOST node index.js) &
536
381
  SERVER_PID=$!
537
382
 
538
- # Wait a bit for server to start
539
383
  sleep 3
540
384
 
541
- # Test the endpoints
542
- echo " Testing endpoints on port $TEST_PORT:"
543
-
385
+ echo " Testing endpoints:"
544
386
  if curl -s http://localhost:$TEST_PORT/api/health >/dev/null 2>&1; then
545
387
  echo " โœ… Health endpoint: OK"
546
- HEALTH_RESPONSE=$(curl -s http://localhost:$TEST_PORT/api/health)
547
- echo " Status: $(echo $HEALTH_RESPONSE | grep -o '"status":"[^"]*"' | cut -d'"' -f4)"
548
388
  else
549
389
  echo " โŒ Health endpoint: FAILED"
550
390
  fi
551
391
 
552
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/ 2>/dev/null || echo "000")
553
- echo " ๐Ÿ“„ Main page: HTTP $HTTP_CODE"
554
-
555
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/admin/ 2>/dev/null || echo "000")
556
- echo " โš™๏ธ Admin page: HTTP $HTTP_CODE"
557
-
558
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/app/ 2>/dev/null || echo "000")
559
- echo " ๐Ÿ‘ค User page: HTTP $HTTP_CODE"
560
-
561
- # Stop test server
562
- sleep 2
563
392
  kill $SERVER_PID 2>/dev/null || true
564
393
  wait $SERVER_PID 2>/dev/null || true
565
394
 
566
- # Restore original .env if we changed it
567
- if [ -f "$PROJECT_DIR/server/.env.bak" ]; then
568
- mv "$PROJECT_DIR/server/.env.bak" "$PROJECT_DIR/server/.env"
569
- fi
570
-
571
395
  echo ""
572
396
  echo "๐ŸŽ‰ DRY RUN COMPLETED!"
573
- echo ""
574
- echo "๐Ÿ“Š Summary:"
575
- echo " โœ… All packages downloaded and extracted"
576
- echo " โœ… All dependencies installed"
577
- echo " โœ… React apps built successfully"
578
- echo " โœ… Unified server installed"
579
- echo " โœ… Server can start and respond"
580
- echo ""
581
- if [ "$NODE_VERSION" -lt 20 ]; then
582
- echo "โš ๏ธ Note for AWS deployment:"
583
- echo " Your Mac has Node.js $(node --version)"
584
- echo " AWS deployment requires Node.js 20+"
585
- echo " Make sure your AWS server has the right version"
586
- echo ""
587
- fi
588
397
  echo "๐Ÿš€ Ready for production deployment!"
589
- echo " Deploy to AWS with: npx @gv-sh/specgen-app deploy"
590
- echo ""
591
- echo "๐Ÿ”’ AWS Deployment Notes:"
592
- echo " 1. Ensure Node.js 20+ on your AWS instance"
593
- echo " 2. Add port 8080 to Security Group inbound rules"
594
- echo " 3. Run: npx @gv-sh/specgen-app deploy"
595
- echo ""
596
- echo "๐Ÿ”ง To test locally right now:"
597
- echo " cd server && npm start"
598
- echo " Open http://localhost:8080/"
599
398
 
600
399
  else
601
- # Real deployment with PM2
602
400
  echo "๐Ÿš€ Starting PM2 deployment..."
603
401
 
604
- # Create PM2 ecosystem configuration with absolute paths
605
402
  cat > "$PROJECT_DIR/ecosystem.config.js" << EOF
606
403
  module.exports = {
607
404
  apps: [{
@@ -610,7 +407,8 @@ module.exports = {
610
407
  cwd: '$PROJECT_DIR',
611
408
  env: {
612
409
  NODE_ENV: 'production',
613
- PORT: 8080
410
+ PORT: 8080,
411
+ HOST: '$BIND_HOST'
614
412
  },
615
413
  instances: 1,
616
414
  exec_mode: 'fork',
@@ -619,59 +417,25 @@ module.exports = {
619
417
  out_file: '$PROJECT_DIR/logs/out.log',
620
418
  log_file: '$PROJECT_DIR/logs/combined.log',
621
419
  time: true,
622
- watch: false,
623
- ignore_watch: ['node_modules', 'logs', '*.log'],
624
- restart_delay: 1000,
625
- max_restarts: 10,
626
- min_uptime: '10s'
420
+ watch: false
627
421
  }]
628
422
  }
629
423
  EOF
630
424
 
631
- # Create logs directory
632
- mkdir -p "$PROJECT_DIR/logs"
633
-
634
- # Copy .env to project root for PM2
635
- cp "$PROJECT_DIR/server/.env" "$PROJECT_DIR/.env" 2>/dev/null || true
425
+ mkdir -p logs
426
+ cp server/.env .env 2>/dev/null || true
636
427
 
637
- # Final port check
638
428
  if ! check_port 8080; then
639
- echo "Port 8080 occupied, force cleaning..."
640
429
  lsof -ti:8080 | xargs kill -9 2>/dev/null || true
641
430
  sleep 2
642
431
  fi
643
432
 
644
- # Start with PM2
645
- cd "$PROJECT_DIR"
646
- echo "โ–ถ๏ธ Starting SpecGen with PM2..."
647
-
648
- NODE_ENV=production PORT=8080 $PM2_CMD start "$PROJECT_DIR/ecosystem.config.js"
433
+ NODE_ENV=production PORT=8080 HOST=$BIND_HOST $PM2_CMD start ecosystem.config.js
649
434
 
650
- # Wait for startup and verify
651
435
  sleep 5
652
436
 
653
- # Verify deployment
654
- echo "๐Ÿ” Verifying deployment..."
655
-
656
437
  if $PM2_CMD list | grep -q "online"; then
657
- echo "Testing endpoints:"
658
-
659
- if curl -s http://localhost:8080/api/health >/dev/null 2>&1; then
660
- echo "โœ… Health endpoint: OK"
661
- else
662
- echo "โŒ Health endpoint: FAILED"
663
- fi
664
-
665
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/ 2>/dev/null)
666
- echo "๐Ÿ“„ Main page: HTTP $HTTP_CODE"
667
-
668
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/admin/ 2>/dev/null)
669
- echo "โš™๏ธ Admin page: HTTP $HTTP_CODE"
670
-
671
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/app/ 2>/dev/null)
672
- echo "๐Ÿ‘ค User page: HTTP $HTTP_CODE"
673
-
674
- PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || curl -s ipecho.net/plain 2>/dev/null || echo 'your-server')
438
+ PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || echo 'your-server')
675
439
 
676
440
  echo ""
677
441
  echo "๐ŸŽ‰ SpecGen deployment completed!"
@@ -680,24 +444,13 @@ EOF
680
444
  echo " - Main page: http://$PUBLIC_IP:8080/"
681
445
  echo " - User app: http://$PUBLIC_IP:8080/app/"
682
446
  echo " - Admin panel: http://$PUBLIC_IP:8080/admin/"
683
- echo " - API docs: http://$PUBLIC_IP:8080/api-docs"
684
- echo " - Health check: http://$PUBLIC_IP:8080/api/health"
685
447
  echo ""
686
- echo "๐Ÿ”’ AWS Security Group:"
687
- echo " If you can't access from outside, add port 8080 to inbound rules:"
688
- echo " EC2 Console โ†’ Security Groups โ†’ Edit Inbound Rules โ†’ Add Rule"
689
- echo " Type: Custom TCP, Port: 8080, Source: 0.0.0.0/0"
690
- echo ""
691
- echo "๐Ÿ“Š Management commands:"
692
- echo " $PM2_CMD status # Check status"
693
- echo " $PM2_CMD logs specgen # View logs"
694
- echo " $PM2_CMD restart specgen # Restart"
448
+ echo "๐Ÿ”ง Binding: Server is bound to $BIND_HOST (${BIND_HOST:+publicly accessible})"
449
+ echo "๐Ÿ“Š Management: npx pm2 status | npx pm2 logs specgen"
695
450
 
696
451
  else
697
- echo ""
698
452
  echo "โŒ Deployment failed!"
699
- echo "๐Ÿ“ Check logs: $PM2_CMD logs specgen"
700
- echo "๐Ÿ“Š Check status: $PM2_CMD status"
453
+ $PM2_CMD logs specgen --lines 10
701
454
  exit 1
702
455
  fi
703
456
  fi