import 'dotenv/config'; import { loadConfig } from '../src/config/env.js'; import { ParseRestClient } from '../src/db/parse-rest.client.js'; import { requiredVocClassNames, VOC_PARSE_CLASSES } from '../src/db/parse-rest.schema.js'; const config = loadConfig(); if (config.storageDriver !== 'parse_rest') throw new Error('STORAGE_DRIVER must be parse_rest'); const workspaceId = process.argv[2] || config.auth.defaultWorkspaceId; const platform = process.argv[3] || 'jd'; const client = new ParseRestClient({ serverUrl: config.parse.serverUrl, appId: config.parse.appId, masterKey: config.parse.masterKey, timeoutMs: config.parse.timeoutMs, }); const schemaResponse = await client.request<{ results: Array<{ className: string; classLevelPermissions?: Record>; }>; }>('/schemas'); const vocSchemas = schemaResponse.results.filter((schema) => requiredVocClassNames.includes(schema.className)); const operations = ['find', 'get', 'count', 'create', 'update', 'delete', 'addField']; const masterOnly = vocSchemas.every((schema) => operations.every((operation) => ( Object.keys(schema.classLevelPermissions?.[operation] ?? {}).length === 0 ))); const where = { workspaceId, platform }; const [ ownProducts, competitorProducts, competitorDetailsReady, metrics, relations, reviews, promptConfigs, defaultModelPrompt, productKnowledge, workspace, completedImport, ] = await Promise.all([ client.count(VOC_PARSE_CLASSES.product, { ...where, role: 'own' }), client.count(VOC_PARSE_CLASSES.product, { ...where, role: 'competitor' }), client.count(VOC_PARSE_CLASSES.product, { ...where, role: 'competitor', source: 'fmode_gateway' }), client.count(VOC_PARSE_CLASSES.dailyMetric, where), client.count(VOC_PARSE_CLASSES.productRelation, where), client.count(VOC_PARSE_CLASSES.review, where), client.count(VOC_PARSE_CLASSES.promptConfig, { workspaceId }), client.findOne<{ template?: string; model?: string }>(VOC_PARSE_CLASSES.promptConfig, { workspaceId, promptKey: 'global.analysis.defaultModel', }), client.count(VOC_PARSE_CLASSES.productKnowledge, { workspaceId }), client.findOne(VOC_PARSE_CLASSES.workspace, { publicId: workspaceId, status: 'active' }), client.findOne(VOC_PARSE_CLASSES.importBatch, { workspaceId, platform, status: 'completed' }), ]); const publicResponse = await fetch( `${config.parse.serverUrl.replace(/\/+$/, '')}/classes/${VOC_PARSE_CLASSES.workspace}?limit=1`, { headers: { 'X-Parse-Application-Id': config.parse.appId }, signal: AbortSignal.timeout(config.parse.timeoutMs), }, ); const publicPayload = await publicResponse.json().catch(() => ({})) as { code?: number }; console.log(JSON.stringify({ schemas: { expected: requiredVocClassNames.length, actual: vocSchemas.length, masterOnly, }, workspaceReady: Boolean(workspace), completedImport: Boolean(completedImport), counts: { ownProducts, competitorProducts, competitorDetailsReady, competitorDetailsPending: competitorProducts - competitorDetailsReady, products: ownProducts + competitorProducts, metrics, relations, reviews, }, aiConfiguration: { promptConfigs, defaultModel: defaultModelPrompt?.model ?? defaultModelPrompt?.template ?? null, ready: promptConfigs === 13 && Boolean(defaultModelPrompt), }, productKnowledge, publicReadBlocked: !publicResponse.ok, publicReadStatus: publicResponse.status, publicReadCode: publicPayload.code ?? null, }, null, 2));