AI translate refactor

This commit is contained in:
Mazyar
2026-05-16 12:56:10 +03:30
parent ca490f3acf
commit 6701428b09
10 changed files with 510 additions and 166 deletions
+55 -30
View File
@@ -295,9 +295,46 @@ func (s *StorageClient) GetSummaryFromStorage(ctx context.Context, contractFolde
return s.getSummaryFromObjectKey(ctx, prefix+"tender.json", contractFolderID, noticePublicationID)
}
// GetTranslationFromStorage reads tender.json and returns the translation for a language
// when translation_status.done includes that language.
func (s *StorageClient) GetTranslationFromStorage(ctx context.Context, contractFolderID, noticePublicationID, language string) (StoredTranslation, error) {
if strings.TrimSpace(contractFolderID) == "" {
return StoredTranslation{}, fmt.Errorf("ai_summarizer: contractFolderID is required")
}
if strings.TrimSpace(noticePublicationID) == "" {
return StoredTranslation{}, fmt.Errorf("ai_summarizer: noticePublicationID is required")
}
if strings.TrimSpace(language) == "" {
return StoredTranslation{}, fmt.Errorf("ai_summarizer: language is required")
}
prefix, err := s.resolveNoticeStoragePrefix(ctx, contractFolderID, noticePublicationID)
if err != nil {
return StoredTranslation{}, err
}
return s.getTranslationFromObjectKey(ctx, prefix+"tender.json", language)
}
// getTranslationFromObjectKey reads tender.json at objectKey and returns translation for language.
func (s *StorageClient) getTranslationFromObjectKey(ctx context.Context, objectKey, language string) (StoredTranslation, error) {
tenderJSON, err := s.readTenderJSONAtKey(ctx, objectKey)
if err != nil {
return StoredTranslation{}, err
}
if !languageInDone(tenderJSON.translationsDone(), language) {
return StoredTranslation{}, ErrTranslationNotReady
}
entry, ok := tenderJSON.translationForLanguage(language)
if !ok {
return StoredTranslation{}, ErrNoTranslation
}
return entry, nil
}
// getSummaryFromObjectKey reads tender.json at objectKey and returns overall_summary when ready.
// contractFolderID and noticePublicationID are used for logging only (may be empty when unknown).
func (s *StorageClient) getSummaryFromObjectKey(ctx context.Context, objectKey, contractFolderID, noticePublicationID string) (string, error) {
func (s *StorageClient) readTenderJSONAtKey(ctx context.Context, objectKey string) (*TenderJSON, error) {
object, err := s.client.GetObject(ctx, s.config.MinioBucket, objectKey, minio.GetObjectOptions{})
if err != nil {
if isMinioNotFound(err) {
@@ -305,13 +342,13 @@ func (s *StorageClient) getSummaryFromObjectKey(ctx context.Context, objectKey,
"bucket": s.config.MinioBucket,
"object_key": objectKey,
})
return "", ErrObjectNotFound
return nil, ErrObjectNotFound
}
var minioErr minio.ErrorResponse
if errors.As(err, &minioErr) && minioErr.StatusCode == http.StatusForbidden {
return "", fmt.Errorf("ai_summarizer: access denied to bucket %s: %w", s.config.MinioBucket, err)
return nil, fmt.Errorf("ai_summarizer: access denied to bucket %s: %w", s.config.MinioBucket, err)
}
return "", fmt.Errorf("ai_summarizer: failed to get object: %w", err)
return nil, fmt.Errorf("ai_summarizer: failed to get object: %w", err)
}
defer object.Close()
@@ -322,14 +359,22 @@ func (s *StorageClient) getSummaryFromObjectKey(ctx context.Context, objectKey,
"bucket": s.config.MinioBucket,
"object_key": objectKey,
})
return "", ErrObjectNotFound
return nil, ErrObjectNotFound
}
return "", fmt.Errorf("ai_summarizer: failed to read tender.json: %w", err)
return nil, fmt.Errorf("ai_summarizer: failed to read tender.json: %w", err)
}
var tenderJSON TenderJSON
if err := json.Unmarshal(data, &tenderJSON); err != nil {
return "", fmt.Errorf("ai_summarizer: failed to parse tender.json: %w", err)
return nil, fmt.Errorf("ai_summarizer: failed to parse tender.json: %w", err)
}
return &tenderJSON, nil
}
func (s *StorageClient) getSummaryFromObjectKey(ctx context.Context, objectKey, contractFolderID, noticePublicationID string) (string, error) {
tenderJSON, err := s.readTenderJSONAtKey(ctx, objectKey)
if err != nil {
return "", err
}
done, overall := tenderJSON.resolved()
@@ -368,32 +413,12 @@ func (s *StorageClient) IsSummaryReady(ctx context.Context, contractFolderID, no
}
objectPath := prefix + "tender.json"
object, err := s.client.GetObject(ctx, s.config.MinioBucket, objectPath, minio.GetObjectOptions{})
tenderJSON, err := s.readTenderJSONAtKey(ctx, objectPath)
if err != nil {
if isMinioNotFound(err) {
if errors.Is(err, ErrObjectNotFound) {
return false, nil
}
return false, fmt.Errorf("ai_summarizer: failed to check summary readiness: %w", err)
}
data, readErr := io.ReadAll(object)
closeErr := object.Close()
if readErr != nil {
if isMinioNotFound(readErr) {
return false, nil
}
return false, fmt.Errorf("ai_summarizer: failed to read tender.json: %w", readErr)
}
if closeErr != nil {
s.logger.Warn("Failed to close tender.json object after readiness check", map[string]interface{}{
"object_key": objectPath,
"error": closeErr.Error(),
})
}
var tenderJSON TenderJSON
if err := json.Unmarshal(data, &tenderJSON); err != nil {
return false, fmt.Errorf("ai_summarizer: failed to parse tender.json: %w", err)
return false, err
}
done, _ := tenderJSON.resolved()