refactor(lint): fix code style and unused variables across src/

- Fixed unused function parameters by prefixing with underscore
- Removed unused imports and variables
- Applied eslint --fix for automatic style fixes
  - Property shorthand
  - String template literals
  - Prefer const over let where appropriate
  - Spacing and formatting

Reduces lint errors from 108+ to 78 (61 unused vars, 17 other issues)

Related to CI lint failures in previous commit

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
TheFlow 2025-10-24 20:15:26 +13:00
parent fc236ffc00
commit 40601f7d27
41 changed files with 97 additions and 100 deletions

View file

@ -102,7 +102,7 @@ async function getAuditAnalytics(req, res) {
const { days = 7 } = req.query;
// Get audit logs
const auditLogsResponse = await getAuditLogs(req, { json: (data) => data });
const auditLogsResponse = await getAuditLogs(req, { json: data => data });
const decisions = auditLogsResponse.decisions;
// Calculate analytics

View file

@ -24,7 +24,7 @@ async function getInbox(req, res) {
skip: parseInt(skip)
};
let items = [];
const items = [];
// Fetch contacts
if (!type || type === 'all' || type === 'contact') {
@ -137,7 +137,7 @@ async function getStats(req, res) {
* Helper: Get media inquiry statistics
*/
async function getMediaStats() {
const [total, newCount, triagedCount, respondedCount, closedCount] = await Promise.all([
const [_total, newCount, triagedCount, respondedCount, closedCount] = await Promise.all([
MediaInquiry.countByStatus('new'),
MediaInquiry.countByStatus('new'),
MediaInquiry.countByStatus('triaged'),

View file

@ -237,7 +237,7 @@ exports.verifySession = async (req, res) => {
amount: session.amount_total / 100,
currency: session.currency,
frequency: session.metadata.frequency,
isSuccessful: isSuccessful
isSuccessful
}
});
@ -269,7 +269,7 @@ exports.createPortalSession = async (req, res) => {
// Find customer by email
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const customers = await stripe.customers.list({
email: email,
email,
limit: 1
});
@ -285,7 +285,7 @@ exports.createPortalSession = async (req, res) => {
// Create portal session
const session = await stripe.billingPortal.sessions.create({
customer: customer.id,
return_url: `${process.env.FRONTEND_URL || 'https://agenticgovernance.digital'}/koha.html`,
return_url: `${process.env.FRONTEND_URL || 'https://agenticgovernance.digital'}/koha.html`
});
logger.info(`[KOHA] Customer portal session created for ${email}`);

View file

@ -27,7 +27,7 @@ async function getAllProjects(req, res) {
try {
const { active, database, limit } = req.query;
let query = {};
const query = {};
// Filter by active status if specified
if (active !== undefined) {
@ -45,7 +45,7 @@ async function getAllProjects(req, res) {
// Get variable counts for each project
const projectsWithCounts = await Promise.all(
projects.map(async (project) => {
projects.map(async project => {
const variableCount = await VariableValue.countDocuments({
projectId: project.id,
active: true

View file

@ -91,7 +91,7 @@ async function getSubmissions(req, res) {
// Manually fetch blog post titles for submissions that have blogPostId
const submissionsWithBlogData = await Promise.all(
submissions.map(async (submission) => {
submissions.map(async submission => {
const submissionObj = submission.toObject();
if (submissionObj.blogPostId) {

View file

@ -7,7 +7,7 @@ const logger = require('../utils/logger.util');
/**
* 404 Not Found handler
*/
function notFound(req, res, next) {
function notFound(req, res, _next) {
res.status(404).json({
error: 'Not Found',
message: `Route ${req.method} ${req.originalUrl} not found`

View file

@ -11,7 +11,7 @@
* Production: Generic error messages only
* Development: More detailed errors for debugging
*/
function sanitizeErrorResponse(err, req, res, next) {
function sanitizeErrorResponse(err, req, res, _next) {
const isProduction = process.env.NODE_ENV === 'production';
// Log full error details internally (always)
@ -46,7 +46,7 @@ function sanitizeErrorResponse(err, req, res, next) {
if (isProduction) {
return res.status(statusCode).json({
error: genericErrors[statusCode] || 'Error',
message: err.message || 'An error occurred',
message: err.message || 'An error occurred'
// NEVER include in production: stack, file paths, internal details
});
}

View file

@ -26,7 +26,7 @@ function securityHeadersMiddleware(req, res, next) {
"frame-ancestors 'none'",
"base-uri 'self'",
"form-action 'self'",
"upgrade-insecure-requests"
'upgrade-insecure-requests'
].join('; ')
);

View file

@ -71,7 +71,7 @@ function validateRequired(fields) {
return res.status(400).json({
error: 'Validation failed',
message: 'Required fields missing',
missing: missing
missing
});
}
@ -83,12 +83,12 @@ function validateRequired(fields) {
* Sanitize string inputs
*/
function sanitizeInputs(req, res, next) {
const sanitizeString = (str) => {
const sanitizeString = str => {
if (typeof str !== 'string') return str;
return validator.escape(str.trim());
};
const sanitizeObject = (obj) => {
const sanitizeObject = obj => {
const sanitized = {};
for (const [key, value] of Object.entries(obj)) {

View file

@ -32,7 +32,7 @@ class Donation {
donor: {
name: data.donor?.name || 'Anonymous',
email: data.donor?.email, // Required for receipt, kept private
country: data.donor?.country,
country: data.donor?.country
// Do NOT store full address unless required for tax purposes
},
@ -230,7 +230,7 @@ class Donation {
monthly_supporters: monthlySupporters,
one_time_donations: oneTimeDonations,
monthly_recurring_revenue: monthlyRevenue,
allocation: allocation,
allocation,
recent_donors: publicDonors,
last_updated: new Date()
};

View file

@ -141,7 +141,7 @@ class ModerationQueue {
{ _id: new ObjectId(id) },
{
$set: {
status: status,
status,
reviewed_at: new Date(),
'review_decision.action': decision.action,
'review_decision.notes': decision.notes,

View file

@ -23,7 +23,7 @@ const projectSchema = new mongoose.Schema({
lowercase: true,
trim: true,
validate: {
validator: function(v) {
validator(v) {
// Slug format: lowercase letters, numbers, hyphens
return /^[a-z0-9-]+$/.test(v);
},
@ -92,7 +92,7 @@ const projectSchema = new mongoose.Schema({
type: String,
default: '',
validate: {
validator: function(v) {
validator(v) {
if (!v) return true; // Empty is valid
// Basic URL validation
try {

View file

@ -114,7 +114,7 @@ class ResponseTemplate {
throw new Error('Template not found');
}
let rendered = {
const rendered = {
subject: template.subject,
content: template.content
};

View file

@ -92,7 +92,7 @@ class SLATracking {
first_response_at: new Date(),
response_time: responseTime,
status: 'responded',
breach: breach,
breach,
updated_at: new Date()
}
}

View file

@ -190,8 +190,8 @@ scheduledTaskSchema.statics.getDueSoon = function(daysAhead = 7) {
status: 'pending',
showInSessionInit: true
})
.sort({ priority: -1, dueDate: 1 })
.limit(10);
.sort({ priority: -1, dueDate: 1 })
.limit(10);
};
// Static: Get overdue tasks
@ -200,7 +200,7 @@ scheduledTaskSchema.statics.getOverdue = function() {
dueDate: { $lt: new Date() },
status: 'pending'
})
.sort({ priority: -1, dueDate: 1 });
.sort({ priority: -1, dueDate: 1 });
};
// Static: Get tasks by category

View file

@ -30,7 +30,7 @@ const variableValueSchema = new mongoose.Schema({
uppercase: true,
trim: true,
validate: {
validator: function(v) {
validator(v) {
// Variable names must be UPPER_SNAKE_CASE
return /^[A-Z][A-Z0-9_]*$/.test(v);
},

View file

@ -374,7 +374,7 @@ router.get('/stats', async (req, res) => {
byCategory: {},
byPriority: {},
dueSoon: await ScheduledTask.countDocuments({
dueDate: { $lte: new Date(Date.now() + 7*24*60*60*1000) },
dueDate: { $lte: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) },
status: 'pending'
})
};

View file

@ -11,7 +11,6 @@ const { asyncHandler } = require('../middleware/error.middleware');
// Import services
const {
classifier,
validator,
enforcer,
monitor
} = require('../services');
@ -115,7 +114,7 @@ router.post('/boundary-check',
const action = {
type: 'decision',
decision: decision,
decision,
description: description || '',
timestamp: new Date()
};

View file

@ -35,7 +35,7 @@ router.get('/metrics', authenticateToken, requireAdmin, async (req, res) => {
res.json({
success: true,
metrics: metrics
metrics
});
} catch (error) {
console.error('Error fetching hooks metrics:', error);

View file

@ -21,7 +21,7 @@ const donationLimiter = rateLimit({
standardHeaders: true,
legacyHeaders: false,
// Skip rate limiting for webhook endpoint (Stripe needs reliable access)
skip: (req) => req.path === '/webhook'
skip: req => req.path === '/webhook'
});
/**

View file

@ -61,7 +61,7 @@ router.get('/health', authenticateToken, requireAdmin, async (req, res) => {
if (fileError) {
status = 'error';
message = 'Cannot read instruction file: ' + fileError;
message = `Cannot read instruction file: ${ fileError}`;
severity = 'error';
} else if (difference === 0) {
status = 'healthy';
@ -69,15 +69,15 @@ router.get('/health', authenticateToken, requireAdmin, async (req, res) => {
severity = 'success';
} else if (difference <= 2) {
status = 'warning';
message = 'Minor desync: ' + difference + ' instruction' + (difference !== 1 ? 's' : '') + ' differ';
message = `Minor desync: ${ difference } instruction${ difference !== 1 ? 's' : '' } differ`;
severity = 'warning';
} else if (difference <= 5) {
status = 'warning';
message = 'Moderate desync: ' + difference + ' instructions differ (' + diffPercent + '%)';
message = `Moderate desync: ${ difference } instructions differ (${ diffPercent }%)`;
severity = 'warning';
} else {
status = 'critical';
message = 'Critical desync: ' + difference + ' instructions differ (' + diffPercent + '%)';
message = `Critical desync: ${ difference } instructions differ (${ diffPercent }%)`;
severity = 'error';
}
@ -86,11 +86,11 @@ router.get('/health', authenticateToken, requireAdmin, async (req, res) => {
const missingInDb = fileInstructions
.filter(i => !dbIds.has(i.id))
.map(i => ({ id: i.id, text: i.text.substring(0, 60) + '...' }));
.map(i => ({ id: i.id, text: `${i.text.substring(0, 60) }...` }));
const orphanedInDb = dbRules
.filter(r => !fileIds.has(r.id))
.map(r => ({ id: r.id, text: r.text.substring(0, 60) + '...' }));
.map(r => ({ id: r.id, text: `${r.text.substring(0, 60) }...` }));
res.json({
success: true,

View file

@ -39,7 +39,7 @@ app.use(securityHeadersMiddleware);
// Keep helmet for other security features (but CSP already set above)
app.use(helmet({
contentSecurityPolicy: false, // Disabled - using our custom CSP in securityHeadersMiddleware
contentSecurityPolicy: false // Disabled - using our custom CSP in securityHeadersMiddleware
}));
// CORS

View file

@ -56,7 +56,7 @@ class AnthropicMemoryClient {
const requestOptions = {
model: this.model,
max_tokens: options.max_tokens || 8096,
messages: messages,
messages,
betas: this.betaHeaders,
...options
};

View file

@ -362,7 +362,7 @@ Respond with JSON:
return excerpt.substring(0, lastPeriod + 1);
}
return excerpt.substring(0, maxLength).trim() + '...';
return `${excerpt.substring(0, maxLength).trim() }...`;
}
/**
@ -527,8 +527,8 @@ Respond with JSON as specified in the system prompt.`;
stats_found: statsFound,
sources_provided: content.sources?.length || 0,
recommendation: violations.length > 0 ? 'REJECT' :
warnings.length > 0 ? 'REVIEW_REQUIRED' :
'APPROVED'
warnings.length > 0 ? 'REVIEW_REQUIRED' :
'APPROVED'
};
// Audit validation decision

View file

@ -45,8 +45,8 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Values cannot be automated, only verified',
humanRequired: true,
keywords: ['value', 'principle', 'ethic', 'moral', 'should', 'ought', 'right', 'wrong',
'privacy', 'policy', 'trade-off', 'tradeoff', 'prioritize', 'priority',
'belief', 'virtue', 'integrity', 'fairness', 'justice'],
'privacy', 'policy', 'trade-off', 'tradeoff', 'prioritize', 'priority',
'belief', 'virtue', 'integrity', 'fairness', 'justice'],
examples: [
'Decide whether to prioritize privacy over convenience',
'Determine our core values',
@ -58,7 +58,7 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Innovation cannot be proceduralized, only facilitated',
humanRequired: true,
keywords: ['innovate', 'create', 'invent', 'breakthrough', 'novel', 'creative',
'architectural', 'architecture', 'design', 'fundamental', 'revolutionary', 'transform'],
'architectural', 'architecture', 'design', 'fundamental', 'revolutionary', 'transform'],
examples: [
'Create entirely new approach',
'Invent solution to fundamental problem',
@ -70,7 +70,7 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Wisdom cannot be encoded, only supported',
humanRequired: true,
keywords: ['wisdom', 'judgment', 'discernment', 'prudence', 'insight',
'strategic', 'direction', 'guidance', 'wise', 'counsel', 'experience'],
'strategic', 'direction', 'guidance', 'wise', 'counsel', 'experience'],
examples: [
'Exercise judgment in unprecedented situation',
'Apply wisdom to complex tradeoff',
@ -82,7 +82,7 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Purpose cannot be generated, only preserved',
humanRequired: true,
keywords: ['purpose', 'mission', 'why', 'meaning', 'goal', 'objective',
'vision', 'intent', 'aim', 'reason for', 'raison', 'fundamental goal'],
'vision', 'intent', 'aim', 'reason for', 'raison', 'fundamental goal'],
examples: [
'Define our organizational purpose',
'Determine why we exist',
@ -94,7 +94,7 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Meaning cannot be computed, only recognized',
humanRequired: true,
keywords: ['meaning', 'significance', 'importance', 'matter', 'meaningful',
'significant', 'important', 'matters', 'valuable', 'worthwhile'],
'significant', 'important', 'matters', 'valuable', 'worthwhile'],
examples: [
'Decide what is truly significant',
'Determine what matters most',
@ -106,7 +106,7 @@ const TRACTATUS_BOUNDARIES = {
principle: 'Agency cannot be simulated, only respected',
humanRequired: true,
keywords: ['agency', 'autonomy', 'choice', 'freedom', 'sovereignty', 'self-determination',
'decide for', 'on behalf', 'override', 'substitute', 'replace human'],
'decide for', 'on behalf', 'override', 'substitute', 'replace human'],
examples: [
'Make autonomous decision for humans',
'Override human choice',

View file

@ -40,7 +40,7 @@ class ClaudeAPIService {
const payload = {
model: options.model || this.model,
max_tokens: options.max_tokens || this.maxTokens,
messages: messages,
messages,
...(options.system && { system: options.system }),
...(options.temperature && { temperature: options.temperature })
};
@ -84,10 +84,10 @@ class ClaudeAPIService {
}
};
const req = https.request(options, (res) => {
const req = https.request(options, res => {
let data = '';
res.on('data', (chunk) => {
res.on('data', chunk => {
data += chunk;
});
@ -105,7 +105,7 @@ class ClaudeAPIService {
});
});
req.on('error', (error) => {
req.on('error', error => {
reject(new Error(`Request error: ${error.message}`));
});

View file

@ -66,7 +66,7 @@ class ClaudeMdAnalyzer {
return {
totalLines: lines.length,
sections,
content: content
content
};
}

View file

@ -112,7 +112,7 @@ Analyze semantic similarity and provide detailed JSON response.`;
isAdaptation: 0
};
let reasoning = [];
const reasoning = [];
// Get publication market data
const pub1 = context.targetPublication1
@ -338,7 +338,7 @@ Analyze semantic similarity and provide detailed JSON response.`;
* @returns {Object} Title similarity result
*/
analyzeTitleSimilarity(title1, title2) {
const normalize = (str) => str.toLowerCase().replace(/[^a-z0-9\s]/g, '').trim();
const normalize = str => str.toLowerCase().replace(/[^a-z0-9\s]/g, '').trim();
const t1 = normalize(title1);
const t2 = normalize(title2);

View file

@ -258,7 +258,7 @@ class CrossReferenceValidator {
text: message.content,
timestamp: message.timestamp || new Date(),
source: 'user',
context: context
context
});
// Calculate relevance to this action

View file

@ -68,8 +68,8 @@ const QUADRANTS = {
persistence: 'HIGH',
description: 'Technical infrastructure, architecture',
keywords: ['code', 'technical', 'architecture', 'infrastructure', 'database', 'api',
'fix', 'bug', 'error', 'authentication', 'security', 'system', 'implementation',
'function', 'method', 'class', 'module', 'component', 'service'],
'fix', 'bug', 'error', 'authentication', 'security', 'system', 'implementation',
'function', 'method', 'class', 'module', 'component', 'service'],
verificationLevel: 'TECHNICAL_REVIEW',
humanOversight: 'TECHNICAL_EXPERTISE',
examples: ['MongoDB port is 27017', 'Use JWT for authentication']
@ -80,8 +80,8 @@ const QUADRANTS = {
persistence: 'CONTEXT_DEPENDENT',
description: 'Innovation, exploration, experimentation',
keywords: ['explore', 'experiment', 'innovate', 'brainstorm', 'creative', 'try',
'alternative', 'alternatives', 'consider', 'possibility', 'investigate',
'research', 'discover', 'prototype', 'test', 'suggest', 'idea'],
'alternative', 'alternatives', 'consider', 'possibility', 'investigate',
'research', 'discover', 'prototype', 'test', 'suggest', 'idea'],
verificationLevel: 'OPTIONAL',
humanOversight: 'INSIGHT_GENERATION',
examples: ['Explore alternative approaches', 'Suggest creative solutions']
@ -676,11 +676,9 @@ class InstructionPersistenceClassifier {
// Handle negations: "never X without confirmation" means confirmation IS required
if (/\b(?:never|don't|do not).*without\s+confirmation\b/i.test(text)) {
params.confirmed = true; // Double negative = positive requirement
}
else if (/\b(?:with confirmation|require confirmation|must confirm|need confirmation)\b/i.test(text)) {
} else if (/\b(?:with confirmation|require confirmation|must confirm|need confirmation)\b/i.test(text)) {
params.confirmed = true;
}
else if (/\b(?:without confirmation|no confirmation|skip confirmation)\b/i.test(text)) {
} else if (/\b(?:without confirmation|no confirmation|skip confirmation)\b/i.test(text)) {
params.confirmed = false;
}

View file

@ -417,7 +417,7 @@ class MetacognitiveVerifier {
// Check for uncertain or weak language
const uncertainPatterns = /\b(maybe|perhaps|might|possibly|not sure|uncertain)\b/i;
const explanationText = (reasoning.explanation || '') + ' ' + (reasoning.steps || []).join(' ');
const explanationText = `${reasoning.explanation || '' } ${ (reasoning.steps || []).join(' ')}`;
if (uncertainPatterns.test(explanationText)) {
score -= 0.2;
issues.push('Reasoning contains uncertain language');
@ -454,7 +454,7 @@ class MetacognitiveVerifier {
const missing = [];
// Penalty for destructive operations without thorough planning
const actionText = (action.type || '') + ' ' + (action.description || '') + ' ' + (action.command || '');
const actionText = `${action.type || '' } ${ action.description || '' } ${ action.command || ''}`;
const isDestructive = /delete|remove|drop|truncate|destroy|force/i.test(actionText) ||
(action.parameters && (action.parameters.destructive || action.parameters.force || action.parameters.delete));
@ -545,7 +545,7 @@ class MetacognitiveVerifier {
/modify_schema|alter.*table|migrate.*database/i
];
const actionText = (action.type || '') + ' ' + (action.description || '') + ' ' + (action.command || '');
const actionText = `${action.type || '' } ${ action.description || '' } ${ action.command || ''}`;
const isDestructive = destructivePatterns.some(pattern => pattern.test(actionText));
// Check if parameters indicate destructive operation
@ -767,7 +767,7 @@ class MetacognitiveVerifier {
return false;
}
const text = (reasoning.explanation || '') + ' ' + (reasoning.steps || []).join(' ');
const text = `${reasoning.explanation || '' } ${ (reasoning.steps || []).join(' ')}`;
const lower = text.toLowerCase();
// Simple contradiction patterns
@ -805,7 +805,7 @@ class MetacognitiveVerifier {
_checkParameterConflicts(parameters, reasoning) {
// Check if parameter values in action conflict with reasoning
const reasoningText = (reasoning.explanation || '') + ' ' + (reasoning.evidence || []).join(' ');
const reasoningText = `${reasoning.explanation || '' } ${ (reasoning.evidence || []).join(' ')}`;
for (const [key, value] of Object.entries(parameters)) {
const valueStr = String(value);
@ -878,7 +878,7 @@ class MetacognitiveVerifier {
*/
_getDecisionReason(decision, scores, criticalFailures) {
if (decision === 'BLOCK') {
return 'Critical failures detected: ' + criticalFailures.map(cf => cf.dimension).join(', ');
return `Critical failures detected: ${ criticalFailures.map(cf => cf.dimension).join(', ')}`;
}
if (decision === 'REQUEST_CLARIFICATION') {
return 'Low confidence in alignment or completeness';

View file

@ -302,9 +302,9 @@ class RuleOptimizer {
suggestions.push({
type: 'missing_imperative',
severity: 'high',
original: ruleText.substring(0, 20) + '...',
original: `${ruleText.substring(0, 20) }...`,
before: ruleText,
after: 'MUST ' + ruleText.charAt(0).toLowerCase() + ruleText.slice(1),
after: `MUST ${ ruleText.charAt(0).toLowerCase() }${ruleText.slice(1)}`,
reason: 'No strong imperative - added "MUST" at start for clarity'
});
}

View file

@ -60,7 +60,7 @@ class TranslationService {
`auth_key=${encodeURIComponent(this.apiKey)}&text=${encodeURIComponent('test')}&target_lang=FR`,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded'
},
timeout: 5000
}
@ -169,7 +169,7 @@ class TranslationService {
// Make translation request
const response = await axios.post(`${this.apiUrl}/translate`, params.toString(), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded'
},
timeout: 30000 // 30 second timeout
});
@ -247,7 +247,7 @@ class TranslationService {
const response = await axios.post(`${this.apiUrl}/translate`, params.toString(), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded'
},
timeout: 60000 // 60 seconds for batch
});

View file

@ -28,10 +28,10 @@ module.exports = {
verifier: MetacognitiveVerifier,
// Convenience methods
classifyInstruction: (instruction) => InstructionPersistenceClassifier.classify(instruction),
classifyInstruction: instruction => InstructionPersistenceClassifier.classify(instruction),
validateAction: (action, context) => CrossReferenceValidator.validate(action, context),
enforceBoundaries: (action, context) => BoundaryEnforcer.enforce(action, context),
analyzePressure: (context) => ContextPressureMonitor.analyzePressure(context),
analyzePressure: context => ContextPressureMonitor.analyzePressure(context),
verifyAction: (action, reasoning, context) => MetacognitiveVerifier.verify(action, reasoning, context),
// Framework status

View file

@ -104,8 +104,8 @@ class KohaService {
success_url: `${process.env.FRONTEND_URL || 'https://agenticgovernance.digital'}/koha/success.html?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.FRONTEND_URL || 'https://agenticgovernance.digital'}/koha.html`,
metadata: {
frequency: frequency,
tier: tier,
frequency,
tier,
currency: donationCurrency,
amount_nzd: String(amountNZD),
exchange_rate: String(exchangeRate),
@ -133,7 +133,7 @@ class KohaService {
sessionParams.subscription_data = {
metadata: {
tier: tier,
tier,
public_acknowledgement: public_acknowledgement ? 'yes' : 'no'
}
};
@ -167,12 +167,12 @@ class KohaService {
// Create pending donation record in database
await Donation.create({
amount: amount,
amount,
currency: donationCurrency.toLowerCase(),
amount_nzd: amountNZD,
exchange_rate_to_nzd: exchangeRate,
frequency: frequency,
tier: tier,
frequency,
tier,
donor: {
name: donor.name || 'Anonymous',
email: donor.email,
@ -193,7 +193,7 @@ class KohaService {
return {
sessionId: session.id,
checkoutUrl: session.url,
frequency: frequency,
frequency,
amount: amount / 100
};
@ -276,8 +276,8 @@ class KohaService {
currency: currency.toLowerCase(),
amount_nzd: amountNZD,
exchange_rate_to_nzd: exchangeRate,
frequency: frequency,
tier: tier,
frequency,
tier,
donor: {
name: session.metadata.donor_name || 'Anonymous',
email: session.customer_email
@ -371,7 +371,7 @@ class KohaService {
const exchangeRate = getExchangeRate(currency);
await Donation.create({
amount: amount,
amount,
currency: currency.toLowerCase(),
amount_nzd: amountNZD,
exchange_rate_to_nzd: exchangeRate,

View file

@ -29,7 +29,7 @@ class DatabaseConnection {
minPoolSize: 2,
maxIdleTimeMS: 30000,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
socketTimeoutMS: 45000
});
await this.client.connect();
@ -105,7 +105,7 @@ const dbConnection = new DatabaseConnection();
module.exports = {
connect: () => dbConnection.connect(),
getDb: () => dbConnection.getDb(),
getCollection: (name) => dbConnection.getCollection(name),
getCollection: name => dbConnection.getCollection(name),
close: () => dbConnection.close(),
isConnected: () => dbConnection.isConnected()
};

View file

@ -94,7 +94,7 @@ function extractExcerpt(content) {
if (!content) return '';
// Remove markdown formatting
let text = content
const text = content
.replace(/^#+\s+/gm, '') // Remove headings
.replace(/\*\*(.+?)\*\*/g, '$1') // Remove bold
.replace(/\*(.+?)\*/g, '$1') // Remove italic
@ -112,7 +112,7 @@ function extractExcerpt(content) {
// Truncate to 150 chars if needed
if (excerpt.length > 150) {
excerpt = excerpt.substring(0, 147) + '...';
excerpt = `${excerpt.substring(0, 147) }...`;
}
return excerpt;

View file

@ -37,7 +37,7 @@ const logger = winston.createLogger({
new winston.transports.File({
filename: logFile,
maxsize: 5242880, // 5MB
maxFiles: 5,
maxFiles: 5
}),
// Error file
@ -45,7 +45,7 @@ const logger = winston.createLogger({
filename: path.join(path.dirname(logFile), 'error.log'),
level: 'error',
maxsize: 5242880,
maxFiles: 5,
maxFiles: 5
})
]
});

View file

@ -25,8 +25,8 @@ renderer.heading = function(text, level, raw) {
// Configure marked
marked.setOptions({
renderer: renderer,
highlight: function(code, lang) {
renderer,
highlight(code, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(code, { language: lang }).value;

View file

@ -27,7 +27,7 @@ class MongooseConnection {
maxIdleTimeMS: 30000,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
family: 4, // Use IPv4, skip trying IPv6
family: 4 // Use IPv4, skip trying IPv6
};
for (let attempt = 1; attempt <= retries; attempt++) {
@ -38,7 +38,7 @@ class MongooseConnection {
logger.info(`✅ Mongoose connected to MongoDB`);
// Handle connection events
mongoose.connection.on('error', (err) => {
mongoose.connection.on('error', err => {
logger.error('Mongoose connection error:', err);
});

View file

@ -38,7 +38,7 @@ async function logSecurityEvent(event) {
severity: event.severity || 'medium'
};
const logLine = JSON.stringify(logEntry) + '\n';
const logLine = `${JSON.stringify(logEntry) }\n`;
try {
// Ensure log directory exists