The job_run_logs table tracks scheduled job orchestration, not individual worker jobs. Worker info (worker_id, worker_hostname) belongs on dispensary_crawl_jobs, not job_run_logs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
120 lines
6.1 KiB
JavaScript
120 lines
6.1 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const express_1 = __importDefault(require("express"));
|
|
const cors_1 = __importDefault(require("cors"));
|
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
const minio_1 = require("./utils/minio");
|
|
const image_storage_1 = require("./utils/image-storage");
|
|
const logger_1 = require("./services/logger");
|
|
const proxyTestQueue_1 = require("./services/proxyTestQueue");
|
|
dotenv_1.default.config();
|
|
const app = (0, express_1.default)();
|
|
const PORT = process.env.PORT || 3010;
|
|
app.use((0, cors_1.default)());
|
|
app.use(express_1.default.json());
|
|
// Serve static images when MinIO is not configured
|
|
const LOCAL_IMAGES_PATH = process.env.LOCAL_IMAGES_PATH || '/app/public/images';
|
|
app.use('/images', express_1.default.static(LOCAL_IMAGES_PATH));
|
|
// Serve static downloads (plugin files, etc.)
|
|
const LOCAL_DOWNLOADS_PATH = process.env.LOCAL_DOWNLOADS_PATH || '/app/public/downloads';
|
|
app.use('/downloads', express_1.default.static(LOCAL_DOWNLOADS_PATH));
|
|
app.get('/health', (req, res) => {
|
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
});
|
|
// Endpoint to check server's outbound IP (for proxy whitelist setup)
|
|
app.get('/outbound-ip', async (req, res) => {
|
|
try {
|
|
const axios = require('axios');
|
|
const response = await axios.get('https://api.ipify.org?format=json', { timeout: 10000 });
|
|
res.json({ outbound_ip: response.data.ip });
|
|
}
|
|
catch (error) {
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
const auth_1 = __importDefault(require("./routes/auth"));
|
|
const dashboard_1 = __importDefault(require("./routes/dashboard"));
|
|
const stores_1 = __importDefault(require("./routes/stores"));
|
|
const dispensaries_1 = __importDefault(require("./routes/dispensaries"));
|
|
const changes_1 = __importDefault(require("./routes/changes"));
|
|
const categories_1 = __importDefault(require("./routes/categories"));
|
|
const products_1 = __importDefault(require("./routes/products"));
|
|
const campaigns_1 = __importDefault(require("./routes/campaigns"));
|
|
const analytics_1 = __importDefault(require("./routes/analytics"));
|
|
const settings_1 = __importDefault(require("./routes/settings"));
|
|
const proxies_1 = __importDefault(require("./routes/proxies"));
|
|
const logs_1 = __importDefault(require("./routes/logs"));
|
|
const scraper_monitor_1 = __importDefault(require("./routes/scraper-monitor"));
|
|
const api_tokens_1 = __importDefault(require("./routes/api-tokens"));
|
|
const api_permissions_1 = __importDefault(require("./routes/api-permissions"));
|
|
const parallel_scrape_1 = __importDefault(require("./routes/parallel-scrape"));
|
|
const schedule_1 = __importDefault(require("./routes/schedule"));
|
|
const crawler_sandbox_1 = __importDefault(require("./routes/crawler-sandbox"));
|
|
const version_1 = __importDefault(require("./routes/version"));
|
|
const public_api_1 = __importDefault(require("./routes/public-api"));
|
|
const dutchie_az_1 = require("./dutchie-az");
|
|
const apiTokenTracker_1 = require("./middleware/apiTokenTracker");
|
|
const crawl_scheduler_1 = require("./services/crawl-scheduler");
|
|
const wordpressPermissions_1 = require("./middleware/wordpressPermissions");
|
|
// Apply WordPress permissions validation first (sets req.apiToken)
|
|
app.use(wordpressPermissions_1.validateWordPressPermissions);
|
|
// Apply API tracking middleware globally
|
|
app.use(apiTokenTracker_1.trackApiUsage);
|
|
app.use(apiTokenTracker_1.checkRateLimit);
|
|
app.use('/api/auth', auth_1.default);
|
|
app.use('/api/dashboard', dashboard_1.default);
|
|
app.use('/api/stores', stores_1.default);
|
|
app.use('/api/dispensaries', dispensaries_1.default);
|
|
app.use('/api/changes', changes_1.default);
|
|
app.use('/api/categories', categories_1.default);
|
|
app.use('/api/products', products_1.default);
|
|
app.use('/api/campaigns', campaigns_1.default);
|
|
app.use('/api/analytics', analytics_1.default);
|
|
app.use('/api/settings', settings_1.default);
|
|
app.use('/api/proxies', proxies_1.default);
|
|
app.use('/api/logs', logs_1.default);
|
|
app.use('/api/scraper-monitor', scraper_monitor_1.default);
|
|
app.use('/api/api-tokens', api_tokens_1.default);
|
|
app.use('/api/api-permissions', api_permissions_1.default);
|
|
app.use('/api/parallel-scrape', parallel_scrape_1.default);
|
|
app.use('/api/schedule', schedule_1.default);
|
|
app.use('/api/crawler-sandbox', crawler_sandbox_1.default);
|
|
app.use('/api/version', version_1.default);
|
|
// Vendor-agnostic AZ data pipeline routes (new public surface)
|
|
app.use('/api/az', dutchie_az_1.dutchieAZRouter);
|
|
// Legacy alias (kept temporarily for backward compatibility)
|
|
app.use('/api/dutchie-az', dutchie_az_1.dutchieAZRouter);
|
|
// Public API v1 - External consumer endpoints (WordPress, etc.)
|
|
// Uses dutchie_az data pipeline with per-dispensary API key auth
|
|
app.use('/api/v1', public_api_1.default);
|
|
async function startServer() {
|
|
try {
|
|
logger_1.logger.info('system', 'Starting server...');
|
|
await (0, minio_1.initializeMinio)();
|
|
await (0, image_storage_1.initializeImageStorage)();
|
|
logger_1.logger.info('system', (0, minio_1.isMinioEnabled)() ? 'MinIO storage initialized' : 'Local filesystem storage initialized');
|
|
// Clean up any orphaned proxy test jobs from previous server runs
|
|
await (0, proxyTestQueue_1.cleanupOrphanedJobs)();
|
|
// Start the crawl scheduler (checks every minute for jobs to run)
|
|
(0, crawl_scheduler_1.startCrawlScheduler)();
|
|
logger_1.logger.info('system', 'Crawl scheduler started');
|
|
// Start the Dutchie AZ scheduler (enqueues jobs for workers)
|
|
await (0, dutchie_az_1.initializeDefaultSchedules)();
|
|
(0, dutchie_az_1.startScheduler)();
|
|
logger_1.logger.info('system', 'Dutchie AZ scheduler started');
|
|
app.listen(PORT, () => {
|
|
logger_1.logger.info('system', `Server running on port ${PORT}`);
|
|
console.log(`🚀 Server running on port ${PORT}`);
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger_1.logger.error('system', `Failed to start server: ${error}`);
|
|
console.error('Failed to start server:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
startServer();
|