backend changes

This commit is contained in:
Chandini 2025-09-18 08:37:51 +05:30
parent 1c4f9b47ed
commit a9964e906d
6 changed files with 121 additions and 92 deletions

View File

@ -6,11 +6,10 @@
// ======================================== // ========================================
// LIVE PRODUCTION URLS (Currently Active) // LIVE PRODUCTION URLS (Currently Active)
// ======================================== // ========================================
const FRONTEND_URL = 'https://dashboard.codenuk.com'; const FRONTEND_URL = 'http://192.168.1.31:3001';
const BACKEND_URL = 'https://backend.codenuk.com'; const BACKEND_URL = 'https://backend.codenuk.com';
// ========================================
// LOCAL DEVELOPMENT URLS (Comment out live URLs above and uncomment these)
// ======================================== // ========================================
// const FRONTEND_URL = 'http://localhost:3001'; // const FRONTEND_URL = 'http://localhost:3001';
// const BACKEND_URL = 'http://localhost:8000'; // const BACKEND_URL = 'http://localhost:8000';

View File

@ -233,7 +233,7 @@ services:
- NODE_ENV=development - NODE_ENV=development
- PORT=8000 - PORT=8000
- HOST=0.0.0.0 - HOST=0.0.0.0
- FRONTEND_URL=https://dashboard.codenuk.com # Allow all URLs - FRONTEND_URL=http://192.168.1.31:3001 # Allow all URLs
- CORS_ORIGINS=* # Allow all URLs - CORS_ORIGINS=* # Allow all URLs
- CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS # Add this line - CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS # Add this line
- CORS_CREDENTIALS=true # Add this line - CORS_CREDENTIALS=true # Add this line
@ -507,7 +507,7 @@ services:
- JWT_ACCESS_EXPIRY=24h - JWT_ACCESS_EXPIRY=24h
- JWT_ADMIN_ACCESS_EXPIRY=7d - JWT_ADMIN_ACCESS_EXPIRY=7d
- JWT_REFRESH_EXPIRY=7d - JWT_REFRESH_EXPIRY=7d
- FRONTEND_URL=https://dashboard.codenuk.com - FRONTEND_URL=http://192.168.1.31:3001
# Email Configuration # Email Configuration
- SMTP_HOST=smtp.gmail.com - SMTP_HOST=smtp.gmail.com
- SMTP_PORT=587 - SMTP_PORT=587
@ -613,7 +613,7 @@ services:
environment: environment:
- PORT=8012 - PORT=8012
- HOST=0.0.0.0 - HOST=0.0.0.0
- FRONTEND_URL=https://dashboard.codenuk.com - FRONTEND_URL=http://192.168.1.31:3001
- POSTGRES_HOST=postgres - POSTGRES_HOST=postgres
- POSTGRES_PORT=5432 - POSTGRES_PORT=5432
- POSTGRES_DB=dev_pipeline - POSTGRES_DB=dev_pipeline

View File

@ -28,9 +28,9 @@ RABBITMQ_USER=pipeline_admin
RABBITMQ_PASSWORD=secure_rabbitmq_password RABBITMQ_PASSWORD=secure_rabbitmq_password
# CORS # CORS
FRONTEND_URL=https://dashboard.codenuk.com FRONTEND_URL=http://192.168.1.31:3001
# CORS Configuration # CORS Configuration
CORS_ORIGIN=https://dashboard.codenuk.com CORS_ORIGIN=http://192.168.1.31:3001
CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS CORS_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS
CORS_CREDENTIALS=true CORS_CREDENTIALS=true

View File

