929 problems (928 errors, 1 warning) -> 0, exit 0.
Rule breakdown, which corrects the report's premise -- `indent` dominated, not
`quotes`: indent 719, quotes 68, no-unused-vars 54, no-empty 36,
no-useless-escape 22, no-case-declarations 17, no-inner-declarations 6,
no-control-regex 5, no-useless-catch 1, no-console 1 (warn).
--fix handled only indent + quotes (719+68 = exactly the "fixable" count).
no-useless-escape was NOT auto-fixable in this eslint version, so the one
genuinely risky class never went through the autofixer -- all 22 were done by
hand. Two mechanical proofs on the autofix diff: a token-level AST diff
(espree, before vs after) shows exactly 68 differing tokens, all quotes, with
the 719 indent fixes producing zero token changes; and a cooked-value diff of
every string/template/regex literal shows 0 differences.
Regex escapes: eslint was correctly conservative and did not flag the
load-bearing ones -- \- in [^a-zA-Z0-9_\-\.] (unescaping makes an invalid
reversed _ -> . range) or in [!@#$%^&*()_+\-=...] (would become a + -> = range
silently matching ",-."). Every removal was a \/ \[ or \. inside a character
class; all 11 old/new pairs were brute-forced over 794 inputs with 0
mismatches.
Manual fixes: no-empty were all deliberate best-effort catches around activity
logging, annotated rather than restructured; no-case-declarations braced in
two adminBackup switches; no-inner-declarations converted to const arrows
after checking no call precedes the declaration and no this/arguments use;
no-control-regex and no-console got targeted disables with stated reasons;
one `catch (e) { throw e; }` wrapper removed.
Two unused bindings were near-misses worth noting: secureStatic.js's
`fullPath` is a path-traversal guard (safePathJoin throws on escape) and
restoreService.js's `backupManifest` is the throw-on-corrupt-manifest gate
before a rollback -- deleting either would have silently removed a check. Only
the bindings were dropped; the calls stay.
Two real bugs found and deliberately preserved with a comment plus a narrow
disable rather than deleted, since deleting would erase the evidence:
_workflowSeedBoot.js's `booted` is written but never read, so the intended
once-per-process guard is missing its early return and workflows re-seed on
every call; and quoteService.js's VALID_QUOTE_TRANSITIONS is a full state
machine nothing consults, so quote status changes are unvalidated.
Backend test suite: 253 suites / 2552 tests passing, 0 failures, before and
after.
Refs testplan REPORT.md #22 (Part 1.2.02).
73 lines
1.9 KiB
JavaScript
73 lines
1.9 KiB
JavaScript
/**
|
|
* Worker Manager - Background service for PicPeak
|
|
*
|
|
* This service runs as a separate process to handle:
|
|
* - File watching for new photos
|
|
* - Expiration checking for events
|
|
* - Other background tasks
|
|
*/
|
|
|
|
const path = require('path');
|
|
const logger = require('../utils/logger');
|
|
|
|
// Load environment variables
|
|
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
|
|
|
|
// Import services
|
|
const { startFileWatcher } = require('./fileWatcher');
|
|
const { startExpirationChecker } = require('./expirationChecker');
|
|
|
|
let isShuttingDown = false;
|
|
|
|
async function startWorkers() {
|
|
logger.info('Starting PicPeak background workers...');
|
|
|
|
try {
|
|
// Start file watcher for automatic photo processing
|
|
startFileWatcher();
|
|
logger.info('File watcher started successfully');
|
|
|
|
// Start expiration checker for event lifecycle management
|
|
startExpirationChecker();
|
|
logger.info('Expiration checker started successfully');
|
|
|
|
logger.info('All background workers started successfully');
|
|
} catch (error) {
|
|
logger.error('Failed to start background workers:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function handleShutdown(signal) {
|
|
if (isShuttingDown) {
|
|
logger.info('Shutdown already in progress...');
|
|
return;
|
|
}
|
|
|
|
isShuttingDown = true;
|
|
logger.info(`Received ${signal}. Shutting down gracefully...`);
|
|
|
|
// Give time for cleanup
|
|
setTimeout(() => {
|
|
logger.info('Worker manager shutdown complete');
|
|
process.exit(0);
|
|
}, 1000);
|
|
}
|
|
|
|
// Handle shutdown signals
|
|
process.on('SIGTERM', () => handleShutdown('SIGTERM'));
|
|
process.on('SIGINT', () => handleShutdown('SIGINT'));
|
|
|
|
// Handle uncaught errors
|
|
process.on('uncaughtException', (error) => {
|
|
logger.error('Uncaught exception in worker manager:', error);
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason) => {
|
|
logger.error('Unhandled rejection in worker manager:', reason);
|
|
});
|
|
|
|
// Start workers
|
|
startWorkers();
|