verify-parse-rest.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import 'dotenv/config';
  2. import { loadConfig } from '../src/config/env.js';
  3. import { ParseRestClient } from '../src/db/parse-rest.client.js';
  4. import { requiredVocClassNames, VOC_PARSE_CLASSES } from '../src/db/parse-rest.schema.js';
  5. const config = loadConfig();
  6. if (config.storageDriver !== 'parse_rest') throw new Error('STORAGE_DRIVER must be parse_rest');
  7. const workspaceId = process.argv[2] || config.auth.defaultWorkspaceId;
  8. const platform = process.argv[3] || 'jd';
  9. const client = new ParseRestClient({
  10. serverUrl: config.parse.serverUrl,
  11. appId: config.parse.appId,
  12. masterKey: config.parse.masterKey,
  13. timeoutMs: config.parse.timeoutMs,
  14. });
  15. const schemaResponse = await client.request<{
  16. results: Array<{
  17. className: string;
  18. classLevelPermissions?: Record<string, Record<string, unknown>>;
  19. }>;
  20. }>('/schemas');
  21. const vocSchemas = schemaResponse.results.filter((schema) => requiredVocClassNames.includes(schema.className));
  22. const operations = ['find', 'get', 'count', 'create', 'update', 'delete', 'addField'];
  23. const masterOnly = vocSchemas.every((schema) => operations.every((operation) => (
  24. Object.keys(schema.classLevelPermissions?.[operation] ?? {}).length === 0
  25. )));
  26. const where = { workspaceId, platform };
  27. const [products, metrics, relations, reviews, workspace, completedImport] = await Promise.all([
  28. client.count(VOC_PARSE_CLASSES.product, where),
  29. client.count(VOC_PARSE_CLASSES.dailyMetric, where),
  30. client.count(VOC_PARSE_CLASSES.productRelation, where),
  31. client.count(VOC_PARSE_CLASSES.review, where),
  32. client.findOne(VOC_PARSE_CLASSES.workspace, { publicId: workspaceId, status: 'active' }),
  33. client.findOne(VOC_PARSE_CLASSES.importBatch, { workspaceId, platform, status: 'completed' }),
  34. ]);
  35. const publicResponse = await fetch(
  36. `${config.parse.serverUrl.replace(/\/+$/, '')}/classes/${VOC_PARSE_CLASSES.workspace}?limit=1`,
  37. {
  38. headers: { 'X-Parse-Application-Id': config.parse.appId },
  39. signal: AbortSignal.timeout(config.parse.timeoutMs),
  40. },
  41. );
  42. const publicPayload = await publicResponse.json().catch(() => ({})) as { code?: number };
  43. console.log(JSON.stringify({
  44. schemas: {
  45. expected: requiredVocClassNames.length,
  46. actual: vocSchemas.length,
  47. masterOnly,
  48. },
  49. workspaceReady: Boolean(workspace),
  50. completedImport: Boolean(completedImport),
  51. counts: { products, metrics, relations, reviews },
  52. publicReadBlocked: !publicResponse.ok,
  53. publicReadStatus: publicResponse.status,
  54. publicReadCode: publicPayload.code ?? null,
  55. }, null, 2));