2026-02-17 23:03:48 -05:00

127 lines
4.0 KiB
JavaScript

const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { nanoid } = require('nanoid');
const { generateContent } = require('../services/ai-generator');
const { buildSite } = require('../services/site-builder');
const { takeScreenshots } = require('../services/screenshot');
const { assemblePacket } = require('../services/packet-assembler');
// Configure multer for logo uploads
const storage = multer.memoryStorage();
const upload = multer({
storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
fileFilter: (req, file, cb) => {
const allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'];
if (allowed.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Invalid file type. Only images are allowed.'));
}
}
});
// POST /api/generate - Main pipeline
router.post('/generate', upload.single('logo'), async (req, res) => {
const clientId = nanoid(12);
const clientDir = path.join(__dirname, '..', 'data', clientId);
try {
// Create client directory
fs.mkdirSync(path.join(clientDir, 'screenshots'), { recursive: true });
fs.mkdirSync(path.join(clientDir, 'site'), { recursive: true });
// Parse form data
const formData = {
agencyName: req.body.agencyName,
agencyEmail: req.body.agencyEmail,
businessName: req.body.businessName,
businessAddress: req.body.businessAddress,
businessEmail: req.body.businessEmail,
businessPhone: req.body.businessPhone,
businessDescription: req.body.businessDescription,
};
// Save logo if uploaded
let logoPath = null;
if (req.file) {
const ext = path.extname(req.file.originalname) || '.png';
logoPath = path.join(clientDir, `logo${ext}`);
fs.writeFileSync(logoPath, req.file.buffer);
formData.logoUrl = `/data/${clientId}/logo${ext}`;
}
// Step 1: Generate AI content
console.log(`[${clientId}] Step 1: Generating AI content...`);
const aiContent = await generateContent(formData);
// Step 2: Build config — generate subdomain from business name
const MAIN_DOMAIN = req.app.locals.MAIN_DOMAIN || 'solvedby.us';
const subdomain = formData.businessName
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '')
.substring(0, 40);
const siteUrl = `https://${subdomain}.${MAIN_DOMAIN}`;
const localSiteUrl = `http://localhost:8899/sites/${clientId}`;
const config = {
clientId,
subdomain,
...formData,
...aiContent,
siteUrl,
localSiteUrl,
generatedAt: new Date().toISOString(),
};
// Save config
fs.writeFileSync(
path.join(clientDir, 'config.json'),
JSON.stringify(config, null, 2)
);
// Step 3: Build the static site
console.log(`[${clientId}] Step 2: Building website...`);
await buildSite(config, clientDir);
// Step 4: Take screenshots
console.log(`[${clientId}] Step 3: Taking screenshots...`);
await takeScreenshots(clientId, clientDir);
// Step 5: Assemble compliance packet zip
console.log(`[${clientId}] Step 4: Assembling compliance packet...`);
await assemblePacket(config, clientDir);
// Step 6: Register subdomain → clientId mapping
const subdomainIndex = req.app.locals.subdomainIndex;
const saveSubdomainIndex = req.app.locals.saveSubdomainIndex;
subdomainIndex[subdomain] = clientId;
saveSubdomainIndex();
console.log(`[${clientId}] Step 5: Registered subdomain ${subdomain}.${MAIN_DOMAIN}`);
console.log(`[${clientId}] ✅ Complete! Site live at ${siteUrl}`);
res.json({
success: true,
clientId,
resultsUrl: `/results/${clientId}`,
siteUrl,
localSiteUrl: `/sites/${clientId}/`,
});
} catch (error) {
console.error(`[${clientId}] ❌ Error:`, error);
res.status(500).json({
success: false,
error: error.message || 'Generation failed',
});
}
});
module.exports = router;