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

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.4-blue.svg)](https://github.com/gv-sh/specgen-app)
3
+ [![Version](https://img.shields.io/badge/version-0.6.6-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.4",
3
+ "version": "0.6.6",
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
@@ -11,10 +11,9 @@ if [ "$1" = "--dry-run" ] || [ "$1" = "-d" ]; then
11
11
  echo "๐Ÿ–ฅ๏ธ Platform: $(uname -s) $(uname -m)"
12
12
  else
13
13
  echo "๐Ÿš€ Deploying SpecGen to production on port 8080..."
14
+ echo "๐Ÿ“ฆ This is a complete deployment - no separate setup needed!"
14
15
  fi
15
16
 
16
- echo "๐Ÿ“ฆ This is a complete deployment - no separate setup needed!"
17
-
18
17
  # Function to check if port is available
19
18
  check_port() {
20
19
  local port=$1
@@ -26,7 +25,13 @@ check_port() {
26
25
  }
27
26
 
28
27
  # Get absolute path of current working directory
29
- PROJECT_DIR=$(pwd)
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
+
30
35
  echo "๐Ÿ“‚ Project directory: $PROJECT_DIR"
31
36
 
32
37
  # ========================================
@@ -74,6 +79,7 @@ if [ "$DRY_RUN" = false ]; then
74
79
  rm -rf logs/* 2>/dev/null || true
75
80
  else
76
81
  echo "๐Ÿงช DRY RUN: Skipping cleanup (existing processes will remain)"
82
+ echo " This is a safe test that won't affect your system"
77
83
  fi
78
84
 
79
85
  # ========================================
@@ -82,18 +88,35 @@ fi
82
88
 
83
89
  echo "๐Ÿ” Checking prerequisites..."
84
90
 
85
- # Check Node.js version
91
+ # Check Node.js version (more lenient for dry-run)
86
92
  NODE_VERSION=$(node --version | sed 's/v//' | cut -d. -f1)
87
- if [ "$NODE_VERSION" -lt 20 ]; then
88
- echo "โŒ Node.js 20+ required. Current version: $(node --version)"
89
- if [ "$PLATFORM" = "Darwin" ]; then
90
- echo "Install with: brew install node@20"
93
+ if [ "$DRY_RUN" = true ]; then
94
+ # More lenient for dry-run testing
95
+ if [ "$NODE_VERSION" -lt 18 ]; then
96
+ 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
+ exit 1
91
101
  else
92
- echo "Install with: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs"
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
93
106
  fi
94
- exit 1
95
107
  else
96
- echo "โœ… Node.js version: $(node --version)"
108
+ # Strict for production
109
+ if [ "$NODE_VERSION" -lt 20 ]; then
110
+ 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
+ exit 1
117
+ else
118
+ echo "โœ… Node.js version: $(node --version)"
119
+ fi
97
120
  fi
98
121
 
99
122
  # Check npm
@@ -114,13 +137,19 @@ elif [ "$PLATFORM" = "Linux" ]; then
114
137
  fi
115
138
  fi
116
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
+
117
146
  # ========================================
118
147
  # SETUP OPENAI API KEY
119
148
  # ========================================
120
149
 
121
150
  echo "๐Ÿ”‘ Setting up OpenAI API key..."
122
151
 
123
- # In dry-run mode, use a test key
152
+ # In dry-run mode, always use a test key
124
153
  if [ "$DRY_RUN" = true ]; then
125
154
  echo "๐Ÿงช DRY RUN: Using test API key"
126
155
  mkdir -p "$PROJECT_DIR/server"
@@ -136,7 +165,7 @@ elif [ ! -f "$PROJECT_DIR/server/.env" ] || grep -q "your_openai_api_key_here" "
136
165
  echo "PORT=8080" >> "$PROJECT_DIR/server/.env"
137
166
  else
138
167
  echo "โš ๏ธ OpenAI API key required for SpecGen to work."
139
- echo "Enter your OpenAI API key (or press Enter to use test key for dry-run): "
168
+ echo "Enter your OpenAI API key (or press Enter to use test key): "
140
169
  read -r OPENAI_KEY
141
170
 
142
171
  if [ -z "$OPENAI_KEY" ]; then
@@ -203,6 +232,170 @@ if [ ! -f "server/index.js" ]; then
203
232
  fi
204
233
 
205
234
  cd "$PROJECT_DIR"
235
+
236
+ # Replace with unified server that serves static files
237
+ echo " ๐Ÿ”ง Installing unified server for port 8080..."
238
+ cat > server/index.js << 'EOF'
239
+ // index.js - Unified server for port 8080 with proper routing
240
+ /* global process */
241
+ require('dotenv').config();
242
+ const express = require('express');
243
+ const cors = require('cors');
244
+ const path = require('path');
245
+ const errorHandler = require('./middleware/errorHandler');
246
+
247
+ // Initialize Express app
248
+ const app = express();
249
+ let PORT = process.env.PORT || 8080;
250
+
251
+ // Middleware
252
+ app.use(cors());
253
+ app.use(express.json());
254
+ app.use(express.urlencoded({ extended: true }));
255
+
256
+ // Serve static files for admin interface at /admin
257
+ const adminBuildPath = path.join(__dirname, '../admin/build');
258
+ const fs = require('fs');
259
+ if (fs.existsSync(adminBuildPath)) {
260
+ app.use('/admin', express.static(adminBuildPath));
261
+ // Handle React Router for admin (catch all admin routes)
262
+ app.get('/admin/*', (req, res) => {
263
+ res.sendFile(path.join(adminBuildPath, 'index.html'));
264
+ });
265
+ console.log('โœ… Admin interface available at /admin');
266
+ } else {
267
+ console.log('โš ๏ธ Admin build not found at', adminBuildPath);
268
+ }
269
+
270
+ // Serve static files for user interface at /app
271
+ const userBuildPath = path.join(__dirname, '../user/build');
272
+ if (fs.existsSync(userBuildPath)) {
273
+ app.use('/app', express.static(userBuildPath));
274
+ // Handle React Router for user app (catch all app routes)
275
+ app.get('/app/*', (req, res) => {
276
+ res.sendFile(path.join(userBuildPath, 'index.html'));
277
+ });
278
+ console.log('โœ… User interface available at /app');
279
+ } else {
280
+ console.log('โš ๏ธ User build not found at', userBuildPath);
281
+ }
282
+
283
+ // Serve user interface as default at root (/) as well
284
+ if (fs.existsSync(userBuildPath)) {
285
+ app.use('/', express.static(userBuildPath, { index: false }));
286
+ }
287
+
288
+ // Routes
289
+ const categoryRoutes = require('./routes/categories');
290
+ const parameterRoutes = require('./routes/parameters');
291
+ const generateRoutes = require('./routes/generate');
292
+ const databaseRoutes = require('./routes/database');
293
+ const contentRoutes = require('./routes/content');
294
+ const settingsRoutes = require('./routes/settings');
295
+
296
+ // API Routes
297
+ app.use('/api/categories', categoryRoutes);
298
+ app.use('/api/parameters', parameterRoutes);
299
+ app.use('/api/generate', generateRoutes);
300
+ app.use('/api/database', databaseRoutes);
301
+ app.use('/api/content', contentRoutes);
302
+ app.use('/api/settings', settingsRoutes);
303
+
304
+ // Only add Swagger in non-test environment
305
+ if (process.env.NODE_ENV !== 'test') {
306
+ const swaggerRoutes = require('./routes/swagger');
307
+ app.use('/api-docs', swaggerRoutes);
308
+ }
309
+
310
+ // Health check routes
311
+ const healthRoutes = require('./routes/health');
312
+ app.use('/api/health', healthRoutes);
313
+
314
+ // Root route - serve user app or provide navigation
315
+ app.get('/', (req, res) => {
316
+ // If user build exists, serve it
317
+ if (fs.existsSync(userBuildPath)) {
318
+ res.sendFile(path.join(userBuildPath, 'index.html'));
319
+ } else {
320
+ // Fallback navigation page
321
+ const html = `
322
+ <!DOCTYPE html>
323
+ <html>
324
+ <head>
325
+ <title>SpecGen - API & Applications</title>
326
+ <style>
327
+ body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; background: #f8f9fa; }
328
+ .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); }
329
+ .nav-card:hover { background-color: #f8f9fa; transform: translateY(-2px); transition: all 0.2s; }
330
+ a { text-decoration: none; color: #007bff; }
331
+ h1 { color: #343a40; text-align: center; }
332
+ .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; }
335
+ </style>
336
+ </head>
337
+ <body>
338
+ <h1>๐Ÿš€ SpecGen Platform</h1>
339
+ <div class="status">โœ… All services running on port ${PORT}</div>
340
+
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.
344
+ </div>
345
+
346
+ <div class="nav-card">
347
+ <h3><a href="/app">๐Ÿ“ฑ User Application</a></h3>
348
+ <p>Main SpecGen user interface for creating and managing specifications</p>
349
+ </div>
350
+
351
+ <div class="nav-card">
352
+ <h3><a href="/admin">โš™๏ธ Admin Panel</a></h3>
353
+ <p>Administrative interface for system management and configuration</p>
354
+ </div>
355
+
356
+ <div class="nav-card">
357
+ <h3><a href="/api-docs">๐Ÿ“š API Documentation</a></h3>
358
+ <p>Interactive API documentation and testing interface</p>
359
+ </div>
360
+
361
+ <div class="nav-card">
362
+ <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>
370
+ </div>
371
+ </body>
372
+ </html>`;
373
+ res.send(html);
374
+ }
375
+ });
376
+
377
+ // Error handling middleware
378
+ app.use(errorHandler);
379
+
380
+ 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`);
391
+ }
392
+ console.log(`- API is ready for use`);
393
+ });
394
+ }
395
+
396
+ module.exports = app;
397
+ EOF
398
+ echo "โœ… Unified server installed"
206
399
  fi
207
400
 
208
401
  # Install and build admin
@@ -327,32 +520,42 @@ if [ "$DRY_RUN" = true ]; then
327
520
  # Copy environment
328
521
  cp "$PROJECT_DIR/server/.env" "$PROJECT_DIR/.env" 2>/dev/null || true
329
522
 
330
- echo " Starting test server on port 8080 for 10 seconds..."
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"
526
+ TEST_PORT=8081
527
+ sed -i.bak 's/PORT=8080/PORT=8081/' "$PROJECT_DIR/server/.env"
528
+ else
529
+ TEST_PORT=8080
530
+ fi
531
+
532
+ echo " Starting test server on port $TEST_PORT for 10 seconds..."
331
533
 
332
534
  # Start server in background
333
- (cd server && NODE_ENV=production PORT=8080 node index.js) &
535
+ (cd server && NODE_ENV=production PORT=$TEST_PORT node index.js) &
334
536
  SERVER_PID=$!
335
537
 
336
538
  # Wait a bit for server to start
337
539
  sleep 3
338
540
 
339
541
  # Test the endpoints
340
- echo " Testing endpoints:"
542
+ echo " Testing endpoints on port $TEST_PORT:"
341
543
 
342
- if curl -s http://localhost:8080/api/health >/dev/null 2>&1; then
544
+ if curl -s http://localhost:$TEST_PORT/api/health >/dev/null 2>&1; then
343
545
  echo " โœ… Health endpoint: OK"
344
- echo " Response: $(curl -s http://localhost:8080/api/health | head -c 100)..."
546
+ HEALTH_RESPONSE=$(curl -s http://localhost:$TEST_PORT/api/health)
547
+ echo " Status: $(echo $HEALTH_RESPONSE | grep -o '"status":"[^"]*"' | cut -d'"' -f4)"
345
548
  else
346
549
  echo " โŒ Health endpoint: FAILED"
347
550
  fi
348
551
 
349
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/ 2>/dev/null || echo "000")
552
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/ 2>/dev/null || echo "000")
350
553
  echo " ๐Ÿ“„ Main page: HTTP $HTTP_CODE"
351
554
 
352
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/admin 2>/dev/null || echo "000")
555
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/admin/ 2>/dev/null || echo "000")
353
556
  echo " โš™๏ธ Admin page: HTTP $HTTP_CODE"
354
557
 
355
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/app 2>/dev/null || echo "000")
558
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$TEST_PORT/app/ 2>/dev/null || echo "000")
356
559
  echo " ๐Ÿ‘ค User page: HTTP $HTTP_CODE"
357
560
 
358
561
  # Stop test server
@@ -360,6 +563,11 @@ if [ "$DRY_RUN" = true ]; then
360
563
  kill $SERVER_PID 2>/dev/null || true
361
564
  wait $SERVER_PID 2>/dev/null || true
362
565
 
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
+
363
571
  echo ""
364
572
  echo "๐ŸŽ‰ DRY RUN COMPLETED!"
365
573
  echo ""
@@ -367,12 +575,25 @@ if [ "$DRY_RUN" = true ]; then
367
575
  echo " โœ… All packages downloaded and extracted"
368
576
  echo " โœ… All dependencies installed"
369
577
  echo " โœ… React apps built successfully"
578
+ echo " โœ… Unified server installed"
370
579
  echo " โœ… Server can start and respond"
371
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
372
588
  echo "๐Ÿš€ Ready for production deployment!"
373
- echo " Run without --dry-run to deploy for real"
589
+ echo " Deploy to AWS with: npx @gv-sh/specgen-app deploy"
374
590
  echo ""
375
- echo "๐Ÿ”ง To test locally:"
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:"
376
597
  echo " cd server && npm start"
377
598
  echo " Open http://localhost:8080/"
378
599
 
@@ -444,10 +665,10 @@ EOF
444
665
  HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/ 2>/dev/null)
445
666
  echo "๐Ÿ“„ Main page: HTTP $HTTP_CODE"
446
667
 
447
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/admin 2>/dev/null)
668
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/admin/ 2>/dev/null)
448
669
  echo "โš™๏ธ Admin page: HTTP $HTTP_CODE"
449
670
 
450
- HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/app 2>/dev/null)
671
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/app/ 2>/dev/null)
451
672
  echo "๐Ÿ‘ค User page: HTTP $HTTP_CODE"
452
673
 
453
674
  PUBLIC_IP=$(curl -s ifconfig.me 2>/dev/null || curl -s ipecho.net/plain 2>/dev/null || echo 'your-server')
@@ -457,11 +678,16 @@ EOF
457
678
  echo ""
458
679
  echo "๐ŸŒ Access your application at:"
459
680
  echo " - Main page: http://$PUBLIC_IP:8080/"
460
- echo " - User app: http://$PUBLIC_IP:8080/app"
461
- echo " - Admin panel: http://$PUBLIC_IP:8080/admin"
681
+ echo " - User app: http://$PUBLIC_IP:8080/app/"
682
+ echo " - Admin panel: http://$PUBLIC_IP:8080/admin/"
462
683
  echo " - API docs: http://$PUBLIC_IP:8080/api-docs"
463
684
  echo " - Health check: http://$PUBLIC_IP:8080/api/health"
464
685
  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 ""
465
691
  echo "๐Ÿ“Š Management commands:"
466
692
  echo " $PM2_CMD status # Check status"
467
693
  echo " $PM2_CMD logs specgen # View logs"