201 lines
9.5 KiB
Go
201 lines
9.5 KiB
Go
package tender
|
|
|
|
import "tm/pkg/response"
|
|
|
|
// UpdateTenderRequest represents a request to update an existing tender
|
|
type UpdateTenderRequest struct {
|
|
ID string `json:"id" valid:"required~Tender ID is required"`
|
|
Title *string `json:"title,omitempty" valid:"stringlength(1|500)~Title must be between 1 and 500 characters"`
|
|
Description *string `json:"description,omitempty" valid:"stringlength(0|5000)~Description must not exceed 5000 characters"`
|
|
Status *TenderStatus `json:"status,omitempty"`
|
|
EstimatedValue *float64 `json:"estimated_value,omitempty" valid:"range(0|999999999999)~Estimated value must be between 0 and 999999999999"`
|
|
Currency *string `json:"currency,omitempty" valid:"stringlength(3|3)~Currency must be 3 characters"`
|
|
TenderDeadline *int64 `json:"tender_deadline,omitempty"` // Unix milliseconds
|
|
}
|
|
|
|
// SearchForm represents a request to list tenders with pagination and filtering
|
|
type SearchForm struct {
|
|
Search *string `query:"q" valid:"optional"`
|
|
Title *string `query:"title" valid:"optional"`
|
|
Description *string `query:"description" valid:"optional"`
|
|
NoticeType *string `query:"notice_type" valid:"optional"`
|
|
NoticeTypes []string `query:"notice_types" valid:"optional"`
|
|
FormTypes []string `query:"form_types" valid:"optional"`
|
|
ProcurementType *string `query:"procurement_type" valid:"optional"`
|
|
Country *string `query:"country" valid:"optional"`
|
|
CountryCode *string `query:"country_code" valid:"optional"`
|
|
CountryCodes []string `query:"country_codes" valid:"optional"`
|
|
RegionCodes []string `query:"region_codes" valid:"optional"`
|
|
CompanyID *string `query:"company_id" valid:"optional"`
|
|
CustomerID *string `query:"customer_id" valid:"optional"`
|
|
Status []string `query:"status" valid:"optional"`
|
|
MainClassification *string `query:"main_classification" valid:"optional"`
|
|
Classifications []string `query:"classifications" valid:"optional"`
|
|
CpvCodes []string `query:"cpv_codes" valid:"optional"`
|
|
MinEstimatedValue *float64 `query:"min_estimated_value" valid:"optional"`
|
|
MaxEstimatedValue *float64 `query:"max_estimated_value" valid:"optional"`
|
|
Currency string `query:"currency" valid:"optional"`
|
|
CreatedAt *int64 `query:"created_at" valid:"optional"`
|
|
CreatedAtFrom *int64 `query:"created_at_from" valid:"optional"`
|
|
CreatedAtTo *int64 `query:"created_at_to" valid:"optional"`
|
|
TenderDeadline *int64 `query:"tender_deadline" valid:"optional"`
|
|
TenderDeadlineFrom *int64 `query:"tender_deadline_from" valid:"optional"`
|
|
TenderDeadlineTo *int64 `query:"tender_deadline_to" valid:"optional"`
|
|
DeadlineFrom *int64 `query:"deadline_from" valid:"optional"`
|
|
DeadlineTo *int64 `query:"deadline_to" valid:"optional"`
|
|
PublicationDate *int64 `query:"publication_date" valid:"optional"`
|
|
PublicationDateFrom *int64 `query:"publication_date_from" valid:"optional"`
|
|
PublicationDateTo *int64 `query:"publication_date_to" valid:"optional"`
|
|
SubmissionDeadline *int64 `query:"submission_deadline" valid:"optional"`
|
|
SubmissionDateAliasFrom *int64 `query:"submission_deadline_from" valid:"optional"`
|
|
SubmissionDateAliasTo *int64 `query:"submission_deadline_to" valid:"optional"`
|
|
SubmissionDateFrom *int64 `query:"submission_date_from" valid:"optional"`
|
|
SubmissionDateTo *int64 `query:"submission_date_to" valid:"optional"`
|
|
Source []string `query:"source" valid:"optional"`
|
|
BuyerOrganizationID *string `query:"buyer_organization_id" valid:"optional"`
|
|
Languages []string `query:"languages" valid:"optional"`
|
|
OnlyActiveDeadlines bool `query:"-" valid:"optional"`
|
|
Language *string `query:"lang" valid:"optional"`
|
|
}
|
|
|
|
// SearchResponse represents the response for listing tenders
|
|
type SearchResponse struct {
|
|
Tenders []TenderResponse `json:"tenders"`
|
|
Metadata *response.Meta `json:"-"`
|
|
}
|
|
|
|
// TenderResponse represents a tender in API responses
|
|
type TenderResponse struct {
|
|
ID string `json:"id"`
|
|
NoticePublicationID string `json:"notice_publication_id"`
|
|
NoticeTypeCode string `json:"notice_type_code"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
ProcurementTypeCode string `json:"procurement_type_code"`
|
|
ProcedureCode string `json:"procedure_code"`
|
|
MainClassification string `json:"main_classification"`
|
|
EstimatedValue float64 `json:"estimated_value"`
|
|
Currency string `json:"currency"`
|
|
Duration string `json:"duration"`
|
|
DurationUnit string `json:"duration_unit"`
|
|
PublicationDate int64 `json:"publication_date"`
|
|
TenderDeadline int64 `json:"tender_deadline"`
|
|
SubmissionDeadline int64 `json:"submission_deadline"`
|
|
ApplicationDeadline int64 `json:"application_deadline"`
|
|
SubmissionURL string `json:"submission_url"`
|
|
CountryCode string `json:"country_code"`
|
|
BuyerOrganization *OrganizationResponse `json:"buyer_organization"`
|
|
Status TenderStatus `json:"status"`
|
|
TenderID string `json:"tender_id"`
|
|
CreatedAt int64 `json:"created_at"`
|
|
OverallSummary string `json:"overall_summary,omitempty"` // AI-generated summary from the pipeline
|
|
Language string `json:"language,omitempty"`
|
|
}
|
|
|
|
// TenderDocumentResponse represents a scraped tender document available for download.
|
|
type TenderDocumentResponse struct {
|
|
Filename string `json:"filename"`
|
|
Size int64 `json:"size"`
|
|
LastModified int64 `json:"last_modified"`
|
|
DocumentType string `json:"document_type,omitempty"`
|
|
}
|
|
|
|
// TenderDocumentsResponse represents scraped documents for a tender.
|
|
type TenderDocumentsResponse struct {
|
|
TenderID string `json:"tender_id"`
|
|
Documents []TenderDocumentResponse `json:"documents"`
|
|
}
|
|
|
|
type OrganizationResponse struct {
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
// ToTenderResponse converts a Tender entity to TenderResponse
|
|
func (t *Tender) ToResponse() *TenderResponse {
|
|
return t.ToResponseWithLanguage("")
|
|
}
|
|
|
|
// ToResponseWithLanguage converts a Tender entity to TenderResponse using a preferred language.
|
|
// When language is provided and translation exists, translated title/description are returned.
|
|
func (t *Tender) ToResponseWithLanguage(language string) *TenderResponse {
|
|
|
|
org := &OrganizationResponse{}
|
|
if t.BuyerOrganization != nil {
|
|
org.Name = t.BuyerOrganization.Name
|
|
}
|
|
title := t.Title
|
|
description := t.Description
|
|
usedLanguage := ""
|
|
if language != "" {
|
|
if entry, ok := t.Translations[language]; ok {
|
|
title = entry.Title
|
|
description = entry.Description
|
|
usedLanguage = language
|
|
}
|
|
}
|
|
|
|
response := &TenderResponse{
|
|
ID: t.ID.Hex(),
|
|
NoticePublicationID: t.NoticePublicationID,
|
|
NoticeTypeCode: t.NoticeTypeCode,
|
|
Title: title,
|
|
Description: description,
|
|
ProcurementTypeCode: t.ProcurementTypeCode,
|
|
ProcedureCode: t.ProcedureCode,
|
|
MainClassification: t.MainClassification,
|
|
EstimatedValue: t.EstimatedValue,
|
|
Currency: t.Currency,
|
|
Duration: t.Duration,
|
|
DurationUnit: t.DurationUnit,
|
|
PublicationDate: t.PublicationDate,
|
|
TenderDeadline: t.TenderDeadline,
|
|
SubmissionDeadline: t.SubmissionDeadline,
|
|
ApplicationDeadline: t.ApplicationDeadline,
|
|
CountryCode: t.CountryCode,
|
|
SubmissionURL: t.SubmissionURL,
|
|
BuyerOrganization: org,
|
|
Status: t.Status,
|
|
TenderID: t.TenderID,
|
|
CreatedAt: t.CreatedAt,
|
|
Language: usedLanguage,
|
|
}
|
|
|
|
return response
|
|
}
|
|
|
|
// AITranslateRequest represents a request for on-demand AI translation.
|
|
type AITranslateRequest struct {
|
|
Language string `json:"language" valid:"required,stringlength(2|5)~Language must be between 2 and 5 characters"`
|
|
}
|
|
|
|
// AITranslateResponse represents the response for AI translation trigger.
|
|
type AITranslateResponse struct {
|
|
NoticeID string `json:"notice_id"`
|
|
Language string `json:"language"`
|
|
TranslatedTitle string `json:"translated_title"`
|
|
TranslatedDescription string `json:"translated_description"`
|
|
}
|
|
|
|
// AISummaryResponse represents the response for getting an AI-generated summary
|
|
type AISummaryResponse struct {
|
|
NoticeID string `json:"notice_id"`
|
|
OverallSummary string `json:"overall_summary"`
|
|
Source string `json:"source"` // "storage" or "on_demand"
|
|
}
|
|
|
|
// AISummarizeResponse represents the response for triggering on-demand AI summarization
|
|
type AISummarizeResponse struct {
|
|
NoticeID string `json:"notice_id"`
|
|
Summaries []AIDocumentSummary `json:"summaries"`
|
|
OverallSummary *string `json:"overall_summary"`
|
|
}
|
|
|
|
// AIDocumentSummary represents a single document summary from the AI service
|
|
type AIDocumentSummary struct {
|
|
DocumentName string `json:"document_name"`
|
|
DocumentType string `json:"document_type"`
|
|
Summary string `json:"summary"`
|
|
SummaryModel string `json:"summary_model"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|