/* * Shared constants for SaaS VOC Cloud Functions * These constants are shared across all cloud functions */ // Allowed actions - each action maps to a specific cloud function const ACTIONS = new Set([ // Context & Workspace 'context.get', 'workspace.list', 'workspace.member.update', // Data Source & Import 'data-source.list', 'import.list', 'audit.list', // Domestic VOC 'domestic.snapshot', 'domestic.products.list', 'domestic.product.get', 'domestic.reviews.list', 'domestic.relations.list', // Sync 'sync.enqueue', 'sync.jobs.list', 'sync.job.get', 'sync.job.events', 'sync.job.retry', 'sync.job.cancel', // Analysis 'analysis.list', 'analysis.create', 'analysis.update', 'insight-decision.list', 'insight-decision.get', 'insight-decision.create', // Actions & Alerts 'action.list', 'action.create', 'action.update', 'alert.list', 'alert.create', 'alert.update', // Knowledge 'knowledge.products.list', 'knowledge.product.upsert', 'knowledge.product.delete', // Competitor 'competitor.overview', 'competitor.refresh', 'competitor.history', 'competitor.alerts', 'competitor.impacts', 'competitor.tasks.list', 'competitor.tasks.create', 'competitor.tasks.update', 'competitor.run.get', // Listing 'listing.overview', 'listing.products.list', 'listing.product.get', 'listing.product.score', 'listing.jd-voc-score.get', 'listing.jd-voc-image-review.run', 'listing.score-job.create', 'listing.score-job.list', 'listing.score-job.get', 'listing.score-job.items', 'listing.score-job.retry', 'listing.score-job.cancel', 'listing.versions.list', 'listing.version.create', 'listing.version.adopt', // AI 'ai.status', 'ai.test', 'ai.prompts.list', 'ai.prompt.update', 'ai.chat', // Upstream 'upstream.amazon', 'upstream.sorftime', 'upstream.tikhub', 'upstream.domestic', ]); // Map actions to Parse class names for generic read operations const CLASS_BY_READ_ACTION = { 'workspace.list': 'VocWorkspace', 'workspace.members.list': 'VocWorkspaceMember', 'data-source.list': 'VocSourceConnection', 'import.list': 'VocImportBatch', 'audit.list': 'VocAuditLog', 'domestic.products.list': 'VocProduct', 'domestic.reviews.list': 'VocReview', 'domestic.relations.list': 'VocProductRelation', 'sync.jobs.list': 'VocSyncJob', 'sync.job.events': 'VocSyncJobEvent', 'analysis.list': 'VocAnalysisRun', 'insight-decision.list': 'VocInsightDecision', 'action.list': 'VocActionItem', 'alert.list': 'VocAlert', 'knowledge.products.list': 'VocProductKnowledge', 'ai.prompts.list': 'VocPromptConfig', 'listing.products.list': 'VocListingSourceSnapshot', 'listing.score-job.list': 'VocListingScoreJob', 'listing.versions.list': 'VocListingVersion', 'competitor.tasks.list': 'VocCompetitorOptimizationTask', }; // Roles that can perform write operations const WRITE_ROLES = new Set(['owner', 'admin', 'editor']); const ADMIN_ROLES = new Set(['owner', 'admin']); // Fields used for product scope filtering const PRODUCT_SCOPE_FIELDS = { VocProduct: 'productId', VocReview: 'productId', VocDailyMetric: 'productId', VocProductRelation: 'ownProductId', VocProductKnowledge: 'productId', VocListingSourceSnapshot: 'productId', VocListingCurrentScore: 'productId', VocListingVersion: 'productId', VocCompetitorListingSnapshot: 'productId', VocCompetitorListingChange: 'productId', VocCompetitorOptimizationTask: 'ownProductId', }; // Fields used for read filtering by class const READ_FILTER_FIELDS = { VocProduct: ['platform', 'role'], VocReview: ['platform', 'productId'], VocProductRelation: ['platform', 'ownProductId', 'competitorProductId'], VocSyncJob: ['status', 'platform'], VocSyncJobEvent: ['jobId', 'eventType'], VocAnalysisRun: ['status', 'analysisType', 'targetKind'], VocInsightDecision: ['sourceAnalysisId', 'sourceInsightId', 'isCurrent'], VocActionItem: ['status', 'actionType', 'productKey'], VocAlert: ['status', 'alertType', 'productKey'], VocProductKnowledge: ['productId', 'productKey', 'status'], VocListingSourceSnapshot: ['platform', 'productId', 'isCurrent', 'scoreStatus', 'aiScoreStatus', 'coverageStatus'], VocListingScoreJob: ['status', 'platform'], VocListingVersion: ['productId', 'status'], VocCompetitorListingSnapshot: ['platform', 'productId'], VocCompetitorListingChange: ['platform', 'productId'], VocCompetitorOptimizationTask: ['status', 'ownProductId'], }; // Allowed paths for upstream providers const UPSTREAM_PATHS = { amazon: [ /^\/test$/, /^\/orders(?:\/[A-Za-z0-9._~-]+)?(?:\/items)?$/, /^\/sales\/orderMetrics$/, /^\/catalog\/items(?:\/[A-Za-z0-9._~-]+)?$/, /^\/listings\/items\/[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)?$/, /^\/customerFeedback\/items\/[A-Za-z0-9._~-]+\/reviews\/(?:topics|trends|browseNode)$/, /^\/sellers\/marketplaceParticipations$/, /^\/returns$/, ], sorftime: [ /^\/api\/(?:CategoryTree|CategoryRequest|CategoryProducts|ProductQuery|ProductRequest|AsinSalesVolume|SimilarProductRealtimeRequest|SimilarProductRealtimeRequestStatusQuery|SimilarProductRealtimeRequestCollection|ProductReviewsQuery|MonitorQuery|KeywordQuery|ASINRequestKeyword|KeywordProductRanking|KeywordSearchResultTrend|ProductVariationHistory)$/, ], tikhub: [ /^\/v1\/(?:tiktok|instagram)\/[A-Za-z0-9._~/-]+$/, ], domestic: [ /^\/jd\/(?:get-item-detail|get-item-comments|search-item-list)\/v1$/, ], }; // Allowed operations for upstream providers const UPSTREAM_OPERATIONS = { amazon: new Set(['get', 'post']), sorftime: new Set(['get', 'post', 'forward']), tikhub: new Set(['get', 'post', 'forward']), domestic: new Set(['gateway.get']), }; // Fields excluded from body data for security const EXCLUDED_BODY_FIELDS = [ 'action', 'workspaceId', 'platform', 'payload', 'idempotencyKey', 'userId', 'jobId', 'productId', 'decisionId', 'analysisId', 'actionId', 'alertId', 'taskId', 'runId', 'versionId', ]; // Fields excluded from storage data const EXCLUDED_STORAGE_FIELDS = ['action', 'workspaceId', 'userId']; // Cloud function mapping - action prefix to function name const ACTION_TO_FUNCTION = { // Context & Workspace 'context': 'vContext', 'workspace': 'vContext', // Domestic VOC 'domestic': 'vDomesticVoc', 'data-source': 'vDomesticVoc', 'import': 'vDomesticVoc', 'audit': 'vDomesticVoc', // Sync 'sync': 'vSync', // Competitor 'competitor': 'vCompetitor', // Listing 'listing.product': 'vListing', 'listing.overview': 'vListing', 'listing.products': 'vListing', // Listing Job 'listing.score-job': 'vListingJob', 'listing.version': 'vListingJob', // Analysis 'analysis': 'vAnalysis', 'insight-decision': 'vAnalysis', // Actions 'action': 'vActions', 'alert': 'vActions', // Knowledge 'knowledge': 'vKnowledge', // AI 'ai': 'vAI', // Upstream 'upstream': 'vUpstream', }; /* // module.exports = { // ACTIONS, // CLASS_BY_READ_ACTION, // WRITE_ROLES, // ADMIN_ROLES, // PRODUCT_SCOPE_FIELDS, // READ_FILTER_FIELDS, // UPSTREAM_PATHS, // UPSTREAM_OPERATIONS, // EXCLUDED_BODY_FIELDS, // EXCLUDED_STORAGE_FIELDS, // ACTION_TO_FUNCTION, // }; */