Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/controllers/llmo/llmo-onboarding.js
Original file line number Diff line number Diff line change
Expand Up @@ -1496,3 +1496,70 @@ export async function performLlmoOffboarding(site, config, context) {
message: 'LLMO offboarding completed successfully',
};
}

export async function appendRowsToQueryIndex(dataFolder, fileNames, env, log) {
const sharepointClient = await createSharePointClient(env);
const redirects = sharepointClient.getRedirects();

const now = Math.floor(Date.now() / 1000);
const rows = fileNames.map((fileName) => {
const name = fileName.endsWith('.json') ? fileName : `${fileName}.json`;
return [
`/${dataFolder}/${name}`,
now,
now,
];
});

log.info(`Appending ${rows.length} rows to query-index.xlsx in ${dataFolder}`);
await redirects.appendRowsToSheet(`/${dataFolder}/query-index.xlsx`, rows);
log.info(`Successfully appended rows to query-index.xlsx in ${dataFolder}`);
}

export async function previewAndPublishQueryIndex(dataFolder, env, log) {
const org = 'adobe';
const site = 'project-elmo-ui-data';
const ref = 'main';
const baseUrl = 'https://admin.hlx.page';
const filePath = `${dataFolder}/query-index.json`;

if (!env.HLX_ONBOARDING_TOKEN) {
throw new Error('HLX_ONBOARDING_TOKEN is not set');
}

const headers = {
Cookie: `auth_token=${env.HLX_ONBOARDING_TOKEN}`,
};

const fetchOptions = { method: 'POST', headers, timeout: 30000 };

const previewUrl = `${baseUrl}/preview/${org}/${site}/${ref}/${filePath}`;
log.info(`Previewing query-index at ${previewUrl}`);
const previewResponse = await fetch(previewUrl, fetchOptions);
if (!previewResponse.ok) {
const errorCode = previewResponse.headers?.get('x-error-code') || '';
const errorMsg = previewResponse.headers?.get('x-error') || '';
let bodyText = '';
try {
bodyText = await previewResponse.text();
} catch { /* noop */ }
log.error(`Preview failed: ${previewResponse.status} ${previewResponse.statusText} | x-error-code: ${errorCode} | x-error: ${errorMsg} | body: ${bodyText}`);
throw new Error(`Preview failed: ${previewResponse.status} ${previewResponse.statusText}`);
}
log.info('Preview of query-index succeeded');

const publishUrl = `${baseUrl}/live/${org}/${site}/${ref}/${filePath}`;
log.info(`Publishing query-index at ${publishUrl}`);
const publishResponse = await fetch(publishUrl, fetchOptions);
if (!publishResponse.ok) {
const errorCode = publishResponse.headers?.get('x-error-code') || '';
const errorMsg = publishResponse.headers?.get('x-error') || '';
let bodyText = '';
try {
bodyText = await publishResponse.text();
} catch { /* noop */ }
log.error(`Publish failed: ${publishResponse.status} ${publishResponse.statusText} | x-error-code: ${errorCode} | x-error: ${errorMsg} | body: ${bodyText}`);
throw new Error(`Publish failed: ${publishResponse.status} ${publishResponse.statusText}`);
}
log.info('Publish of query-index succeeded');
}
65 changes: 65 additions & 0 deletions src/controllers/llmo/llmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import {
performLlmoOnboarding,
performLlmoOffboarding,
postLlmoAlert,
appendRowsToQueryIndex,
previewAndPublishQueryIndex,
} from './llmo-onboarding.js';
import { queryLlmoFiles } from './llmo-query-handler.js';
import { updateModifiedByDetails } from './llmo-config-metadata.js';
Expand Down Expand Up @@ -1773,6 +1775,68 @@ function LlmoController(ctx) {
}
};

const updateQueryIndex = async (context) => {
const { log, env } = context;
const { data } = context;

try {
if (!accessControlUtil.isLLMOAdministrator()) {
return forbidden('Only LLMO administrators can update the query index');
}

if (!data || typeof data !== 'object') {
return badRequest('Request body is required');
}

const { domain, fileNames } = data;

if (!domain) {
return badRequest('domain is required');
}

if (!Array.isArray(fileNames) || fileNames.length === 0) {
return badRequest('fileNames must be a non-empty array of strings');
}

if (fileNames.some((f) => typeof f !== 'string' || !f.trim())) {
return badRequest('Each fileName must be a non-empty string');
}

const { dataAccess } = context;
const { Site } = dataAccess;

const baseURL = composeBaseURL(domain);
const site = await Site.findByBaseURL(baseURL);
if (!site) {
return notFound(`Site not found for domain: ${domain}`);
}

const config = site.getConfig();
const llmoConfig = config.getLlmoConfig();

if (!llmoConfig?.dataFolder) {
return badRequest('LLMO is not onboarded for this site, dataFolder is missing');
}

const { dataFolder } = llmoConfig;

await appendRowsToQueryIndex(dataFolder, fileNames, env, log);
await previewAndPublishQueryIndex(dataFolder, env, log);

log.info(`Successfully updated query-index.xlsx for domain ${domain} with ${fileNames.length} entries`);

return ok({
message: 'query-index.xlsx updated, previewed, and published successfully',
domain,
dataFolder,
entriesAdded: fileNames.length,
});
} catch (error) {
log.error(`Failed to update query-index for domain ${data?.domain}: ${error.message}`);
return internalServerError(`Failed to update query-index: ${error.message}`);
}
};

return {
getLlmoSheetData,
queryLlmoSheetData,
Expand Down Expand Up @@ -1804,6 +1868,7 @@ function LlmoController(ctx) {
checkEdgeOptimizeStatus,
updateEdgeOptimizeCDNRouting,
markOpportunitiesReviewed,
updateQueryIndex,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ export default function getRouteHandlers(
'GET /sites/:siteId/llmo/strategy/demo/brand-presence': llmoController.getDemoBrandPresence,
'GET /sites/:siteId/llmo/strategy/demo/recommendations': llmoController.getDemoRecommendations,
'POST /llmo/onboard': llmoController.onboardCustomer,
'POST /llmo/onboard/update-query-index': llmoController.updateQueryIndex,
'POST /sites/:siteId/llmo/offboard': llmoController.offboardCustomer,
'POST /sites/:siteId/llmo/edge-optimize-config': llmoController.createOrUpdateEdgeConfig,
'GET /sites/:siteId/llmo/edge-optimize-config': llmoController.getEdgeConfig,
Expand Down
1 change: 1 addition & 0 deletions src/routes/required-capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const INTERNAL_ROUTES = [
'GET /sites/:siteId/llmo/strategy/demo/brand-presence',
'GET /sites/:siteId/llmo/strategy/demo/recommendations',
'POST /llmo/onboard',
'POST /llmo/onboard/update-query-index',
'POST /sites/:siteId/llmo/offboard',
'POST /sites/:siteId/llmo/edge-optimize-config',
'POST /sites/:siteId/llmo/edge-optimize-config/stage',
Expand Down
Loading
Loading