feat: add auto-increment id, size/duration tracking, and soft cleanup to conversion_jobs
Rename the old CHAR(36) id to uuid (still used for public URLs and file naming) and add a real auto-increment id as the primary key. Track input/output file size and conversion duration per job. Cleanup no longer deletes rows; it marks cleaned_at and skips already-cleaned expired jobs on later runs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+9
-8
@@ -10,7 +10,7 @@ import { registerImageToPdfConverter } from './converters/imageToPdf.js';
|
||||
import { registerDocumentConverters } from './converters/document.js';
|
||||
import { resolveInputFormat } from './mime.js';
|
||||
import { deleteIfExists } from './storage.js';
|
||||
import { createJob, getJobById } from './jobs/jobRepository.js';
|
||||
import { createJob, getJobByUuid } from './jobs/jobRepository.js';
|
||||
import { outputPath } from './storage.js';
|
||||
|
||||
let convertersRegistered = false;
|
||||
@@ -77,7 +77,7 @@ export function createApp(config, pool) {
|
||||
for (let i = 0; i < req.files.length; i += 1) {
|
||||
const file = req.files[i];
|
||||
const targetFormat = targetFormats[i];
|
||||
const id = path.basename(file.filename, path.extname(file.filename));
|
||||
const uuid = path.basename(file.filename, path.extname(file.filename));
|
||||
const sourceFormat = path.extname(file.filename).slice(1).toLowerCase();
|
||||
|
||||
const { mime, valid } = await resolveInputFormat(file.path, sourceFormat);
|
||||
@@ -99,30 +99,31 @@ export function createApp(config, pool) {
|
||||
|
||||
const expiresAt = new Date(Date.now() + config.retentionHours * 3600 * 1000);
|
||||
await createJob(pool, {
|
||||
id,
|
||||
uuid,
|
||||
family: registryEntry.family,
|
||||
sourceFormat,
|
||||
targetFormat,
|
||||
originalFilename: file.originalname,
|
||||
inputPath: file.filename,
|
||||
inputMimeType: mime,
|
||||
inputSizeBytes: file.size,
|
||||
expiresAt,
|
||||
});
|
||||
|
||||
results.push({ file: file.originalname, id, status: 'pending' });
|
||||
results.push({ file: file.originalname, id: uuid, status: 'pending' });
|
||||
}
|
||||
|
||||
res.status(201).json({ jobs: results });
|
||||
});
|
||||
|
||||
app.get('/api/jobs/:id', async (req, res) => {
|
||||
const job = await getJobById(pool, req.params.id);
|
||||
const job = await getJobByUuid(pool, req.params.id);
|
||||
if (!job) {
|
||||
return res.status(404).json({ error: 'Job not found' });
|
||||
}
|
||||
|
||||
res.json({
|
||||
id: job.id,
|
||||
id: job.uuid,
|
||||
status: job.status,
|
||||
originalFilename: job.originalFilename,
|
||||
sourceFormat: job.sourceFormat,
|
||||
@@ -138,7 +139,7 @@ export function createApp(config, pool) {
|
||||
}
|
||||
|
||||
app.get('/api/jobs/:id/download', async (req, res) => {
|
||||
const job = await getJobById(pool, req.params.id);
|
||||
const job = await getJobByUuid(pool, req.params.id);
|
||||
if (!job) {
|
||||
return res.status(404).json({ error: 'Job not found' });
|
||||
}
|
||||
@@ -146,7 +147,7 @@ export function createApp(config, pool) {
|
||||
return res.status(409).json({ error: `Job is not ready yet (status: ${job.status})` });
|
||||
}
|
||||
|
||||
const filePath = outputPath(config, job.id, job.targetFormat);
|
||||
const filePath = outputPath(config, job.uuid, job.targetFormat);
|
||||
const downloadFilename = `${path.parse(job.originalFilename).name}.${job.targetFormat}`;
|
||||
res.set('Content-Type', job.outputMimeType);
|
||||
res.set('Content-Disposition', contentDispositionHeader(downloadFilename));
|
||||
|
||||
Reference in New Issue
Block a user