relv-space4 / src /server /routes /internal.ts
relv-dev's picture
Deploy latest verified Turnitin worker
521a9b6 verified
Raw
History Blame Contribute Delete
5.16 kB
import { Router, Request, Response } from 'express';
import { config } from '../../config';
import {
claimSpecificAccountForManualQuota,
getTurnitinAccountById,
} from '../../db/accounts';
import { requireAdminSecret } from '../middleware/admin-secret';
import { getJobById } from '../../db/jobs';
import { runQuotaCheckForAccount } from '../../cron/quota-check';
import { logger } from '../../utils/logger';
const router = Router();
const MAX_MANUAL_QUOTA_CHECKS_PER_WORKER = 1;
let activeManualQuotaChecks = 0;
// Only /internal routes require the admin secret. Keep this scoped so unknown
// public paths return 404 instead of noisy "admin secret mismatch" warnings.
router.use('/internal', requireAdminSecret);
/**
* POST /internal/jobs/:id/run
* Manually trigger a job run. Stub implementation — validates the job exists
* and returns 202 Accepted. Actual worker invocation is handled elsewhere.
*/
router.post('/internal/jobs/:id/run', async (req: Request, res: Response): Promise<void> => {
const id = String(req.params.id);
try {
const job = await getJobById(id);
if (!job) {
res.status(404).json({ error: 'Job not found' });
return;
}
logger.info('Manual job run requested', { jobId: id });
// TODO: Integrate with worker dispatch
res.status(202).json({ message: 'Job run accepted', jobId: id });
} catch (err) {
logger.error('Internal job run error', {
jobId: id,
error: err instanceof Error ? err.message : String(err),
});
res.status(500).json({ error: 'Internal server error' });
}
});
/**
* POST /internal/accounts/:id/quota-check
* Manually trigger a quota check for a specific account.
* The check is started in the background after the account is leased, so the
* dashboard request is not held open for a full browser session.
*/
router.post(
'/internal/accounts/:id/quota-check',
async (req: Request, res: Response): Promise<void> => {
const id = String(req.params.id);
let handedOffToBackground = false;
try {
logger.info('Manual quota check requested', { accountId: id });
if (activeManualQuotaChecks >= MAX_MANUAL_QUOTA_CHECKS_PER_WORKER) {
res.status(429).json({
error: 'This worker is already running a manual quota check. Try another worker or wait briefly.',
});
return;
}
activeManualQuotaChecks += 1;
const existingAccount = await getTurnitinAccountById(id);
if (!existingAccount) {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
res.status(404).json({ error: 'Turnitin account not found' });
return;
}
if (existingAccount.turnitin_status === 'disabled') {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
res.status(409).json({ error: 'This account is disabled and cannot be checked.' });
return;
}
if (existingAccount.turnitin_status === 'login_failed') {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
res.status(409).json({
error: 'This account is marked login_failed. Fix the credential before checking quota.',
});
return;
}
if (existingAccount.turnitin_pool_key === 'legacy_carta' || existingAccount.turnitin_pool_key === 'modern_one') {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
res.status(409).json({
error:
'Manual quota check supports reusable modern Turnitin accounts only. Legacy and modern_one pools are finalized after submission.',
});
return;
}
const leaseOwner = `${config.workerId}:manual-quota-check`;
const claimedAccount = await claimSpecificAccountForManualQuota(id, leaseOwner);
if (!claimedAccount) {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
res.status(409).json({
error: 'This account is currently leased by another worker or is not ready for checking.',
});
return;
}
handedOffToBackground = true;
void runQuotaCheckForAccount(claimedAccount, {
source: 'manual',
fallbackStatus: existingAccount.turnitin_status || 'available',
})
.catch((err: unknown) => {
logger.error('Manual quota check background task failed', {
accountId: id,
error: err instanceof Error ? err.message : String(err),
});
})
.finally(() => {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
});
res.status(202).json({
message: 'Quota check started',
accountId: id,
workerId: config.workerId,
});
} catch (err: unknown) {
logger.error('Manual quota check request failed', {
accountId: id,
error: err instanceof Error ? err.message : String(err),
});
if (!handedOffToBackground) {
activeManualQuotaChecks = Math.max(0, activeManualQuotaChecks - 1);
}
res.status(500).json({ error: 'Failed to start quota check' });
}
},
);
export default router;