fix: conform moved code to eslint indent/quotes, 4-arg mutation callbacks
- eslint --fix on branch-changed backend files (indent shift from the module-wrapper nesting in decomposed files); backend lint now 904 errors vs 1,315 on main - useMutationWithToast forwards all four TanStack v5 callback args (tsc -b strict build flagged the 3-arg passthrough)
This commit is contained in:
@@ -1177,7 +1177,7 @@ async function runBackupInternal(isManual = false) {
|
||||
|
||||
async function startBackupService() {
|
||||
try {
|
||||
const config = await resolveConfigWithFallback();
|
||||
const config = await resolveConfigWithFallback();
|
||||
if (!config || !normalizeBoolean(config.backup_enabled)) {
|
||||
if (backupJob) {
|
||||
backupJob.stop();
|
||||
|
||||
@@ -51,29 +51,29 @@ async function listContracts({ filters = {}, sort = 'issue_desc', page = 1, page
|
||||
const total = ensureInt(totalRow?.total || 0);
|
||||
|
||||
switch (sort) {
|
||||
case 'oldest':
|
||||
query = query.orderBy('contracts.created_at', 'asc').orderBy('contracts.id', 'asc');
|
||||
break;
|
||||
case 'issue_asc':
|
||||
query = query.orderBy('contracts.issue_date', 'asc').orderBy('contracts.id', 'asc');
|
||||
break;
|
||||
case 'issue_desc':
|
||||
query = query.orderBy('contracts.issue_date', 'desc').orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('contracts.created_at', 'desc').orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'oldest':
|
||||
query = query.orderBy('contracts.created_at', 'asc').orderBy('contracts.id', 'asc');
|
||||
break;
|
||||
case 'issue_asc':
|
||||
query = query.orderBy('contracts.issue_date', 'asc').orderBy('contracts.id', 'asc');
|
||||
break;
|
||||
case 'issue_desc':
|
||||
query = query.orderBy('contracts.issue_date', 'desc').orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('contracts.created_at', 'desc').orderBy('contracts.id', 'desc');
|
||||
break;
|
||||
}
|
||||
|
||||
const offset = Math.max(0, (page - 1) * pageSize);
|
||||
|
||||
@@ -78,8 +78,8 @@ async function buildPlaceholderContext(contract, customer) {
|
||||
: '';
|
||||
const customerAddress = customer
|
||||
? [customer.address_line1, customer.address_line2, customer.postal_code, customer.city]
|
||||
.filter(Boolean)
|
||||
.join(', ')
|
||||
.filter(Boolean)
|
||||
.join(', ')
|
||||
: '';
|
||||
|
||||
return {
|
||||
|
||||
@@ -73,21 +73,21 @@ async function recordCustomerSignature({ token, name, ip, signatureDataUrl, acce
|
||||
// consistent and saves a redundant read.
|
||||
const persistedIp = await maybeStoreIp(ip);
|
||||
try {
|
||||
await db.transaction(async (trx) => {
|
||||
await trx('contracts').where({ id: contract.id }).update({
|
||||
status: 'signed_by_customer',
|
||||
signed_by_customer_at: now,
|
||||
signed_customer_name: String(name).trim(),
|
||||
signed_customer_ip: persistedIp,
|
||||
signed_customer_signature_path: signaturePath,
|
||||
updated_at: now,
|
||||
await db.transaction(async (trx) => {
|
||||
await trx('contracts').where({ id: contract.id }).update({
|
||||
status: 'signed_by_customer',
|
||||
signed_by_customer_at: now,
|
||||
signed_customer_name: String(name).trim(),
|
||||
signed_customer_ip: persistedIp,
|
||||
signed_customer_signature_path: signaturePath,
|
||||
updated_at: now,
|
||||
});
|
||||
await trx('contract_action_tokens').where({ id: tokenRow.id }).update({
|
||||
used_at: now,
|
||||
used_action: 'signed_by_customer',
|
||||
used_ip: persistedIp,
|
||||
});
|
||||
});
|
||||
await trx('contract_action_tokens').where({ id: tokenRow.id }).update({
|
||||
used_at: now,
|
||||
used_action: 'signed_by_customer',
|
||||
used_ip: persistedIp,
|
||||
});
|
||||
});
|
||||
} catch (txErr) {
|
||||
// C.7 — clean up the orphan signature PNG we wrote before the
|
||||
// transaction. The DB rollback already undid the contract +
|
||||
@@ -230,14 +230,14 @@ async function recordAdminCountersignature(contractId, { name, ip, signatureData
|
||||
const newStatus = contract.status === 'signed_by_customer' ? 'fully_signed' : 'signed_by_admin';
|
||||
const persistedAdminIp = await maybeStoreIp(ip);
|
||||
try {
|
||||
await db('contracts').where({ id: contract.id }).update({
|
||||
status: newStatus,
|
||||
signed_by_admin_at: now,
|
||||
signed_admin_name: String(name).trim(),
|
||||
signed_admin_ip: persistedAdminIp,
|
||||
signed_admin_signature_path: signaturePath,
|
||||
updated_at: now,
|
||||
});
|
||||
await db('contracts').where({ id: contract.id }).update({
|
||||
status: newStatus,
|
||||
signed_by_admin_at: now,
|
||||
signed_admin_name: String(name).trim(),
|
||||
signed_admin_ip: persistedAdminIp,
|
||||
signed_admin_signature_path: signaturePath,
|
||||
updated_at: now,
|
||||
});
|
||||
} catch (updateErr) {
|
||||
// C.7 — clean up the orphan signature PNG if the contract row
|
||||
// update threw. Best-effort; log on cleanup failure and re-throw
|
||||
|
||||
@@ -329,11 +329,11 @@ async function createInvoice(payload, adminId, trx = db) {
|
||||
* code should reach for the clearer `spawnInstallmentInvoices`.
|
||||
*/
|
||||
async function spawnInstallmentInvoices({ trx, eventId, quoteId, customer, currency, language,
|
||||
lineItems, totals, installments, eventDate, adminId,
|
||||
ccPdfEmail, netDays,
|
||||
eventName, eventTimeStart, eventTimeEnd,
|
||||
paymentNetDaysTemplateId, paymentTimingTemplateId,
|
||||
paymentTermSnapshot, dealUuid, hold = false }) {
|
||||
lineItems, totals, installments, eventDate, adminId,
|
||||
ccPdfEmail, netDays,
|
||||
eventName, eventTimeStart, eventTimeEnd,
|
||||
paymentNetDaysTemplateId, paymentTimingTemplateId,
|
||||
paymentTermSnapshot, dealUuid, hold = false }) {
|
||||
// Monthly-billing intercept (migration 128). Quote → invoice
|
||||
// conversion for a monthly-mode customer doesn't fan out N
|
||||
// installment invoices — the customer pays one consolidated bill
|
||||
|
||||
@@ -45,20 +45,20 @@ function computeScheduledSendAt(trigger, offsetDays, eventDate, baseDate = new D
|
||||
const offset = ensureInt(offsetDays) * ms;
|
||||
const eventTs = eventDate ? new Date(eventDate).getTime() : null;
|
||||
switch (trigger) {
|
||||
case 'quote_accepted':
|
||||
return new Date(baseDate.getTime() + offset);
|
||||
case 'before_event':
|
||||
case 'after_event':
|
||||
if (!eventTs) return new Date(baseDate.getTime() + offset);
|
||||
return new Date(eventTs + offset);
|
||||
case 'after_delivery':
|
||||
// Treat as event_date + 14 days as a sensible default; admin can
|
||||
// edit the scheduled_send_at on the invoice later.
|
||||
if (!eventTs) return new Date(baseDate.getTime() + 14 * ms + offset);
|
||||
return new Date(eventTs + 14 * ms + offset);
|
||||
case 'fixed_date':
|
||||
default:
|
||||
return new Date(baseDate.getTime() + offset);
|
||||
case 'quote_accepted':
|
||||
return new Date(baseDate.getTime() + offset);
|
||||
case 'before_event':
|
||||
case 'after_event':
|
||||
if (!eventTs) return new Date(baseDate.getTime() + offset);
|
||||
return new Date(eventTs + offset);
|
||||
case 'after_delivery':
|
||||
// Treat as event_date + 14 days as a sensible default; admin can
|
||||
// edit the scheduled_send_at on the invoice later.
|
||||
if (!eventTs) return new Date(baseDate.getTime() + 14 * ms + offset);
|
||||
return new Date(eventTs + 14 * ms + offset);
|
||||
case 'fixed_date':
|
||||
default:
|
||||
return new Date(baseDate.getTime() + offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ async function replaceReconciliationLine(
|
||||
const subtotal = topLineSubtotal != null
|
||||
? topLineSubtotal
|
||||
: nonRecon.filter((x) => x.parent_position == null)
|
||||
.reduce((s, x) => s + ensureInt(x.line_total_minor), 0);
|
||||
.reduce((s, x) => s + ensureInt(x.line_total_minor), 0);
|
||||
const adjustment = netSlice - subtotal;
|
||||
if (adjustment === 0) return;
|
||||
|
||||
|
||||
@@ -67,35 +67,35 @@ async function listInvoices({ filters = {}, sort = 'issue_desc', page = 1, pageS
|
||||
const total = ensureInt(countRow?.total || 0);
|
||||
|
||||
switch (sort) {
|
||||
// "Newest" / "Oldest" means newest/oldest by CREATION time, not
|
||||
// by issue_date. Issue_date is admin-controlled (used for tax
|
||||
// accruals, retro-dating, future-dating) so it can drift from
|
||||
// actual chronology — sorting by it makes a just-created invoice
|
||||
// disappear into the middle of the list whenever its issue_date
|
||||
// is set to something other than today. created_at always
|
||||
// reflects when the row landed in the DB. id is the tiebreaker
|
||||
// for rows that share a created_at second.
|
||||
case 'oldest': query = query.orderBy('invoices.created_at', 'asc').orderBy('invoices.id', 'asc'); break;
|
||||
case 'issue_asc': query = query.orderBy('invoices.issue_date', 'asc').orderBy('invoices.id', 'asc'); break;
|
||||
case 'issue_desc': query = query.orderBy('invoices.issue_date', 'desc').orderBy('invoices.id', 'desc'); break;
|
||||
case 'due_asc': query = query.orderBy('invoices.due_date', 'asc'); break;
|
||||
case 'due_desc': query = query.orderBy('invoices.due_date', 'desc'); break;
|
||||
case 'value_asc': query = query.orderBy('invoices.total_amount_minor', 'asc'); break;
|
||||
case 'value_desc': query = query.orderBy('invoices.total_amount_minor', 'desc'); break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('invoices.created_at', 'desc').orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
// "Newest" / "Oldest" means newest/oldest by CREATION time, not
|
||||
// by issue_date. Issue_date is admin-controlled (used for tax
|
||||
// accruals, retro-dating, future-dating) so it can drift from
|
||||
// actual chronology — sorting by it makes a just-created invoice
|
||||
// disappear into the middle of the list whenever its issue_date
|
||||
// is set to something other than today. created_at always
|
||||
// reflects when the row landed in the DB. id is the tiebreaker
|
||||
// for rows that share a created_at second.
|
||||
case 'oldest': query = query.orderBy('invoices.created_at', 'asc').orderBy('invoices.id', 'asc'); break;
|
||||
case 'issue_asc': query = query.orderBy('invoices.issue_date', 'asc').orderBy('invoices.id', 'asc'); break;
|
||||
case 'issue_desc': query = query.orderBy('invoices.issue_date', 'desc').orderBy('invoices.id', 'desc'); break;
|
||||
case 'due_asc': query = query.orderBy('invoices.due_date', 'asc'); break;
|
||||
case 'due_desc': query = query.orderBy('invoices.due_date', 'desc'); break;
|
||||
case 'value_asc': query = query.orderBy('invoices.total_amount_minor', 'asc'); break;
|
||||
case 'value_desc': query = query.orderBy('invoices.total_amount_minor', 'desc'); break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('invoices.created_at', 'desc').orderBy('invoices.id', 'desc');
|
||||
break;
|
||||
}
|
||||
|
||||
const offset = Math.max(0, (page - 1) * pageSize);
|
||||
|
||||
@@ -358,7 +358,7 @@ async function sendStorno(stornoId, adminId) {
|
||||
// email body — customers' bookkeepers expect to see the pair.
|
||||
const originalRow = storno.cancels_invoice_id
|
||||
? await db('invoices').where({ id: storno.cancels_invoice_id })
|
||||
.select('invoice_number', 'issue_date').first()
|
||||
.select('invoice_number', 'issue_date').first()
|
||||
: null;
|
||||
|
||||
const { to: stornoTo, cc: stornoCc } = resolveBillingRecipients(customer, storno.cc_pdf_email);
|
||||
|
||||
@@ -400,40 +400,40 @@ async function listQuotes({ filters = {}, sort = 'issue_desc', page = 1, pageSiz
|
||||
const total = ensureInt(totalRow?.total || 0);
|
||||
|
||||
switch (sort) {
|
||||
// "Newest" / "Oldest" sort by CREATION time, not issue_date —
|
||||
// the latter is admin-controlled (retro-dated quotes, future-
|
||||
// dated quotes for accruals) and drifts from actual chronology.
|
||||
// Sorting by created_at always puts a just-saved quote at the
|
||||
// top of the "Newest first" list.
|
||||
case 'oldest':
|
||||
query = query.orderBy('quotes.created_at', 'asc').orderBy('quotes.id', 'asc');
|
||||
break;
|
||||
case 'issue_asc':
|
||||
query = query.orderBy('quotes.issue_date', 'asc').orderBy('quotes.id', 'asc');
|
||||
break;
|
||||
case 'issue_desc':
|
||||
query = query.orderBy('quotes.issue_date', 'desc').orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'value_asc':
|
||||
query = query.orderBy('quotes.total_amount_minor', 'asc');
|
||||
break;
|
||||
case 'value_desc':
|
||||
query = query.orderBy('quotes.total_amount_minor', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('quotes.created_at', 'desc').orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
// "Newest" / "Oldest" sort by CREATION time, not issue_date —
|
||||
// the latter is admin-controlled (retro-dated quotes, future-
|
||||
// dated quotes for accruals) and drifts from actual chronology.
|
||||
// Sorting by created_at always puts a just-saved quote at the
|
||||
// top of the "Newest first" list.
|
||||
case 'oldest':
|
||||
query = query.orderBy('quotes.created_at', 'asc').orderBy('quotes.id', 'asc');
|
||||
break;
|
||||
case 'issue_asc':
|
||||
query = query.orderBy('quotes.issue_date', 'asc').orderBy('quotes.id', 'asc');
|
||||
break;
|
||||
case 'issue_desc':
|
||||
query = query.orderBy('quotes.issue_date', 'desc').orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'customer_asc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) asc')
|
||||
.orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'customer_desc':
|
||||
query = query
|
||||
.orderByRaw('COALESCE(customer_accounts.company_name, customer_accounts.last_name, customer_accounts.email) desc')
|
||||
.orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
case 'value_asc':
|
||||
query = query.orderBy('quotes.total_amount_minor', 'asc');
|
||||
break;
|
||||
case 'value_desc':
|
||||
query = query.orderBy('quotes.total_amount_minor', 'desc');
|
||||
break;
|
||||
case 'newest':
|
||||
default:
|
||||
query = query.orderBy('quotes.created_at', 'desc').orderBy('quotes.id', 'desc');
|
||||
break;
|
||||
}
|
||||
|
||||
const offset = Math.max(0, (page - 1) * pageSize);
|
||||
@@ -1508,8 +1508,8 @@ async function convertToInvoiceOnly(quoteId, adminId, options = {}) {
|
||||
|
||||
const paymentTermSnapshot = quote.payment_term_snapshot
|
||||
? (typeof quote.payment_term_snapshot === 'string'
|
||||
? JSON.parse(quote.payment_term_snapshot)
|
||||
: quote.payment_term_snapshot)
|
||||
? JSON.parse(quote.payment_term_snapshot)
|
||||
: quote.payment_term_snapshot)
|
||||
: null;
|
||||
|
||||
const invoiceService = require('./invoiceService');
|
||||
@@ -1621,8 +1621,8 @@ async function convertToEvent(quoteId, adminId, options = {}) {
|
||||
|
||||
const paymentTermSnapshot = quote.payment_term_snapshot
|
||||
? (typeof quote.payment_term_snapshot === 'string'
|
||||
? JSON.parse(quote.payment_term_snapshot)
|
||||
: quote.payment_term_snapshot)
|
||||
? JSON.parse(quote.payment_term_snapshot)
|
||||
: quote.payment_term_snapshot)
|
||||
: null;
|
||||
|
||||
// Lazy import to avoid the circular dep.
|
||||
|
||||
@@ -200,20 +200,20 @@ class RestoreService {
|
||||
// Step 6: Perform the actual restore based on type
|
||||
let restoreResult;
|
||||
switch (options.restoreType) {
|
||||
case 'full':
|
||||
restoreResult = await this.performFullRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'database':
|
||||
restoreResult = await this.performDatabaseRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'files':
|
||||
restoreResult = await this.performFilesRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'selective':
|
||||
restoreResult = await this.performSelectiveRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown restore type: ${options.restoreType}`);
|
||||
case 'full':
|
||||
restoreResult = await this.performFullRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'database':
|
||||
restoreResult = await this.performDatabaseRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'files':
|
||||
restoreResult = await this.performFilesRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
case 'selective':
|
||||
restoreResult = await this.performSelectiveRestore(localBackupPath, manifest, options);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown restore type: ${options.restoreType}`);
|
||||
}
|
||||
|
||||
// Step 7: Post-restore verification
|
||||
@@ -308,7 +308,7 @@ class RestoreService {
|
||||
this.log('info', 'Post-restore migrations applied');
|
||||
} catch (migErr) {
|
||||
this.log('warn',
|
||||
`Post-restore migrate:safe failed — restore data is in place but the schema may lag the running image. ` +
|
||||
'Post-restore migrate:safe failed — restore data is in place but the schema may lag the running image. ' +
|
||||
`A container restart will retry via wait-for-db.sh. Error: ${migErr.message}`);
|
||||
}
|
||||
|
||||
@@ -409,8 +409,8 @@ class RestoreService {
|
||||
if (restoreRun) {
|
||||
const failureMessage = rollbackAttempted
|
||||
? (rollbackSucceeded
|
||||
? `${error.message} (rolled back successfully to pre-restore state)`
|
||||
: `${error.message} | ROLLBACK ALSO FAILED: ${rollbackError} — destination is in a partial state, inspect before retrying`)
|
||||
? `${error.message} (rolled back successfully to pre-restore state)`
|
||||
: `${error.message} | ROLLBACK ALSO FAILED: ${rollbackError} — destination is in a partial state, inspect before retrying`)
|
||||
: `${error.message} (no pre-restore backup available — destination may be partial)`;
|
||||
await db('restore_runs').where('id', restoreRun.id).update({
|
||||
completed_at: new Date(),
|
||||
@@ -888,9 +888,9 @@ class RestoreService {
|
||||
throw new Error(
|
||||
`Database backup file not found. Tried: ${candidates.join(', ')}. ` +
|
||||
`Manifest recorded path: ${dbBackupFile}. ` +
|
||||
`Hint: this usually means the manifest's database.backup_file path no longer ` +
|
||||
`exists on disk (deleted? moved? volume not mounted?). Check ` +
|
||||
`~/<your-compose-dir>/backup/database/ on the host.`
|
||||
'Hint: this usually means the manifest\'s database.backup_file path no longer ' +
|
||||
'exists on disk (deleted? moved? volume not mounted?). Check ' +
|
||||
'~/<your-compose-dir>/backup/database/ on the host.'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1043,8 +1043,8 @@ class RestoreService {
|
||||
await spawnAsync('psql', [
|
||||
'-h', host, '-p', String(port), '-U', user, '-d', maintenanceDb,
|
||||
'-c',
|
||||
`SELECT pg_terminate_backend(pid) FROM pg_stat_activity ` +
|
||||
`WHERE datname = '${database.replace(/'/g, "''")}' AND pid <> pg_backend_pid()`,
|
||||
'SELECT pg_terminate_backend(pid) FROM pg_stat_activity ' +
|
||||
`WHERE datname = '${database.replace(/'/g, '\'\'')}' AND pid <> pg_backend_pid()`,
|
||||
], { env });
|
||||
|
||||
// Drop and recreate database (extremely dangerous!)
|
||||
|
||||
@@ -494,14 +494,14 @@ class S3StorageAdapter extends stream.EventEmitter {
|
||||
|
||||
let command;
|
||||
switch (operation.toLowerCase()) {
|
||||
case 'getobject':
|
||||
command = new GetObjectCommand(params);
|
||||
break;
|
||||
case 'putobject':
|
||||
command = new PutObjectCommand(params);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported operation: ${operation}`);
|
||||
case 'getobject':
|
||||
command = new GetObjectCommand(params);
|
||||
break;
|
||||
case 'putobject':
|
||||
command = new PutObjectCommand(params);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported operation: ${operation}`);
|
||||
}
|
||||
|
||||
return await getSignedUrl(this.s3Client, command, {
|
||||
@@ -638,7 +638,7 @@ class S3StorageAdapter extends stream.EventEmitter {
|
||||
UploadId: uploadId
|
||||
}));
|
||||
} catch (abortError) {
|
||||
logger.error(`Failed to abort multipart upload:`, abortError);
|
||||
logger.error('Failed to abort multipart upload:', abortError);
|
||||
}
|
||||
|
||||
throw error;
|
||||
|
||||
@@ -64,8 +64,8 @@ class WatermarkGeneratorService {
|
||||
const storageKey = resolvePhotoStorageKey(event, photo);
|
||||
const result = storageKey
|
||||
? await withLocalCopy(storageKey, (lp) =>
|
||||
watermarkService.generateAndSaveWatermark(photo, lp, settings)
|
||||
)
|
||||
watermarkService.generateAndSaveWatermark(photo, lp, settings)
|
||||
)
|
||||
: await watermarkService.generateAndSaveWatermark(photo, resolvePhotoFilePath(event, photo), settings);
|
||||
|
||||
if (result.success) {
|
||||
@@ -170,8 +170,8 @@ class WatermarkGeneratorService {
|
||||
const storageKey = resolvePhotoStorageKey(event, photo);
|
||||
const result = storageKey
|
||||
? await withLocalCopy(storageKey, (lp) =>
|
||||
watermarkService.generateAndSaveWatermark(photo, lp, settings)
|
||||
)
|
||||
watermarkService.generateAndSaveWatermark(photo, lp, settings)
|
||||
)
|
||||
: await watermarkService.generateAndSaveWatermark(photo, resolvePhotoFilePath(event, photo), settings);
|
||||
|
||||
if (result.success) {
|
||||
|
||||
Reference in New Issue
Block a user