feat: complete inventory image and sales workflows
Quality / test (push) Canceled after 0s

Commit the working vertical slices for inventory image processing and the Sale workflow, including Sale history, audited voiding, multi-item persistence, admin UI, migrations, documentation, and tests.
This commit is contained in:
2026-09-09 00:35:57 -04:00
parent ea145191df
commit 8e5ce80196
32 changed files with 1092 additions and 226 deletions
+8 -2
View File
@@ -5,6 +5,7 @@ dotenv.config({ path: fileURLToPath(new URL('../../../../.env', import.meta.url)
import { buildApp } from './build-app.js';
import { createDatabase } from '../infrastructure/database/client.js';
import { resolveProjectImageStorageRoot } from '../infrastructure/images/local-image-storage.js';
import { createPasswordResetNotifier } from '../infrastructure/email/password-reset-notifier.js';
import { createRedisConnection } from '../infrastructure/redis/client.js';
import { createAuthenticationService } from '../modules/auth/services/authentication-service.js';
@@ -36,6 +37,8 @@ import { createPublicProductService } from '../modules/products/services/public-
import { createSearchService } from '../modules/search/services/search-service.js';
import { createSellerRepository } from '../modules/sellers/repositories/seller-repository.js';
import { createPublicSellerService } from '../modules/sellers/services/public-seller-service.js';
import { createSaleRepository } from '../modules/sales/repositories/sale-repository.js';
import { createSaleService } from '../modules/sales/services/sale-service.js';
function parsePort(value) {
const port = Number.parseInt(value ?? '3000', 10);
@@ -48,6 +51,7 @@ function parsePort(value) {
}
async function startServer() {
const imageStorageRoot = resolveProjectImageStorageRoot(process.env.IMAGE_STORAGE_ROOT ?? '.local/image-storage', import.meta.url);
const database = createDatabase();
const redis = await createRedisConnection();
const productRepository = createProductRepository(database.db);
@@ -58,6 +62,7 @@ async function startServer() {
const listingRepository = createListingRepository(database.db);
const sellerRepository = createSellerRepository(database.db);
const conditionRepository = createConditionRepository(database.db);
const saleRepository = createSaleRepository(database.db);
const userRepository = createUserRepository(database.db);
const sessionRepository = createSessionRepository(database.db);
const passwordResetRepository = createPasswordResetRepository(database.db);
@@ -71,7 +76,7 @@ async function startServer() {
});
const passwordResetNotifier = createPasswordResetNotifier();
const publicImageService = createPublicImageService({
imageStorage: createLocalImageStorage(process.env.IMAGE_STORAGE_ROOT ?? '.local/image-storage'),
imageStorage: createLocalImageStorage(imageStorageRoot),
inventoryImageRepository,
});
const authenticationService = createAuthenticationService({
@@ -108,11 +113,12 @@ async function startServer() {
publicImageService,
publicInventoryService: createPublicInventoryService({ inventoryItemRepository, publicImageService }),
inventoryImageService: createInventoryImageService({
imageStorage: createLocalImageStorage(process.env.IMAGE_STORAGE_ROOT ?? '.local/image-storage'),
imageStorage: createLocalImageStorage(imageStorageRoot),
imageDerivativeJobRepository,
inventoryImageRepository,
}),
listingService: createListingService({ listingRepository, inventoryImageRepository }),
saleService: createSaleService({ saleRepository }),
publicListingService: createPublicListingService({ listingRepository, publicImageService }),
productService: createProductService({ productRepository }),
publicProductService: createPublicProductService({ productRepository }),