feat(affiliate-marketing): add unified TikTok + Shopee system planner and API#273
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a unified TikTok and Shopee campaign analysis system, including a new API endpoint, Zod validation schemas, and the core logic for calculating performance metrics and budget splits. The review feedback identifies several areas for improvement: the TikTokShopeeSystemPlan type should be exported for external use, the budget calculation contains unreachable logic and magic numbers that should be refactored, and the nextActions list should be made dynamic based on performance benchmarks rather than remaining static.
| return `สำหรับ ${input.audience}: ${input.currentCaption} | ปรับตามข้อเสนอ: ${directives}. CTA: กดดูรายละเอียดและเริ่มได้ทันที`; | ||
| } | ||
|
|
||
| type TikTokShopeeSystemPlan = { |
There was a problem hiding this comment.
The TikTokShopeeSystemPlan type is used as the return type for the exported buildTikTokShopeeSystem function. It should be exported so that consumers of this module can properly type the results in their own codebases.
| type TikTokShopeeSystemPlan = { | |
| export type TikTokShopeeSystemPlan = { |
| const tiktokCtr = campaign.tiktokViews === 0 ? 0 : campaign.tiktokClicks / campaign.tiktokViews; | ||
| const shopeeCvr = campaign.shopeeClicks === 0 ? 0 : campaign.shopeeOrders / campaign.shopeeClicks; | ||
| const blendedScore = Number((tiktokCtr * 0.5 + shopeeCvr * 0.5).toFixed(4)); | ||
| const tiktokBudget = Math.max(25, Math.min(80, Math.round((0.65 - shopeeCvr) * 100))); |
There was a problem hiding this comment.
This budget calculation contains several magic numbers and a potential logic inconsistency. The upper bound of 80 in Math.min(80, ...) is unreachable because the expression (0.65 - shopeeCvr) * 100 maxes out at 65 (when shopeeCvr is 0). Consider extracting these values into named constants and verifying the intended range for the TikTok budget split.
| const nextActions = [ | ||
| `TikTok hook refresh for ${campaign.productId}`, | ||
| `Shopee PDP optimization for ${campaign.productId}`, | ||
| `Retarget users who clicked TikTok but not Shopee checkout`, | ||
| ]; |
There was a problem hiding this comment.
The nextActions list is currently static for all products. To provide a more useful "system plan" as described in the PR, these recommendations should be dynamic based on the calculated metrics (e.g., only suggesting a hook refresh if the tiktokCtr is below a specific benchmark).
const nextActions = [];
if (tiktokCtr < 0.03) nextActions.push('TikTok hook refresh for ' + campaign.productId);
if (shopeeCvr < 0.05) nextActions.push('Shopee PDP optimization for ' + campaign.productId);
nextActions.push('Retarget users who clicked TikTok but not Shopee checkout');
Motivation
Description
tiktokShopeeSystemRequestSchemaand related types inapps/affiliate-marketing/src/schemas.tsto validate campaign inputs.buildTikTokShopeeSysteminapps/affiliate-marketing/src/engine.tswhich computes TikTok CTR, Shopee CVR, a blended score, recommended TikTok/Shopee budget split, and a deterministic next-action playbook per product.POST /v1/system/tiktok-shopeeinapps/affiliate-marketing/src/index.tswhich validates payloads and returns the generated system plan.apps/affiliate-marketing/src/engine.test.tsto assert ordering, budget split ranges and output structure for the planner.Testing
npm test --workspace apps/affiliate-marketingwhich completed successfully and reported all tests passing (1 file, 4 tests).Codex Task