target fix

This commit is contained in:
arys
2026-04-03 00:31:46 +05:00
parent 891f9ce3db
commit 1cbca9ecfc
2 changed files with 65 additions and 21 deletions
@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.util.StringUtils;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -29,63 +30,88 @@ public class TargetingCampaignController {
private final ABTestingService abTestingService; private final ABTestingService abTestingService;
private final MarketingAnalysisV3Repository analysisRepository; private final MarketingAnalysisV3Repository analysisRepository;
private final SocialMediaCredentialsService credentialsService; private final SocialMediaCredentialsService credentialsService;
private final JwtService jwtService;
private String resolveUserId(String userIdHeader, String authHeader) {
if (StringUtils.hasText(userIdHeader)) {
return userIdHeader;
}
String userId = jwtService.extractUserIdFromHeader(authHeader);
if (userId == null) {
throw new IllegalArgumentException("Cannot resolve user identity: X-User-Id header or valid Authorization token required");
}
return userId;
}
@PostMapping("/campaigns") @PostMapping("/campaigns")
public ResponseEntity<TargetingCampaign> createCampaign( public ResponseEntity<TargetingCampaign> createCampaign(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestBody TargetingCampaignRequest request) { @RequestBody TargetingCampaignRequest request) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Create campaign requested by {}", userId); log.info("[Targeting] Create campaign requested by {}", userId);
return ResponseEntity.ok(campaignService.createCampaign(request, userId)); return ResponseEntity.ok(campaignService.createCampaign(request, userId));
} }
@GetMapping("/campaigns") @GetMapping("/campaigns")
public ResponseEntity<Page<TargetingCampaign>> getUserCampaigns( public ResponseEntity<Page<TargetingCampaign>> getUserCampaigns(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) { @RequestParam(defaultValue = "10") int size) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Get campaigns for {}", userId); log.info("[Targeting] Get campaigns for {}", userId);
return ResponseEntity.ok(campaignService.getUserCampaigns(userId, page, size)); return ResponseEntity.ok(campaignService.getUserCampaigns(userId, page, size));
} }
@GetMapping("/campaigns/{id}") @GetMapping("/campaigns/{id}")
public ResponseEntity<TargetingCampaign> getCampaign( public ResponseEntity<TargetingCampaign> getCampaign(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id) { @PathVariable String id) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Get campaign {} for {}", id, userId); log.info("[Targeting] Get campaign {} for {}", id, userId);
return ResponseEntity.ok(campaignService.getCampaignById(id, userId)); return ResponseEntity.ok(campaignService.getCampaignById(id, userId));
} }
@PostMapping("/campaigns/{id}/pause") @PostMapping("/campaigns/{id}/pause")
public ResponseEntity<TargetingCampaign> pauseCampaign( public ResponseEntity<TargetingCampaign> pauseCampaign(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id) { @PathVariable String id) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Pause campaign {}", id); log.info("[Targeting] Pause campaign {}", id);
return ResponseEntity.ok(campaignService.pauseCampaign(id, userId)); return ResponseEntity.ok(campaignService.pauseCampaign(id, userId));
} }
@PostMapping("/campaigns/{id}/resume") @PostMapping("/campaigns/{id}/resume")
public ResponseEntity<TargetingCampaign> resumeCampaign( public ResponseEntity<TargetingCampaign> resumeCampaign(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id) { @PathVariable String id) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Resume campaign {}", id); log.info("[Targeting] Resume campaign {}", id);
return ResponseEntity.ok(campaignService.resumeCampaign(id, userId)); return ResponseEntity.ok(campaignService.resumeCampaign(id, userId));
} }
@GetMapping("/campaigns/{id}/insights") @GetMapping("/campaigns/{id}/insights")
public ResponseEntity<TargetingPerformanceDto> getInsights( public ResponseEntity<TargetingPerformanceDto> getInsights(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id, @PathVariable String id,
@RequestParam(defaultValue = "last_7d") String datePreset) { @RequestParam(defaultValue = "last_7d") String datePreset) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Get insights for campaign {}", id); log.info("[Targeting] Get insights for campaign {}", id);
return ResponseEntity.ok(campaignService.getCampaignInsights(id, userId, datePreset)); return ResponseEntity.ok(campaignService.getCampaignInsights(id, userId, datePreset));
} }
@PostMapping("/campaigns/{id}/sync-insights") @PostMapping("/campaigns/{id}/sync-insights")
public ResponseEntity<Void> syncInsights( public ResponseEntity<Void> syncInsights(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id) { @PathVariable String id) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Force sync insights for campaign {}", id); log.info("[Targeting] Force sync insights for campaign {}", id);
// Authorize
campaignService.getCampaignById(id, userId); campaignService.getCampaignById(id, userId);
campaignService.syncInsights(id); campaignService.syncInsights(id);
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
@@ -93,8 +119,10 @@ public class TargetingCampaignController {
@GetMapping("/campaigns/{id}/ab-test/evaluate") @GetMapping("/campaigns/{id}/ab-test/evaluate")
public ResponseEntity<String> evaluateAbTest( public ResponseEntity<String> evaluateAbTest(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@PathVariable String id) { @PathVariable String id) {
String userId = resolveUserId(userIdHeader, authHeader);
log.info("[Targeting] Evaluate AB Test for {}", id); log.info("[Targeting] Evaluate AB Test for {}", id);
TargetingCampaign campaign = campaignService.getCampaignById(id, userId); TargetingCampaign campaign = campaignService.getCampaignById(id, userId);
return ResponseEntity.ok(abTestingService.evaluateABTest(campaign)); return ResponseEntity.ok(abTestingService.evaluateABTest(campaign));
@@ -104,7 +132,8 @@ public class TargetingCampaignController {
@PostMapping("/audience/segment") @PostMapping("/audience/segment")
public ResponseEntity<List<AudienceSegmentDto>> segmentAudience( public ResponseEntity<List<AudienceSegmentDto>> segmentAudience(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestBody Map<String, String> body) { @RequestBody Map<String, String> body) {
String analysisId = body.get("analysisId"); String analysisId = body.get("analysisId");
log.info("[Targeting] Segment audience for analysis {}", analysisId); log.info("[Targeting] Segment audience for analysis {}", analysisId);
@@ -114,7 +143,8 @@ public class TargetingCampaignController {
@PostMapping("/audience/estimate") @PostMapping("/audience/estimate")
public ResponseEntity<Map<String, Long>> estimateAudience( public ResponseEntity<Map<String, Long>> estimateAudience(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestParam String platform, @RequestParam String platform,
@RequestBody TargetingAudienceProfile profile) { @RequestBody TargetingAudienceProfile profile) {
log.info("[Targeting] Estimate audience for platform {}", platform); log.info("[Targeting] Estimate audience for platform {}", platform);
@@ -125,8 +155,10 @@ public class TargetingCampaignController {
@PostMapping("/budget/optimize") @PostMapping("/budget/optimize")
public ResponseEntity<BudgetOptimizationDto> optimizeBudget( public ResponseEntity<BudgetOptimizationDto> optimizeBudget(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestBody Map<String, String> body) { @RequestBody Map<String, String> body) {
String userId = resolveUserId(userIdHeader, authHeader);
String campaignId = body.get("campaignId"); String campaignId = body.get("campaignId");
log.info("[Targeting] Optimize budget for campaign {}", campaignId); log.info("[Targeting] Optimize budget for campaign {}", campaignId);
TargetingCampaign campaign = campaignService.getCampaignById(campaignId, userId); TargetingCampaign campaign = campaignService.getCampaignById(campaignId, userId);
@@ -138,14 +170,16 @@ public class TargetingCampaignController {
@PostMapping("/account/select") @PostMapping("/account/select")
public ResponseEntity<Void> selectAdAccount( public ResponseEntity<Void> selectAdAccount(
@RequestHeader("X-User-Id") String userId, @RequestHeader(value = "X-User-Id", required = false) String userIdHeader,
@RequestHeader(value = "Authorization", required = false) String authHeader,
@RequestBody Map<String, String> body) { @RequestBody Map<String, String> body) {
String userId = resolveUserId(userIdHeader, authHeader);
String platform = body.get("platform"); String platform = body.get("platform");
String adAccountId = body.get("adAccountId"); String adAccountId = body.get("adAccountId");
log.info("[Targeting] Select ad account {} for platform {} by user {}", adAccountId, platform, userId); log.info("[Targeting] Select ad account {} for platform {} by user {}", adAccountId, platform, userId);
credentialsService.updateAdAccountId(userId, platform, adAccountId); credentialsService.updateAdAccountId(userId, platform, adAccountId);
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@@ -410,25 +410,35 @@ public class TargetingCampaignService {
} }
return rawPlatforms.stream() return rawPlatforms.stream()
.map(this::mapPlatform) .flatMap(p -> expandPlatform(p).stream())
.filter(Objects::nonNull) .filter(Objects::nonNull)
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private kz.konturai.parser.enums.TargetingPlatform mapPlatform(String platform) { private List<kz.konturai.parser.enums.TargetingPlatform> expandPlatform(String platform) {
if (platform == null || platform.isBlank()) { if (platform == null || platform.isBlank()) {
return null; return List.of();
} }
String normalized = platform.trim().toUpperCase(Locale.ROOT); String normalized = platform.trim().toUpperCase(Locale.ROOT);
// FB_IG / META expand to both Facebook + Instagram
if ("FB_IG".equals(normalized) || "FB+IG".equals(normalized)) {
return List.of(
kz.konturai.parser.enums.TargetingPlatform.FACEBOOK,
kz.konturai.parser.enums.TargetingPlatform.INSTAGRAM
);
}
if ("META".equals(normalized)) { if ("META".equals(normalized)) {
return kz.konturai.parser.enums.TargetingPlatform.FACEBOOK; return List.of(
kz.konturai.parser.enums.TargetingPlatform.FACEBOOK,
kz.konturai.parser.enums.TargetingPlatform.INSTAGRAM
);
} }
try { try {
return kz.konturai.parser.enums.TargetingPlatform.valueOf(normalized); return List.of(kz.konturai.parser.enums.TargetingPlatform.valueOf(normalized));
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
log.warn("Unknown targeting platform '{}', skipping", platform); log.warn("Unknown targeting platform '{}', skipping", platform);
return null; return List.of();
} }
} }