feat: Enhance FaceAI functionality and improve login process
All checks were successful
Publish FaceAI Container / publish (push) Successful in 4m43s

- Added a retry mechanism for page navigation in `live-site-test-utils.js` to handle transient errors during login.
- Introduced a new function `performLiveLoginRequest` to handle login requests via API, improving the login flow.
- Updated the login process to utilize the new API request method, ensuring a more robust authentication.
- Implemented new utility functions in `rus-ecom-240621.js` for managing FaceAI state and filtering.
- Created `faceai_photo_lookup.jsp` to handle photo lookups, returning JSON responses for better integration with the frontend.
- Updated `faceai_return.php` to redirect users with appropriate parameters after FaceAI processing.
- Modified `fotoCR.jsp` and `fotoCR-en.jsp` to include FaceAI photo IDs in the image elements for better tracking.
- Enhanced the UI to display the number of matched photos dynamically based on FaceAI results.
This commit is contained in:
MaddoScientisto 2026-04-19 14:18:00 +02:00
commit bba8026b7c
17 changed files with 1077 additions and 95 deletions

View file

@ -28,7 +28,7 @@ export const config = {
uploadRoot: process.env.FACEAI_UPLOAD_ROOT || path.join(process.env.FACEAI_RUNTIME_ROOT || '/data/runtime', 'uploads'),
searchTtlSeconds: Number(process.env.FACEAI_SEARCH_TTL_SECONDS || 24 * 60 * 60),
resultTtlSeconds: Number(process.env.FACEAI_RESULT_TTL_SECONDS || 24 * 60 * 60),
processorHeartbeatGraceMs: Number(process.env.FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS || 20 * 1000),
processorHeartbeatGraceMs: Number(process.env.FACEAI_PROCESSOR_HEARTBEAT_GRACE_MS || 60 * 1000),
rateLimitWindowSeconds: Number(process.env.FACEAI_RATE_LIMIT_WINDOW_SECONDS || 10 * 60),
rateLimitMaxRequests: Number(process.env.FACEAI_RATE_LIMIT_MAX_REQUESTS || 5)
rateLimitMaxRequests: Number(process.env.FACEAI_RATE_LIMIT_MAX_REQUESTS || 20)
};

View file

@ -20,6 +20,7 @@ import {
getSearchRecord,
incrementRateLimit,
markSearchFailed,
releaseActiveSearchLock,
saveSearchRecord
} from './redis-store.js';
import { getSearchQueue } from './queue.js';
@ -126,6 +127,27 @@ async function failSearchIfProcessorUnavailable(search) {
);
}
async function resolveBlockingActiveSearch(userId) {
const activeSearchId = await getActiveSearchId(redis, userId);
if (!activeSearchId) {
return null;
}
const existingSearch = await getSearchRecord(redis, activeSearchId);
if (!existingSearch) {
await releaseActiveSearchLock(redis, userId, activeSearchId);
return null;
}
const normalizedSearch = await failSearchIfProcessorUnavailable(existingSearch);
if (!normalizedSearch || normalizedSearch.status === 'completed' || normalizedSearch.status === 'failed') {
await releaseActiveSearchLock(redis, userId, activeSearchId);
return null;
}
return normalizedSearch;
}
function logHealthFailure(details) {
const signature = JSON.stringify(details);
if (signature === lastHealthFailureSignature) {
@ -528,13 +550,14 @@ app.post('/api/searches', requireSession, enforceSearchRateLimit, upload.single(
return;
}
const activeSearchId = await getActiveSearchId(redis, userId);
const activeSearch = await resolveBlockingActiveSearch(userId);
if (activeSearchId) {
if (activeSearch) {
res.status(409).json({
error: 'There is already an operation being processed.',
code: 'ACTIVE_SEARCH_EXISTS',
activeSearchId
activeSearchId: activeSearch.id,
activeSearchStatus: activeSearch.status
});
return;
}