.
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# Изменения в API: Интеграция v2 анализа
|
||||
|
||||
## Обзор изменений
|
||||
|
||||
Добавлена возможность опционального создания и сохранения v2 анализа вместе с обычным анализом. Все v2 анализы сохраняются в MongoDB и доступны через новые эндпойнты.
|
||||
|
||||
---
|
||||
|
||||
## 1. POST `/api/marketing/analysis/start` - Обновлен
|
||||
|
||||
### Новый query параметр:
|
||||
|
||||
- **`generateV2`** (boolean, опционально, по умолчанию `false`)
|
||||
- Если `true`, вместе с обычным анализом создается и сохраняется v2 анализ
|
||||
- Оба анализа автоматически связываются между собой
|
||||
|
||||
### Изменения в ответе:
|
||||
|
||||
**Если `generateV2=false` (по умолчанию):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Анализ запущен успешно",
|
||||
"data": {
|
||||
"analysisId": "string",
|
||||
"status": "processing",
|
||||
"estimatedCompletionTime": "2024-01-01T12:00:00",
|
||||
"message": "Комплексный анализ (...) запущен успешно..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Если `generateV2=true`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Анализ запущен успешно",
|
||||
"data": {
|
||||
"analysisId": "string",
|
||||
"status": "processing",
|
||||
"estimatedCompletionTime": "2024-01-01T12:00:00",
|
||||
"message": "Комплексный анализ (...) запущен успешно...",
|
||||
"v2AnalysisId": "string" // ← НОВОЕ ПОЛЕ
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Пример использования:
|
||||
|
||||
```javascript
|
||||
// Создание обычного анализа
|
||||
POST /api/marketing/analysis/start
|
||||
Body: { ... }
|
||||
|
||||
// Создание обычного анализа + v2 анализа
|
||||
POST /api/marketing/analysis/start?generateV2=true
|
||||
Body: { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. GET `/api/marketing/analysis/my` - Обновлен
|
||||
|
||||
### Новое поле в ответе:
|
||||
|
||||
Каждый элемент в списке теперь содержит опциональное поле `v2AnalysisId`:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"analysisId": "string",
|
||||
"businessNiche": "string",
|
||||
"product": "string",
|
||||
// ... другие поля ...
|
||||
"v2AnalysisId": "string" // ← НОВОЕ ПОЛЕ (может быть null)
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Примечание:** Поле `v2AnalysisId` будет присутствовать только если для данного анализа был создан связанный v2 анализ.
|
||||
|
||||
---
|
||||
|
||||
## 3. GET `/api/marketing/analysis/v2/{id}` - Новый эндпойнт
|
||||
|
||||
### Описание:
|
||||
|
||||
Получение сохраненного v2 анализа по ID.
|
||||
|
||||
### Параметры:
|
||||
|
||||
- **Path:** `id` (string) - ID v2 анализа
|
||||
- **Header:** `Authorization` (JWT токен)
|
||||
|
||||
### Ответ:
|
||||
|
||||
**Успешный ответ (200):**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"reportTitle": "string",
|
||||
"sections": {
|
||||
"marketOverview": { ... },
|
||||
"targetAudience": { ... },
|
||||
"competitiveEnvironment": { ... },
|
||||
// ... другие секции ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Ошибки:**
|
||||
|
||||
- `401` - Не авторизован
|
||||
- `404` - Анализ не найден
|
||||
- `403` - Нет доступа к этому анализу
|
||||
|
||||
### Пример использования:
|
||||
|
||||
```javascript
|
||||
GET /api/marketing/analysis/v2/507f1f77bcf86cd799439011
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. POST `/api/marketing/analysis/start/v2` - Без изменений
|
||||
|
||||
Эндпойнт работает как прежде - создает только v2 анализ без связи с обычным анализом.
|
||||
|
||||
---
|
||||
|
||||
## Рекомендации для фронтенда
|
||||
|
||||
1. **При создании анализа:**
|
||||
|
||||
- Используйте `generateV2=true` если нужен v2 анализ сразу
|
||||
- Сохраняйте `v2AnalysisId` из ответа для последующего доступа
|
||||
|
||||
2. **При отображении списка анализов:**
|
||||
|
||||
- Проверяйте наличие поля `v2AnalysisId`
|
||||
- Если поле присутствует, можно показать кнопку/ссылку для просмотра v2 анализа
|
||||
|
||||
3. **При получении v2 анализа:**
|
||||
- Используйте `GET /api/marketing/analysis/v2/{id}` для получения полных данных
|
||||
- Обрабатывайте случаи, когда v2 анализ может быть не найден (404)
|
||||
|
||||
---
|
||||
|
||||
## Обратная совместимость
|
||||
|
||||
✅ Все изменения обратно совместимы:
|
||||
|
||||
- Существующие запросы без `generateV2` работают как прежде
|
||||
- Поле `v2AnalysisId` опционально и не ломает существующий код
|
||||
- Новые эндпойнты не влияют на старую функциональность
|
||||
@@ -2,6 +2,7 @@ package kz.konturai.parser.controller;
|
||||
|
||||
import kz.konturai.parser.dto.*;
|
||||
import kz.konturai.parser.model.MarketingAnalysis;
|
||||
import kz.konturai.parser.model.MarketingAnalysisV2Document;
|
||||
import kz.konturai.parser.model.MarketingStrategy;
|
||||
import kz.konturai.parser.model.PostingTask;
|
||||
import kz.konturai.parser.service.JwtService;
|
||||
@@ -78,6 +79,7 @@ public class MarketingController {
|
||||
@PostMapping("/start")
|
||||
public ResponseEntity<?> startAnalysis(
|
||||
@RequestHeader(value = "Authorization", required = false) String authHeader,
|
||||
@RequestParam(value = "generateV2", defaultValue = "false") boolean generateV2,
|
||||
@Valid @RequestBody MarketingAnalysisRequest request) {
|
||||
|
||||
String userId = extractUserIdFromHeader(authHeader);
|
||||
@@ -89,6 +91,24 @@ public class MarketingController {
|
||||
List<MarketingAnalysis> analyses = marketingAnalysisService.startAnalysis(request, userId);
|
||||
MarketingAnalysis analysis = analyses.get(0);
|
||||
|
||||
// Опционально создаем v2 анализ и связываем его
|
||||
String v2AnalysisId = null;
|
||||
if (generateV2) {
|
||||
try {
|
||||
v2AnalysisId = marketingAnalysisService.generateAndSaveAnalysisV2(request, userId);
|
||||
// Связываем обычный анализ с v2
|
||||
analysis.setV2AnalysisId(v2AnalysisId);
|
||||
marketingAnalysisService.updateAnalysis(analysis);
|
||||
// Связываем v2 анализ с обычным
|
||||
marketingAnalysisService.linkV2AnalysisToAnalysis(v2AnalysisId, analysis.getId());
|
||||
logger.info("Created and linked v2 analysis {} to analysis {}", v2AnalysisId,
|
||||
analysis.getId());
|
||||
} catch (Exception e) {
|
||||
logger.error("Error creating v2 analysis: {}", e.getMessage(), e);
|
||||
// Продолжаем выполнение даже если v2 анализ не создался
|
||||
}
|
||||
}
|
||||
|
||||
// Start async processing
|
||||
marketingAnalysisService.processAnalysis(analysis.getId(), request);
|
||||
|
||||
@@ -107,6 +127,18 @@ public class MarketingController {
|
||||
estimatedCompletion,
|
||||
"Комплексный анализ (" + analysisTypesStr
|
||||
+ ") запущен успешно. Результаты будут готовы в течение 5-10 минут.");
|
||||
|
||||
// Добавляем v2 id в ответ, если он был создан
|
||||
if (v2AnalysisId != null) {
|
||||
Map<String, Object> responseData = new HashMap<>();
|
||||
responseData.put("analysisId", response.getAnalysisId());
|
||||
responseData.put("status", response.getStatus());
|
||||
responseData.put("estimatedCompletionTime", response.getEstimatedCompletionTime());
|
||||
responseData.put("message", response.getMessage());
|
||||
responseData.put("v2AnalysisId", v2AnalysisId);
|
||||
return ResponseEntity.ok(ApiResponse.success("Анализ запущен успешно", responseData));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success("Анализ запущен успешно", response));
|
||||
}
|
||||
|
||||
@@ -120,8 +152,53 @@ public class MarketingController {
|
||||
return unauthorizedResponse();
|
||||
}
|
||||
|
||||
MarketingAnalysisResponseV2 response = marketingAnalysisService.generateAnalysisV2(request);
|
||||
return ResponseEntity.ok(response);
|
||||
try {
|
||||
String analysisId = marketingAnalysisService.generateAndSaveAnalysisV2(request, userId);
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("id", analysisId);
|
||||
response.put("message", "Анализ успешно создан и сохранен");
|
||||
return ResponseEntity.ok(ApiResponse.success("Анализ создан", response));
|
||||
} catch (Exception e) {
|
||||
logger.error("Error creating analysis v2: {}", e.getMessage(), e);
|
||||
ErrorResponse error = new ErrorResponse(
|
||||
"INTERNAL_SERVER_ERROR",
|
||||
"Произошла ошибка при создании анализа");
|
||||
return ResponseEntity.status(500)
|
||||
.body(ApiResponse.error("Внутренняя ошибка сервера", error));
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/v2/{id}")
|
||||
public ResponseEntity<?> getAnalysisV2(
|
||||
@RequestHeader(value = "Authorization", required = false) String authHeader,
|
||||
@PathVariable String id) {
|
||||
|
||||
String userId = extractUserIdFromHeader(authHeader);
|
||||
if (userId == null) {
|
||||
return unauthorizedResponse();
|
||||
}
|
||||
|
||||
Optional<MarketingAnalysisV2Document> optAnalysis = marketingAnalysisService
|
||||
.getAnalysisV2ById(id);
|
||||
|
||||
if (optAnalysis.isEmpty()) {
|
||||
ErrorResponse error = new ErrorResponse(
|
||||
"NOT_FOUND",
|
||||
"Анализ с указанным ID не найден");
|
||||
return ResponseEntity.status(404)
|
||||
.body(ApiResponse.error("Анализ не найден", error));
|
||||
}
|
||||
|
||||
MarketingAnalysisV2Document analysis = optAnalysis.get();
|
||||
if (!userId.equals(analysis.getUserId())) {
|
||||
ErrorResponse error = new ErrorResponse(
|
||||
"FORBIDDEN",
|
||||
"У вас нет доступа к этому анализу");
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN)
|
||||
.body(ApiResponse.error("Доступ запрещен", error));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(ApiResponse.success(analysis.getAnalysisData()));
|
||||
}
|
||||
|
||||
@GetMapping("/{analysisId}")
|
||||
@@ -561,6 +638,22 @@ public class MarketingController {
|
||||
response.setCreatedAt(analysis.getCreatedAt());
|
||||
response.setCompletedAt(analysis.getCompletedAt());
|
||||
response.setStatusHistory(analysis.getStatusHistory());
|
||||
|
||||
// Ищем связанный v2 анализ
|
||||
String v2AnalysisId = analysis.getV2AnalysisId();
|
||||
if (v2AnalysisId == null || v2AnalysisId.isEmpty()) {
|
||||
// Если v2AnalysisId не установлен, пытаемся найти по analysisId
|
||||
Optional<MarketingAnalysisV2Document> optV2 = marketingAnalysisService
|
||||
.getV2AnalysisByAnalysisId(analysis.getId());
|
||||
if (optV2.isPresent()) {
|
||||
v2AnalysisId = optV2.get().getId();
|
||||
// Обновляем анализ для сохранения связи
|
||||
analysis.setV2AnalysisId(v2AnalysisId);
|
||||
marketingAnalysisService.updateAnalysis(analysis);
|
||||
}
|
||||
}
|
||||
response.setV2AnalysisId(v2AnalysisId);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public class AnalysisHistoryResponse {
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime completedAt;
|
||||
private List<StatusHistoryEntry> statusHistory;
|
||||
private String v2AnalysisId; // ID связанного v2 анализа
|
||||
|
||||
public AnalysisHistoryResponse() {
|
||||
}
|
||||
@@ -142,4 +143,12 @@ public class AnalysisHistoryResponse {
|
||||
public void setAnalysisType(String analysisType) {
|
||||
this.analysisType = analysisType;
|
||||
}
|
||||
|
||||
public String getV2AnalysisId() {
|
||||
return v2AnalysisId;
|
||||
}
|
||||
|
||||
public void setV2AnalysisId(String v2AnalysisId) {
|
||||
this.v2AnalysisId = v2AnalysisId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ public class MarketingAnalysis {
|
||||
@Field("status_history")
|
||||
private List<StatusHistoryEntry> statusHistory;
|
||||
|
||||
@Field("v2_analysis_id")
|
||||
private String v2AnalysisId; // ID связанного v2 анализа
|
||||
|
||||
public MarketingAnalysis() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.status = "queued";
|
||||
@@ -231,4 +234,12 @@ public class MarketingAnalysis {
|
||||
public void setAnalysisType(List<String> analysisType) {
|
||||
this.analysisType = analysisType;
|
||||
}
|
||||
|
||||
public String getV2AnalysisId() {
|
||||
return v2AnalysisId;
|
||||
}
|
||||
|
||||
public void setV2AnalysisId(String v2AnalysisId) {
|
||||
this.v2AnalysisId = v2AnalysisId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package kz.konturai.parser.model;
|
||||
|
||||
import kz.konturai.parser.dto.MarketingAnalysisResponseV2;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Document(collection = "marketing_analysis_v2")
|
||||
public class MarketingAnalysisV2Document {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Field("user_id")
|
||||
private String userId;
|
||||
|
||||
@Field("business_niche")
|
||||
private String businessNiche;
|
||||
|
||||
@Field("product")
|
||||
private String product;
|
||||
|
||||
@Field("target_audience")
|
||||
private Map<String, Object> targetAudience;
|
||||
|
||||
@Field("region")
|
||||
private List<String> region;
|
||||
|
||||
@Field("goal")
|
||||
private String goal;
|
||||
|
||||
@Field("detail_level")
|
||||
private String detailLevel;
|
||||
|
||||
@Field("strong_side")
|
||||
private String strongSide;
|
||||
|
||||
@Field("weak_side")
|
||||
private String weakSide;
|
||||
|
||||
@Field("analysis_type")
|
||||
private List<String> analysisType;
|
||||
|
||||
@Field("analysis_data")
|
||||
private MarketingAnalysisResponseV2 analysisData;
|
||||
|
||||
@Field("created_at")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Field("updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@Field("analysis_id")
|
||||
private String analysisId; // ID связанного обычного анализа
|
||||
|
||||
public MarketingAnalysisV2Document() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getBusinessNiche() {
|
||||
return businessNiche;
|
||||
}
|
||||
|
||||
public void setBusinessNiche(String businessNiche) {
|
||||
this.businessNiche = businessNiche;
|
||||
}
|
||||
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public void setProduct(String product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public Map<String, Object> getTargetAudience() {
|
||||
return targetAudience;
|
||||
}
|
||||
|
||||
public void setTargetAudience(Map<String, Object> targetAudience) {
|
||||
this.targetAudience = targetAudience;
|
||||
}
|
||||
|
||||
public List<String> getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(List<String> region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public String getGoal() {
|
||||
return goal;
|
||||
}
|
||||
|
||||
public void setGoal(String goal) {
|
||||
this.goal = goal;
|
||||
}
|
||||
|
||||
public String getDetailLevel() {
|
||||
return detailLevel;
|
||||
}
|
||||
|
||||
public void setDetailLevel(String detailLevel) {
|
||||
this.detailLevel = detailLevel;
|
||||
}
|
||||
|
||||
public String getStrongSide() {
|
||||
return strongSide;
|
||||
}
|
||||
|
||||
public void setStrongSide(String strongSide) {
|
||||
this.strongSide = strongSide;
|
||||
}
|
||||
|
||||
public String getWeakSide() {
|
||||
return weakSide;
|
||||
}
|
||||
|
||||
public void setWeakSide(String weakSide) {
|
||||
this.weakSide = weakSide;
|
||||
}
|
||||
|
||||
public List<String> getAnalysisType() {
|
||||
return analysisType;
|
||||
}
|
||||
|
||||
public void setAnalysisType(List<String> analysisType) {
|
||||
this.analysisType = analysisType;
|
||||
}
|
||||
|
||||
public MarketingAnalysisResponseV2 getAnalysisData() {
|
||||
return analysisData;
|
||||
}
|
||||
|
||||
public void setAnalysisData(MarketingAnalysisResponseV2 analysisData) {
|
||||
this.analysisData = analysisData;
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(LocalDateTime createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public String getAnalysisId() {
|
||||
return analysisId;
|
||||
}
|
||||
|
||||
public void setAnalysisId(String analysisId) {
|
||||
this.analysisId = analysisId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package kz.konturai.parser.repository;
|
||||
|
||||
import kz.konturai.parser.model.MarketingAnalysisV2Document;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface MarketingAnalysisV2Repository extends MongoRepository<MarketingAnalysisV2Document, String> {
|
||||
Optional<MarketingAnalysisV2Document> findById(String id);
|
||||
|
||||
List<MarketingAnalysisV2Document> findByUserIdOrderByCreatedAtDesc(String userId);
|
||||
|
||||
Optional<MarketingAnalysisV2Document> findByIdAndUserId(String id, String userId);
|
||||
|
||||
Optional<MarketingAnalysisV2Document> findByAnalysisId(String analysisId);
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import kz.konturai.parser.dto.StatusHistoryEntry;
|
||||
import kz.konturai.parser.model.AnalysisType;
|
||||
import kz.konturai.parser.model.DetailLevel;
|
||||
import kz.konturai.parser.model.MarketingAnalysis;
|
||||
import kz.konturai.parser.model.MarketingAnalysisV2Document;
|
||||
import kz.konturai.parser.repository.MarketingAnalysisRepository;
|
||||
import kz.konturai.parser.repository.MarketingAnalysisV2Repository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -392,6 +394,7 @@ public class MarketingAnalysisService {
|
||||
private static final long RETRY_DELAY_MS = 1000;
|
||||
|
||||
private final MarketingAnalysisRepository repository;
|
||||
private final MarketingAnalysisV2Repository v2Repository;
|
||||
private final OpenAIAnalyticsService openAIAnalyticsService;
|
||||
private final MinIOService minIOService;
|
||||
private final ResearchPdfService researchPdfService;
|
||||
@@ -411,11 +414,13 @@ public class MarketingAnalysisService {
|
||||
|
||||
public MarketingAnalysisService(
|
||||
MarketingAnalysisRepository repository,
|
||||
MarketingAnalysisV2Repository v2Repository,
|
||||
OpenAIAnalyticsService openAIAnalyticsService,
|
||||
MinIOService minIOService,
|
||||
ResearchPdfService researchPdfService,
|
||||
SerperSearchService serperSearchService) {
|
||||
this.repository = repository;
|
||||
this.v2Repository = v2Repository;
|
||||
this.openAIAnalyticsService = openAIAnalyticsService;
|
||||
this.minIOService = minIOService;
|
||||
this.researchPdfService = researchPdfService;
|
||||
@@ -703,6 +708,88 @@ public class MarketingAnalysisService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерирует анализ v2 и сохраняет его в MongoDB
|
||||
*
|
||||
* @param request Запрос на анализ
|
||||
* @param userId ID пользователя
|
||||
* @return ID сохраненного анализа
|
||||
*/
|
||||
public String generateAndSaveAnalysisV2(MarketingAnalysisRequest request, String userId) {
|
||||
try {
|
||||
// Генерируем анализ
|
||||
MarketingAnalysisResponseV2 analysisData = generateAnalysisV2(request);
|
||||
|
||||
// Создаем документ для сохранения
|
||||
MarketingAnalysisV2Document document = new MarketingAnalysisV2Document();
|
||||
document.setUserId(userId);
|
||||
document.setBusinessNiche(request.getBusinessNiche());
|
||||
document.setProduct(request.getProduct());
|
||||
document.setTargetAudience(request.getTargetAudience());
|
||||
document.setRegion(request.getRegion());
|
||||
document.setGoal(request.getGoal());
|
||||
document.setDetailLevel(request.getDetailLevel());
|
||||
document.setStrongSide(request.getStrongSide());
|
||||
document.setWeakSide(request.getWeakSide());
|
||||
document.setAnalysisType(request.getAnalysisType());
|
||||
document.setAnalysisData(analysisData);
|
||||
|
||||
// Сохраняем в MongoDB
|
||||
MarketingAnalysisV2Document saved = v2Repository.save(document);
|
||||
logger.info("Saved marketing analysis v2 with id: {}", saved.getId());
|
||||
return saved.getId();
|
||||
} catch (Exception e) {
|
||||
logger.error("generateAndSaveAnalysisV2: Failed to generate and save analysis: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Не удалось сохранить marketing analysis v2", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает сохраненный анализ v2 по ID
|
||||
*
|
||||
* @param id ID анализа
|
||||
* @return Документ анализа или null, если не найден
|
||||
*/
|
||||
public Optional<MarketingAnalysisV2Document> getAnalysisV2ById(String id) {
|
||||
return v2Repository.findById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет анализ в базе данных
|
||||
*
|
||||
* @param analysis Анализ для обновления
|
||||
* @return Обновленный анализ
|
||||
*/
|
||||
public MarketingAnalysis updateAnalysis(MarketingAnalysis analysis) {
|
||||
return repository.save(analysis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Связывает v2 анализ с обычным анализом
|
||||
*
|
||||
* @param v2AnalysisId ID v2 анализа
|
||||
* @param analysisId ID обычного анализа
|
||||
*/
|
||||
public void linkV2AnalysisToAnalysis(String v2AnalysisId, String analysisId) {
|
||||
Optional<MarketingAnalysisV2Document> optV2 = v2Repository.findById(v2AnalysisId);
|
||||
if (optV2.isPresent()) {
|
||||
MarketingAnalysisV2Document v2Doc = optV2.get();
|
||||
v2Doc.setAnalysisId(analysisId);
|
||||
v2Repository.save(v2Doc);
|
||||
logger.info("Linked v2 analysis {} to analysis {}", v2AnalysisId, analysisId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает v2 анализ по ID обычного анализа
|
||||
*
|
||||
* @param analysisId ID обычного анализа
|
||||
* @return Документ v2 анализа или null, если не найден
|
||||
*/
|
||||
public Optional<MarketingAnalysisV2Document> getV2AnalysisByAnalysisId(String analysisId) {
|
||||
return v2Repository.findByAnalysisId(analysisId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example payload used ONLY for prompting the AI with the expected JSON
|
||||
* schema/shape.
|
||||
|
||||
Reference in New Issue
Block a user