feat: claim durable image derivative jobs
Quality / test (push) Canceled after 0s

This commit is contained in:
2026-09-08 22:04:02 -04:00
parent 7be79f4840
commit abd574293b
4 changed files with 134 additions and 3 deletions
@@ -9,6 +9,8 @@ import {
conditionProfiles,
conditions,
inventoryItems,
inventoryImages,
imageDerivativeJobs,
listings,
mfaMethods,
passwordResetTokens,
@@ -25,6 +27,7 @@ import { createPasswordResetRepository } from '../../src/modules/auth/repositori
import { createMfaMethodRepository } from '../../src/modules/auth/repositories/mfa-method-repository.js';
import { createInventoryItemRepository } from '../../src/modules/inventory/repositories/inventory-item-repository.js';
import { createProductRepository } from '../../src/modules/products/repositories/product-repository.js';
import { createImageDerivativeJobRepository } from '../../src/modules/inventory/repositories/image-derivative-job-repository.js';
import { createSellerRepository } from '../../src/modules/sellers/repositories/seller-repository.js';
const connectionString = process.env.TEST_DATABASE_URL;
@@ -39,6 +42,7 @@ if (!new URL(connectionString).pathname.endsWith('_test')) {
const database = createDatabase(connectionString);
const productRepository = createProductRepository(database.db);
const imageDerivativeJobRepository = createImageDerivativeJobRepository(database.db);
const sellerRepository = createSellerRepository(database.db);
const inventoryItemRepository = createInventoryItemRepository(database.db);
const sessionRepository = createSessionRepository(database.db);
@@ -79,7 +83,7 @@ async function createCatalogPrerequisites() {
beforeEach(async () => {
await database.db.execute(
sql`TRUNCATE security_audit_events, password_reset_tokens, mfa_methods, sessions, inventory_items, products, conditions, condition_profiles, categories, sellers, users CASCADE`,
sql`TRUNCATE image_derivative_jobs, inventory_images, security_audit_events, password_reset_tokens, mfa_methods, sessions, inventory_items, products, conditions, condition_profiles, categories, sellers, users CASCADE`,
);
});
@@ -221,6 +225,44 @@ test('lists only sellers with publicly visible inventory', async () => {
assert.deepEqual(await sellerRepository.listPublic(), []);
});
test('claims and completes image derivative jobs while updating image processing status', async () => {
const { seller, category, condition } = await createCatalogPrerequisites();
const [product] = await database.db.insert(products).values({
sellerId: seller.id,
categoryId: category.id,
name: 'Derivative Job Product',
slug: 'derivative-job-product',
}).returning();
const [inventoryItem] = await database.db.insert(inventoryItems).values({
productId: product.id,
conditionId: condition.id,
}).returning();
const [image] = await database.db.insert(inventoryImages).values({
inventoryItemId: inventoryItem.id,
storageKey: 'inventory/derivative-source.jpg',
originalFilename: 'source.jpg',
mimeType: 'image/jpeg',
fileSize: 4,
width: 100,
height: 100,
}).returning();
const [job] = await database.db.insert(imageDerivativeJobs).values({
inventoryImageId: image.id,
sourceKey: image.storageKey,
}).returning();
const claimed = await imageDerivativeJobRepository.claimNext();
assert.equal(claimed.id, job.id);
assert.equal(claimed.status, 'PROCESSING');
const [processingImage] = await database.db.select().from(inventoryImages).where(sql`id = ${image.id}`);
assert.equal(processingImage.processingStatus, 'PROCESSING');
const completed = await imageDerivativeJobRepository.complete(job.id, [{ name: 'thumbnail', key: 'thumb.webp' }]);
assert.equal(completed.status, 'COMPLETED');
const [completedImage] = await database.db.select().from(inventoryImages).where(sql`id = ${image.id}`);
assert.equal(completedImage.processingStatus, 'COMPLETED');
});
test('retrieves only non-revoked, non-expired sessions', async () => {
const { user, seller } = await createCatalogPrerequisites();
const tokenHash = 'a hashed session token';