Implement Feedback Management System with CRUD Operations and API Enhancements
- Introduced a new feedback management system, including the creation of feedback entities, services, and repositories. - Implemented CRUD operations for feedback, allowing users to submit likes and dislikes on tenders. - Developed administrative endpoints for listing and retrieving feedback with comprehensive filtering options. - Enhanced public API to allow users to view feedback related to tenders. - Updated Swagger documentation to reflect new feedback endpoints and their functionalities. - Removed obsolete configuration file `config.yaml` as part of the transition to a modular configuration system. - Ensured adherence to Clean Architecture principles throughout the implementation.
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
"tm/pkg/logger"
|
||||
mongopkg "tm/pkg/mongo"
|
||||
"tm/pkg/mongo"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
@@ -39,36 +39,36 @@ type Repository interface {
|
||||
|
||||
// companyRepository implements the Repository interface using the MongoDB ORM
|
||||
type companyRepository struct {
|
||||
ormRepo mongopkg.Repository[Company]
|
||||
ormRepo mongo.Repository[Company]
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
// NewCompanyRepository creates a new company repository
|
||||
func NewCompanyRepository(mongoManager *mongopkg.ConnectionManager, logger logger.Logger) Repository {
|
||||
func NewCompanyRepository(mongoManager *mongo.ConnectionManager, logger logger.Logger) Repository {
|
||||
// Create indexes using the ORM's index management
|
||||
indexes := []mongopkg.Index{
|
||||
*mongopkg.CreateUniqueIndex("name_idx", bson.D{{Key: "name", Value: 1}}),
|
||||
*mongopkg.CreateUniqueIndex("registration_number_idx", bson.D{{Key: "registration_number", Value: 1}}),
|
||||
*mongopkg.CreateUniqueIndex("tax_id_idx", bson.D{{Key: "tax_id", Value: 1}}),
|
||||
*mongopkg.NewIndex("type_idx", bson.D{{Key: "type", Value: 1}}),
|
||||
*mongopkg.NewIndex("status_idx", bson.D{{Key: "status", Value: 1}}),
|
||||
*mongopkg.NewIndex("industry_idx", bson.D{{Key: "industry", Value: 1}}),
|
||||
*mongopkg.NewIndex("is_verified_idx", bson.D{{Key: "is_verified", Value: 1}}),
|
||||
*mongopkg.NewIndex("is_compliant_idx", bson.D{{Key: "is_compliant", Value: 1}}),
|
||||
*mongopkg.NewIndex("language_idx", bson.D{{Key: "language", Value: 1}}),
|
||||
*mongopkg.NewIndex("currency_idx", bson.D{{Key: "currency", Value: 1}}),
|
||||
*mongopkg.NewIndex("employee_count_idx", bson.D{{Key: "employee_count", Value: 1}}),
|
||||
*mongopkg.NewIndex("annual_revenue_idx", bson.D{{Key: "annual_revenue", Value: 1}}),
|
||||
*mongopkg.NewIndex("founded_year_idx", bson.D{{Key: "founded_year", Value: 1}}),
|
||||
*mongopkg.NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
||||
indexes := []mongo.Index{
|
||||
*mongo.CreateUniqueIndex("name_idx", bson.D{{Key: "name", Value: 1}}),
|
||||
*mongo.CreateUniqueIndex("registration_number_idx", bson.D{{Key: "registration_number", Value: 1}}),
|
||||
*mongo.CreateUniqueIndex("tax_id_idx", bson.D{{Key: "tax_id", Value: 1}}),
|
||||
*mongo.NewIndex("type_idx", bson.D{{Key: "type", Value: 1}}),
|
||||
*mongo.NewIndex("status_idx", bson.D{{Key: "status", Value: 1}}),
|
||||
*mongo.NewIndex("industry_idx", bson.D{{Key: "industry", Value: 1}}),
|
||||
*mongo.NewIndex("is_verified_idx", bson.D{{Key: "is_verified", Value: 1}}),
|
||||
*mongo.NewIndex("is_compliant_idx", bson.D{{Key: "is_compliant", Value: 1}}),
|
||||
*mongo.NewIndex("language_idx", bson.D{{Key: "language", Value: 1}}),
|
||||
*mongo.NewIndex("currency_idx", bson.D{{Key: "currency", Value: 1}}),
|
||||
*mongo.NewIndex("employee_count_idx", bson.D{{Key: "employee_count", Value: 1}}),
|
||||
*mongo.NewIndex("annual_revenue_idx", bson.D{{Key: "annual_revenue", Value: 1}}),
|
||||
*mongo.NewIndex("founded_year_idx", bson.D{{Key: "founded_year", Value: 1}}),
|
||||
*mongo.NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}),
|
||||
// Tag indexes for efficient search
|
||||
*mongopkg.NewIndex("cpv_codes_idx", bson.D{{Key: "tags.cpv_codes", Value: 1}}),
|
||||
*mongopkg.NewIndex("categories_idx", bson.D{{Key: "tags.categories", Value: 1}}),
|
||||
*mongopkg.NewIndex("keywords_idx", bson.D{{Key: "tags.keywords", Value: 1}}),
|
||||
*mongopkg.NewIndex("specializations_idx", bson.D{{Key: "tags.specializations", Value: 1}}),
|
||||
*mongopkg.NewIndex("certifications_idx", bson.D{{Key: "tags.certifications", Value: 1}}),
|
||||
*mongo.NewIndex("cpv_codes_idx", bson.D{{Key: "tags.cpv_codes", Value: 1}}),
|
||||
*mongo.NewIndex("categories_idx", bson.D{{Key: "tags.categories", Value: 1}}),
|
||||
*mongo.NewIndex("keywords_idx", bson.D{{Key: "tags.keywords", Value: 1}}),
|
||||
*mongo.NewIndex("specializations_idx", bson.D{{Key: "tags.specializations", Value: 1}}),
|
||||
*mongo.NewIndex("certifications_idx", bson.D{{Key: "tags.certifications", Value: 1}}),
|
||||
// Text index for search
|
||||
*mongopkg.CreateTextIndex("search_idx", "name", "description", "industry"),
|
||||
*mongo.CreateTextIndex("search_idx", "name", "description", "industry"),
|
||||
}
|
||||
|
||||
// Create indexes
|
||||
@@ -80,7 +80,7 @@ func NewCompanyRepository(mongoManager *mongopkg.ConnectionManager, logger logge
|
||||
}
|
||||
|
||||
// Create ORM repository
|
||||
ormRepo := mongopkg.NewRepository[Company](mongoManager.GetCollection("companies"), logger)
|
||||
ormRepo := mongo.NewRepository[Company](mongoManager.GetCollection("companies"), logger)
|
||||
|
||||
return &companyRepository{
|
||||
ormRepo: ormRepo,
|
||||
@@ -119,7 +119,7 @@ func (r *companyRepository) Create(ctx context.Context, company *Company) error
|
||||
func (r *companyRepository) GetByID(ctx context.Context, id string) (*Company, error) {
|
||||
company, err := r.ormRepo.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, mongopkg.ErrDocumentNotFound) {
|
||||
if errors.Is(err, mongo.ErrDocumentNotFound) {
|
||||
return nil, errors.New("company not found")
|
||||
}
|
||||
r.logger.Error("Failed to get company by ID", map[string]interface{}{
|
||||
@@ -137,7 +137,7 @@ func (r *companyRepository) GetByName(ctx context.Context, name string) (*Compan
|
||||
filter := bson.M{"name": name}
|
||||
company, err := r.ormRepo.FindOne(ctx, filter)
|
||||
if err != nil {
|
||||
if errors.Is(err, mongopkg.ErrDocumentNotFound) {
|
||||
if errors.Is(err, mongo.ErrDocumentNotFound) {
|
||||
return nil, errors.New("company not found")
|
||||
}
|
||||
r.logger.Error("Failed to get company by name", map[string]interface{}{
|
||||
@@ -155,7 +155,7 @@ func (r *companyRepository) GetByRegistrationNumber(ctx context.Context, registr
|
||||
filter := bson.M{"registration_number": registrationNumber}
|
||||
company, err := r.ormRepo.FindOne(ctx, filter)
|
||||
if err != nil {
|
||||
if errors.Is(err, mongopkg.ErrDocumentNotFound) {
|
||||
if errors.Is(err, mongo.ErrDocumentNotFound) {
|
||||
return nil, errors.New("company not found")
|
||||
}
|
||||
r.logger.Error("Failed to get company by registration number", map[string]interface{}{
|
||||
@@ -173,7 +173,7 @@ func (r *companyRepository) GetByTaxID(ctx context.Context, taxID string) (*Comp
|
||||
filter := bson.M{"tax_id": taxID}
|
||||
company, err := r.ormRepo.FindOne(ctx, filter)
|
||||
if err != nil {
|
||||
if errors.Is(err, mongopkg.ErrDocumentNotFound) {
|
||||
if errors.Is(err, mongo.ErrDocumentNotFound) {
|
||||
return nil, errors.New("company not found")
|
||||
}
|
||||
r.logger.Error("Failed to get company by tax ID", map[string]interface{}{
|
||||
@@ -289,7 +289,7 @@ func (r *companyRepository) Delete(ctx context.Context, id string) error {
|
||||
// List retrieves companies with pagination
|
||||
func (r *companyRepository) List(ctx context.Context, limit, offset int) ([]*Company, error) {
|
||||
// Build pagination
|
||||
pagination := mongopkg.NewPaginationBuilder().
|
||||
pagination := mongo.NewPaginationBuilder().
|
||||
Limit(limit).
|
||||
Skip(offset).
|
||||
SortDesc("created_at").
|
||||
@@ -407,7 +407,7 @@ func (r *companyRepository) Search(ctx context.Context, search string, companyTy
|
||||
}
|
||||
|
||||
// Build pagination
|
||||
pagination := mongopkg.NewPaginationBuilder().
|
||||
pagination := mongo.NewPaginationBuilder().
|
||||
Limit(limit).
|
||||
Skip(offset)
|
||||
|
||||
@@ -755,7 +755,7 @@ func (r *companyRepository) SearchByTags(ctx context.Context, cpvCodes []string,
|
||||
filter["status"] = bson.M{"$ne": CompanyStatusInactive}
|
||||
|
||||
// Build pagination
|
||||
pagination := mongopkg.NewPaginationBuilder().
|
||||
pagination := mongo.NewPaginationBuilder().
|
||||
Limit(limit).
|
||||
Skip(offset).
|
||||
SortDesc("created_at").
|
||||
|
||||
Reference in New Issue
Block a user