feat: add parts catalogs integration, catalog prefetch worker, and vehicle select modal
Integrate external parts catalogs API with auth service, add BullMQ-based catalog prefetch worker for background data caching, expand vehicles service with shared vehicle support, and add vehicle select modal to frontend. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
||||
} from './emex.types';
|
||||
import { mapEmexResponse, createEmptyDecodedVehicle } from './emex.mapper';
|
||||
import { EmexBrowserService } from './emex.browser';
|
||||
import { RedisService } from '../../redis/redis.service';
|
||||
|
||||
// Type definition for the imported scraper module
|
||||
interface EmexScraperModule {
|
||||
@@ -66,6 +67,7 @@ export class EmexService {
|
||||
constructor(
|
||||
private configService: ConfigService,
|
||||
private browserService: EmexBrowserService,
|
||||
private redis: RedisService,
|
||||
) {
|
||||
// __dirname is apps/api/src/integrations/emex/ or dist/integrations/emex/
|
||||
// Scraper lives at <monorepo-root>/scripts/emex-vin-scraper.js
|
||||
@@ -82,6 +84,15 @@ export class EmexService {
|
||||
this.logger.log(`EMEX Service initialized with scraper path: ${this.scraperPath}`);
|
||||
}
|
||||
|
||||
/** Mark EMEX as actively used (5min TTL) to defer prefetch worker */
|
||||
private async touchActivity(): Promise<void> {
|
||||
try {
|
||||
await this.redis.set("prefetch:activity:emex", String(Date.now()), 300);
|
||||
} catch {
|
||||
// Non-critical — don't break the request
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily initialize the scraper module
|
||||
*/
|
||||
@@ -184,6 +195,7 @@ export class EmexService {
|
||||
|
||||
const supported = this.isSupported(cleanVin);
|
||||
this.logger.log(`Decoding VIN: ${cleanVin} (catalog supported: ${supported})`);
|
||||
await this.touchActivity();
|
||||
|
||||
let release: (() => Promise<void>) | null = null;
|
||||
|
||||
@@ -375,6 +387,7 @@ export class EmexService {
|
||||
}
|
||||
|
||||
this.logger.log(`Fetching parts from category URL: ${categoryUrl}`);
|
||||
await this.touchActivity();
|
||||
|
||||
let release: (() => Promise<void>) | null = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user