overall summary respose
This commit is contained in:
@@ -319,6 +319,8 @@ func (t *Tender) ToResponseWithLanguage(language string) *TenderResponse {
|
|||||||
ProjectName: strings.TrimSpace(t.ProjectName),
|
ProjectName: strings.TrimSpace(t.ProjectName),
|
||||||
CreatedAt: t.CreatedAt,
|
CreatedAt: t.CreatedAt,
|
||||||
Language: usedLanguage,
|
Language: usedLanguage,
|
||||||
|
|
||||||
|
OverallSummary: strings.TrimSpace(t.AIOverallSummary),
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|||||||
+28
-10
@@ -123,20 +123,19 @@ func (s *tenderService) GetByID(ctx context.Context, id string) (*TenderResponse
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// enrichWithAISummary attempts to fetch the AI-generated overall summary from
|
// enrichWithAISummary loads overall_summary from MinIO (PROC_<contractFolderID>/<noticePublicationID>/tender.json)
|
||||||
// MinIO storage and attaches it to the response. Failures are logged but do not
|
// and attaches it to the response. The primary notice publication id is tried first, then related ids.
|
||||||
// cause the request to fail — the field will simply be omitted.
|
// A previously stored ai_overall_summary on the tender (already mapped in ToResponse) is kept when MinIO
|
||||||
//
|
// has no ready summary. On success the tender document is updated so list/search can return it without
|
||||||
// Because one tender record can span several TED notices (we merge by
|
// another MinIO round-trip.
|
||||||
// contract_folder_id), we try the latest publication id first and fall back to
|
|
||||||
// older RelatedNoticePublicationIDs if the AI pipeline only finished an
|
|
||||||
// earlier notice in the procedure.
|
|
||||||
func (s *tenderService) enrichWithAISummary(ctx context.Context, t *Tender, resp *TenderResponse) {
|
func (s *tenderService) enrichWithAISummary(ctx context.Context, t *Tender, resp *TenderResponse) {
|
||||||
if s.aiSummarizerStorage == nil || t == nil || t.ContractFolderID == "" {
|
if t == nil || resp == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.aiSummarizerStorage == nil || strings.TrimSpace(t.ContractFolderID) == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep tender detail response fast even if AI storage is slow/unreachable.
|
|
||||||
enrichCtx, cancel := context.WithTimeout(ctx, aiSummaryEnrichmentTimeout)
|
enrichCtx, cancel := context.WithTimeout(ctx, aiSummaryEnrichmentTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -160,6 +159,25 @@ func (s *tenderService) enrichWithAISummary(ctx context.Context, t *Tender, resp
|
|||||||
"used_notice_id": usedNotice,
|
"used_notice_id": usedNotice,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.persistAIOverallSummary(enrichCtx, t, summary)
|
||||||
|
}
|
||||||
|
|
||||||
|
// persistAIOverallSummary stores the resolved summary on the tender for list/search responses.
|
||||||
|
func (s *tenderService) persistAIOverallSummary(ctx context.Context, t *Tender, summary string) {
|
||||||
|
summary = strings.TrimSpace(summary)
|
||||||
|
if summary == "" || summary == strings.TrimSpace(t.AIOverallSummary) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.AIOverallSummary = summary
|
||||||
|
t.UpdatedAt = time.Now().Unix()
|
||||||
|
if err := s.repository.Update(ctx, t); err != nil {
|
||||||
|
s.logger.Warn("Failed to persist AI overall summary on tender", map[string]interface{}{
|
||||||
|
"tender_id": t.ID.Hex(),
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookupSummaryForTender returns the overall_summary for a tender by trying its
|
// lookupSummaryForTender returns the overall_summary for a tender by trying its
|
||||||
|
|||||||
Reference in New Issue
Block a user