Refactor Tender Management to Introduce Notice Entity and Repository

- Replaced the tender repository with a new notice repository, encapsulating notice-related data access methods.
- Introduced the Notice entity to represent tender/contract notices, including relevant fields and methods for managing notice data.
- Updated the TED scraper to utilize the new notice repository for creating and managing notices, enhancing the integration with the tender management system.
- Implemented Ollama SDK initialization in the web bootstrap process, allowing for improved AI interactions.
- Enhanced the tender service to include Ollama SDK for additional functionality, ensuring a more robust service layer.
This commit is contained in:
n.nakhostin
2025-10-04 15:22:49 +03:30
parent 154610e2a0
commit cc3d6163ed
15 changed files with 1088 additions and 85 deletions
+52 -52
View File
@@ -10,7 +10,7 @@ import (
"path/filepath"
"strings"
"time"
"tm/internal/tender"
"tm/internal/notice"
"tm/pkg/logger"
"tm/pkg/mongo"
"tm/pkg/notification"
@@ -37,7 +37,7 @@ type TEDScraper struct {
httpClient *http.Client
xmlParser *TEDParser
mongoManager *mongo.ConnectionManager
tenderRepo tender.TenderRepository
tenderRepo notice.Repository
}
// NewTEDScraper creates a new TED scraper instance
@@ -45,7 +45,7 @@ func NewTEDScraper(
config *Config,
logger logger.Logger,
mongoManager *mongo.ConnectionManager,
tenderRepo tender.TenderRepository,
tenderRepo notice.Repository,
notify notification.SDK,
) *TEDScraper {
httpClient := &http.Client{
@@ -275,7 +275,7 @@ func (s *TEDScraper) tarGzFileProcessor(ctx context.Context, reader io.Reader, o
return result, nil
}
func (s *TEDScraper) findTenderByContractNoticeID(ctx context.Context, contractNoticeID string) (*tender.Tender, error) {
func (s *TEDScraper) findTenderByContractNoticeID(ctx context.Context, contractNoticeID string) (*notice.Notice, error) {
existingTender, err := s.tenderRepo.GetByContractNoticeID(ctx, contractNoticeID)
if err != nil {
if err.Error() == "document not found" {
@@ -308,60 +308,60 @@ func (s *TEDScraper) processXMLContent(ctx context.Context, content []byte, file
// Map to tender entity
t := s.mapToTenderFromParsedDoc(notice, "", fileName)
existingTender, err := s.findTenderByContractNoticeID(ctx, t.ContractNoticeID)
// existingTender, err := s.findTenderByContractNoticeID(ctx, t.ContractNoticeID)
// if err != nil {
// s.logger.Warn("Error checking for existing tender", map[string]interface{}{
// "contract_notice_id": t.ContractNoticeID,
// "error": err.Error(),
// })
// }
// if err == nil && existingTender != nil {
// // Update existing tender
// s.logger.Info("Found existing tender, updating", map[string]interface{}{
// "existing_tender_id": existingTender.ID.Hex(),
// "contract_notice_id": t.ContractNoticeID,
// })
// t.ID = existingTender.ID
// t.UpdatedAt = time.Now().Unix()
// err = s.tenderRepo.Update(ctx, t)
// if err != nil {
// s.logger.Error("Failed to update existing tender", map[string]interface{}{
// "tender_id": t.ID.Hex(),
// "error": err.Error(),
// })
// return fmt.Errorf("failed to update existing tender: %w", err)
// }
// s.logger.Info("Successfully updated tender", map[string]interface{}{
// "tender_id": t.ID.Hex(),
// })
// } else {
// // Create new tender
s.logger.Info("Creating new tender", map[string]interface{}{
"contract_notice_id": t.ContractNoticeID,
"tender_id": t.TenderID,
})
t.CreatedAt = time.Now().Unix()
t.UpdatedAt = t.CreatedAt
err = s.tenderRepo.Import(ctx, t)
if err != nil {
s.logger.Warn("Error checking for existing tender", map[string]interface{}{
s.logger.Error("Failed to create new tender", map[string]interface{}{
"contract_notice_id": t.ContractNoticeID,
"tender_id": t.TenderID,
"error": err.Error(),
})
return fmt.Errorf("failed to create tender: %w", err)
}
if err == nil && existingTender != nil {
// Update existing tender
s.logger.Info("Found existing tender, updating", map[string]interface{}{
"existing_tender_id": existingTender.ID.Hex(),
"contract_notice_id": t.ContractNoticeID,
})
t.ID = existingTender.ID
t.UpdatedAt = time.Now().Unix()
err = s.tenderRepo.Update(ctx, t)
if err != nil {
s.logger.Error("Failed to update existing tender", map[string]interface{}{
"tender_id": t.ID.Hex(),
"error": err.Error(),
})
return fmt.Errorf("failed to update existing tender: %w", err)
}
s.logger.Info("Successfully updated tender", map[string]interface{}{
"tender_id": t.ID.Hex(),
})
} else {
// Create new tender
s.logger.Info("Creating new tender", map[string]interface{}{
"contract_notice_id": t.ContractNoticeID,
"tender_id": t.TenderID,
})
t.CreatedAt = time.Now().Unix()
t.UpdatedAt = t.CreatedAt
err = s.tenderRepo.Create(ctx, t)
if err != nil {
s.logger.Error("Failed to create new tender", map[string]interface{}{
"contract_notice_id": t.ContractNoticeID,
"tender_id": t.TenderID,
"error": err.Error(),
})
return fmt.Errorf("failed to create tender: %w", err)
}
s.logger.Info("Successfully created new tender", map[string]interface{}{
"tender_id": t.TenderID,
"contract_notice_id": t.ContractNoticeID,
})
}
s.logger.Info("Successfully created new tender", map[string]interface{}{
"tender_id": t.TenderID,
"contract_notice_id": t.ContractNoticeID,
})
// }
// Log detailed parsed information based on notice type
s.logger.Info("Successfully parsed notice", map[string]interface{}{