127 lines
4.0 KiB
JavaScript
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;
|