@ -37,10 +37,11 @@ async function runMigrations() {
console.log('✅ Migration tracking table ready'); console.log('✅ Migration tracking table ready');
// Get all migration files in order // Get all migration files in order
// Reordered to ensure custom_templates table exists before admin_approval_workflow
const migrationFiles = [ const migrationFiles = [
'001_initial_schema.sql', '001_initial_schema.sql',
'002_admin_approval_workflow.sql', '003_custom_templates.sql', // Moved earlier since others depend on it
'003_custom_templates.sql', '002_admin_approval_workflow.sql', // Now runs after custom_templates is created
'004_add_is_custom_flag.sql', '004_add_is_custom_flag.sql',
'004_add_user_id_to_custom_templates.sql', '004_add_user_id_to_custom_templates.sql',
'005_fix_custom_features_foreign_key.sql', '005_fix_custom_features_foreign_key.sql',

View File

@ -148,9 +148,31 @@ class AuthService {
async sendVerificationEmail(user) { async sendVerificationEmail(user) {
const token = await this.createEmailVerificationToken(user.id); const token = await this.createEmailVerificationToken(user.id);
// Send users to the frontend verification page; the frontend will call the backend and handle redirects // Resolve verification URL. Prefer environment variable (works in Docker). If not present,
const { getVerificationUrl } = require('../../../../config/urls'); // fall back to the repository-level config/urls.js when available (development).
const verifyUrl = getVerificationUrl(token); let verifyUrl;
const frontendUrlFromEnv = process.env.FRONTEND_URL;
if (frontendUrlFromEnv) {
const FRONTEND_URL = frontendUrlFromEnv.replace(/\/$/, '');
verifyUrl = `${FRONTEND_URL}/verify-email?token=${encodeURIComponent(token)}`;
} else {
try {
// Attempt to load repo-level config (works when running locally from repo root)
// This is guarded so it won't crash inside Docker if the relative path isn't valid.
// eslint-disable-next-line global-require
const urls = require('../../../../config/urls');
if (urls && typeof urls.getVerificationUrl === 'function') {
verifyUrl = urls.getVerificationUrl(token);
} else if (urls && urls.FRONTEND_URL) {
const FRONTEND_URL = urls.FRONTEND_URL.replace(/\/$/, '');
verifyUrl = `${FRONTEND_URL}/verify-email?token=${encodeURIComponent(token)}`;
}
} catch (err) {
// As a last resort, build a relative backend-hosted verification endpoint
const backendHost = process.env.BACKEND_URL || `http://localhost:${process.env.PORT || 8011}`;
verifyUrl = `${backendHost.replace(/\/$/, '')}/api/auth/verify-email?token=${encodeURIComponent(token)}`;
}
}
const today = new Date(); const today = new Date();
const dateString = today.toLocaleDateString('en-US'); const dateString = today.toLocaleDateString('en-US');

View File

@ -28,7 +28,15 @@ export default function BusinessQuestionsScreen() {
console.log('🚀 Generating comprehensive business questions for integrated system:', selectedFeatures); console.log('🚀 Generating comprehensive business questions for integrated system:', selectedFeatures);
// Call the new comprehensive endpoint // Call the new comprehensive endpoint
const { getApiUrl } = require('../../../../../../config/urls'); // Prefer an environment-provided backend URL for frontend builds (REACT_APP_BACKEND_URL or NEXT_PUBLIC_BACKEND_URL).
const backendBase = (process.env.REACT_APP_BACKEND_URL || process.env.NEXT_PUBLIC_BACKEND_URL || '').replace(/\/$/, '') || '';
const getApiUrl = (endpoint) => {
const clean = endpoint.startsWith('/') ? endpoint.slice(1) : endpoint;
if (backendBase) return `${backendBase}/${clean}`;
// Fallback to relative path (assumes frontend is served with proxy to backend)
return `/${clean}`;
};
const response = await fetch(getApiUrl('api/v1/generate-comprehensive-business-questions'), { const response = await fetch(getApiUrl('api/v1/generate-comprehensive-business-questions'), {
method: 'POST', method: 'POST',
headers: { headers: {
@ -106,7 +114,7 @@ export default function BusinessQuestionsScreen() {
description: `Complete ${projectType} system with ${selectedFeatures.length} integrated features`, description: `Complete ${projectType} system with ${selectedFeatures.length} integrated features`,
requirements: selectedFeatures.flatMap(f => f.requirements || []), requirements: selectedFeatures.flatMap(f => f.requirements || []),
complexity: selectedFeatures.some(f => f.complexity === 'high') ? 'high' : complexity: selectedFeatures.some(f => f.complexity === 'high') ? 'high' :
selectedFeatures.some(f => f.complexity === 'medium') ? 'medium' : 'low', selectedFeatures.some(f => f.complexity === 'medium') ? 'medium' : 'low',
logicRules: selectedFeatures.flatMap(f => f.logicRules || []) logicRules: selectedFeatures.flatMap(f => f.logicRules || [])
}; };
@ -264,11 +272,10 @@ export default function BusinessQuestionsScreen() {
<button <button
onClick={handleSubmit} onClick={handleSubmit}
disabled={isSubmitting || Object.values(businessAnswers).filter(answer => answer.trim()).length === 0} disabled={isSubmitting || Object.values(businessAnswers).filter(answer => answer.trim()).length === 0}
className={`px-6 py-2 rounded-md font-medium transition-colors ${ className={`px-6 py-2 rounded-md font-medium transition-colors ${isSubmitting || Object.values(businessAnswers).filter(answer => answer.trim()).length === 0
isSubmitting || Object.values(businessAnswers).filter(answer => answer.trim()).length === 0
? 'bg-gray-300 text-gray-500 cursor-not-allowed' ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
: 'bg-green-600 text-white hover:bg-green-700' : 'bg-green-600 text-white hover:bg-green-700'
}`} }`}
> >
{isSubmitting ? ( {isSubmitting ? (
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">