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>
263 lines
9.8 KiB
JavaScript
263 lines
9.8 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || (function () {
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
return function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
})();
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const express_1 = require("express");
|
|
const middleware_1 = require("../auth/middleware");
|
|
const migrate_1 = require("../db/migrate");
|
|
const proxy_1 = require("../services/proxy");
|
|
const proxyTestQueue_1 = require("../services/proxyTestQueue");
|
|
const router = (0, express_1.Router)();
|
|
router.use(middleware_1.authMiddleware);
|
|
// Get all proxies
|
|
router.get('/', async (req, res) => {
|
|
try {
|
|
const result = await migrate_1.pool.query(`
|
|
SELECT id, host, port, protocol, active, is_anonymous,
|
|
last_tested_at, test_result, response_time_ms, created_at,
|
|
city, state, country, country_code, location_updated_at
|
|
FROM proxies
|
|
ORDER BY created_at DESC
|
|
`);
|
|
res.json({ proxies: result.rows });
|
|
}
|
|
catch (error) {
|
|
console.error('Error fetching proxies:', error);
|
|
res.status(500).json({ error: 'Failed to fetch proxies' });
|
|
}
|
|
});
|
|
// Get active proxy test job (must be before /:id route)
|
|
router.get('/test-job', async (req, res) => {
|
|
try {
|
|
const job = await (0, proxyTestQueue_1.getActiveProxyTestJob)();
|
|
res.json({ job });
|
|
}
|
|
catch (error) {
|
|
console.error('Error fetching active job:', error);
|
|
res.status(500).json({ error: 'Failed to fetch active job' });
|
|
}
|
|
});
|
|
// Get proxy test job status (must be before /:id route)
|
|
router.get('/test-job/:jobId', async (req, res) => {
|
|
try {
|
|
const { jobId } = req.params;
|
|
const job = await (0, proxyTestQueue_1.getProxyTestJob)(parseInt(jobId));
|
|
if (!job) {
|
|
return res.status(404).json({ error: 'Job not found' });
|
|
}
|
|
res.json({ job });
|
|
}
|
|
catch (error) {
|
|
console.error('Error fetching job status:', error);
|
|
res.status(500).json({ error: 'Failed to fetch job status' });
|
|
}
|
|
});
|
|
// Get single proxy
|
|
router.get('/:id', async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const result = await migrate_1.pool.query(`
|
|
SELECT id, host, port, protocol, username, active, is_anonymous,
|
|
last_tested_at, test_result, response_time_ms, created_at
|
|
FROM proxies
|
|
WHERE id = $1
|
|
`, [id]);
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Proxy not found' });
|
|
}
|
|
res.json({ proxy: result.rows[0] });
|
|
}
|
|
catch (error) {
|
|
console.error('Error fetching proxy:', error);
|
|
res.status(500).json({ error: 'Failed to fetch proxy' });
|
|
}
|
|
});
|
|
// Add single proxy
|
|
router.post('/', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { host, port, protocol, username, password } = req.body;
|
|
if (!host || !port || !protocol) {
|
|
return res.status(400).json({ error: 'Host, port, and protocol required' });
|
|
}
|
|
// Test and add proxy
|
|
const proxyId = await (0, proxy_1.addProxy)(host, port, protocol, username, password);
|
|
const result = await migrate_1.pool.query(`
|
|
SELECT * FROM proxies WHERE id = $1
|
|
`, [proxyId]);
|
|
res.status(201).json({ proxy: result.rows[0] });
|
|
}
|
|
catch (error) {
|
|
console.error('Error adding proxy:', error);
|
|
res.status(400).json({ error: error.message || 'Failed to add proxy' });
|
|
}
|
|
});
|
|
// Add multiple proxies
|
|
router.post('/bulk', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { proxies } = req.body;
|
|
if (!proxies || !Array.isArray(proxies)) {
|
|
return res.status(400).json({ error: 'Proxies array required' });
|
|
}
|
|
const result = await (0, proxy_1.addProxiesFromList)(proxies);
|
|
res.status(201).json(result);
|
|
}
|
|
catch (error) {
|
|
console.error('Error adding proxies:', error);
|
|
res.status(500).json({ error: 'Failed to add proxies' });
|
|
}
|
|
});
|
|
// Test single proxy
|
|
router.post('/:id/test', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const proxyResult = await migrate_1.pool.query(`
|
|
SELECT host, port, protocol, username, password
|
|
FROM proxies
|
|
WHERE id = $1
|
|
`, [id]);
|
|
if (proxyResult.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Proxy not found' });
|
|
}
|
|
const proxy = proxyResult.rows[0];
|
|
const testResult = await (0, proxy_1.testProxy)(proxy.host, proxy.port, proxy.protocol, proxy.username, proxy.password);
|
|
// Update proxy with test results
|
|
await migrate_1.pool.query(`
|
|
UPDATE proxies
|
|
SET last_tested_at = CURRENT_TIMESTAMP,
|
|
test_result = $1,
|
|
response_time_ms = $2,
|
|
is_anonymous = $3,
|
|
active = $4
|
|
WHERE id = $5
|
|
`, [
|
|
testResult.success ? 'success' : 'failed',
|
|
testResult.responseTimeMs,
|
|
testResult.isAnonymous,
|
|
testResult.success,
|
|
id
|
|
]);
|
|
res.json({ test_result: testResult });
|
|
}
|
|
catch (error) {
|
|
console.error('Error testing proxy:', error);
|
|
res.status(500).json({ error: 'Failed to test proxy' });
|
|
}
|
|
});
|
|
// Start proxy test job
|
|
router.post('/test-all', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const jobId = await (0, proxyTestQueue_1.createProxyTestJob)();
|
|
res.json({ jobId, message: 'Proxy test job started' });
|
|
}
|
|
catch (error) {
|
|
console.error('Error starting proxy test job:', error);
|
|
res.status(500).json({ error: 'Failed to start proxy test job' });
|
|
}
|
|
});
|
|
// Cancel proxy test job
|
|
router.post('/test-job/:jobId/cancel', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { jobId } = req.params;
|
|
const cancelled = await (0, proxyTestQueue_1.cancelProxyTestJob)(parseInt(jobId));
|
|
if (!cancelled) {
|
|
return res.status(404).json({ error: 'Job not found or already completed' });
|
|
}
|
|
res.json({ message: 'Job cancelled successfully' });
|
|
}
|
|
catch (error) {
|
|
console.error('Error cancelling job:', error);
|
|
res.status(500).json({ error: 'Failed to cancel job' });
|
|
}
|
|
});
|
|
// Update proxy
|
|
router.put('/:id', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const { host, port, protocol, username, password, active } = req.body;
|
|
const result = await migrate_1.pool.query(`
|
|
UPDATE proxies
|
|
SET host = COALESCE($1, host),
|
|
port = COALESCE($2, port),
|
|
protocol = COALESCE($3, protocol),
|
|
username = COALESCE($4, username),
|
|
password = COALESCE($5, password),
|
|
active = COALESCE($6, active),
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = $7
|
|
RETURNING *
|
|
`, [host, port, protocol, username, password, active, id]);
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Proxy not found' });
|
|
}
|
|
res.json({ proxy: result.rows[0] });
|
|
}
|
|
catch (error) {
|
|
console.error('Error updating proxy:', error);
|
|
res.status(500).json({ error: 'Failed to update proxy' });
|
|
}
|
|
});
|
|
// Delete proxy
|
|
router.delete('/:id', (0, middleware_1.requireRole)('superadmin'), async (req, res) => {
|
|
try {
|
|
const { id } = req.params;
|
|
const result = await migrate_1.pool.query(`
|
|
DELETE FROM proxies WHERE id = $1 RETURNING id
|
|
`, [id]);
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Proxy not found' });
|
|
}
|
|
res.json({ message: 'Proxy deleted successfully' });
|
|
}
|
|
catch (error) {
|
|
console.error('Error deleting proxy:', error);
|
|
res.status(500).json({ error: 'Failed to delete proxy' });
|
|
}
|
|
});
|
|
// Update all proxy locations
|
|
router.post('/update-locations', (0, middleware_1.requireRole)('superadmin', 'admin'), async (req, res) => {
|
|
try {
|
|
const { updateAllProxyLocations } = await Promise.resolve().then(() => __importStar(require('../services/geolocation')));
|
|
// Run in background
|
|
updateAllProxyLocations().catch(err => {
|
|
console.error('❌ Location update failed:', err);
|
|
});
|
|
res.json({ message: 'Location update job started' });
|
|
}
|
|
catch (error) {
|
|
console.error('Error starting location update:', error);
|
|
res.status(500).json({ error: 'Failed to start location update' });
|
|
}
|
|
});
|
|
exports.default = router;
|