AI translate refactor
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user