[30388f42] feat: Full stack integration and documentation overhaul
This commit is contained in:
57
general-market-intelligence/Dockerfile.fullstack
Normal file
57
general-market-intelligence/Dockerfile.fullstack
Normal file
@@ -0,0 +1,57 @@
|
||||
# Stage 1: Build the React frontend
|
||||
FROM node:20-slim AS frontend-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json and install all dependencies
|
||||
# Paths are relative to the build context (project root)
|
||||
COPY general-market-intelligence/package.json ./
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the frontend application code
|
||||
COPY general-market-intelligence/ .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# ---
|
||||
|
||||
# Stage 2: Final application image
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies (minimal)
|
||||
# We use NodeSource to get a clean, modern Node.js install without bloat
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends curl ca-certificates && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||
apt-get install -y --no-install-recommends nodejs && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python dependencies
|
||||
COPY general-market-intelligence/requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy the Node.js server and its production dependencies manifest
|
||||
COPY general-market-intelligence/server.cjs .
|
||||
COPY general-market-intelligence/package.json .
|
||||
COPY helpers.py .
|
||||
COPY config.py .
|
||||
COPY market_db_manager.py .
|
||||
|
||||
# Install dependencies for the Node.js server
|
||||
RUN npm install
|
||||
RUN npm install express cors body-parser
|
||||
|
||||
# Copy the built React app from the builder stage
|
||||
COPY --from=frontend-builder /app/dist ./dist
|
||||
|
||||
# Copy the main Python orchestrator script from the project root
|
||||
COPY general-market-intelligence/market_intel_orchestrator.py .
|
||||
|
||||
# Expose the port the Node.js server will run on
|
||||
EXPOSE 3001
|
||||
|
||||
# The command to run the application
|
||||
CMD ["node", "server.cjs"]
|
||||
3
general-market-intelligence/requirements.txt
Normal file
3
general-market-intelligence/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
requests
|
||||
beautifulsoup4
|
||||
lxml
|
||||
@@ -126,7 +126,7 @@ app.post('/api/generate-search-strategy', async (req, res) => {
|
||||
try {
|
||||
fs.writeFileSync(tempContextFilePath, contextContent);
|
||||
|
||||
const pythonScript = path.join(__dirname, '..', 'market_intel_orchestrator.py');
|
||||
const pythonScript = path.join(__dirname, 'market_intel_orchestrator.py');
|
||||
const scriptArgs = [
|
||||
pythonScript,
|
||||
'--mode', 'generate_strategy',
|
||||
@@ -163,7 +163,7 @@ app.post('/api/identify-competitors', async (req, res) => {
|
||||
cleanupFiles.push(tempContextFilePath);
|
||||
}
|
||||
|
||||
const pythonScript = path.join(__dirname, '..', 'market_intel_orchestrator.py');
|
||||
const pythonScript = path.join(__dirname, 'market_intel_orchestrator.py');
|
||||
const scriptArgs = [
|
||||
pythonScript,
|
||||
'--mode', 'identify_competitors',
|
||||
@@ -193,7 +193,7 @@ app.post('/api/analyze-company', async (req, res) => {
|
||||
return res.status(400).json({ error: 'Missing companyName or strategy' });
|
||||
}
|
||||
|
||||
const pythonScript = path.join(__dirname, '..', 'market_intel_orchestrator.py');
|
||||
const pythonScript = path.join(__dirname, 'market_intel_orchestrator.py');
|
||||
const scriptArgs = [
|
||||
pythonScript,
|
||||
'--mode', 'analyze_company',
|
||||
@@ -228,7 +228,7 @@ app.post('/api/generate-outreach', async (req, res) => {
|
||||
fs.writeFileSync(tempDataFilePath, JSON.stringify(companyData));
|
||||
fs.writeFileSync(tempContextFilePath, knowledgeBase);
|
||||
|
||||
const pythonScript = path.join(__dirname, '..', 'market_intel_orchestrator.py');
|
||||
const pythonScript = path.join(__dirname, 'market_intel_orchestrator.py');
|
||||
const scriptArgs = [
|
||||
pythonScript,
|
||||
'--mode', 'generate_outreach',
|
||||
@@ -252,7 +252,7 @@ app.post('/api/generate-outreach', async (req, res) => {
|
||||
// --- DATABASE ROUTES ---
|
||||
|
||||
// Initialize DB on startup
|
||||
const dbScript = path.join(__dirname, '..', 'market_db_manager.py');
|
||||
const dbScript = path.join(__dirname, 'market_db_manager.py');
|
||||
spawn('python3', [dbScript, 'init']);
|
||||
|
||||
app.get('/api/projects', (req, res) => {
|
||||
|
||||
@@ -1,29 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"node"
|
||||
],
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user