diff --git a/src/app/project/repository.go b/src/app/project/repository.go index 164ff09bcff81560690b25aac0b4fad14d1f55a8..671636fbbe512d8560be0f676c5a2fe5c67d1636 100644 --- a/src/app/project/repository.go +++ b/src/app/project/repository.go @@ -33,6 +33,9 @@ type ProjectRepository interface { // FindByProjectID retrieves a project using its human-readable project ID FindByProjectID(ctx context.Context, projectID string) (*Project, error) + // FindByShortcut retrieves a project using its shortcut/abbreviation + FindByShortcut(ctx context.Context, shortcut string) (*Project, error) + // FindByCreatedBy retrieves all projects created by a specific user FindByCreatedBy(ctx context.Context, userID uuid.UUID) ([]*Project, error) @@ -81,7 +84,9 @@ func (r *MongoProjectRepository) Create(ctx context.Context, toCreate *ProjectTo // Set system-generated fields like ID and creation timestamp project := &Project{ ID: primitive.NewObjectID(), // Generate new MongoDB ObjectID + UUID: uuid.New(), // Generate new UUID for external references ProjectID: toCreate.ProjectID, // User-provided project identifier + Shortcut: toCreate.Shortcut, // User-provided project shortcut Name: toCreate.Name, // Project display name Description: toCreate.Description, // Optional project description StartDate: toCreate.StartDate, // Project start date @@ -156,6 +161,30 @@ func (r *MongoProjectRepository) FindByProjectID(ctx context.Context, projectID return &project, nil } +// FindByShortcut retrieves a project using its shortcut/abbreviation +// This method is used when checking for duplicate shortcuts during creation and updates +func (r *MongoProjectRepository) FindByShortcut(ctx context.Context, shortcut string) (*Project, error) { + ctx, cancel := context.WithTimeout(ctx, r.timeout) + defer cancel() + + log.Printf("DEBUG: Finding project by shortcut '%s'", shortcut) + + var project Project + // Query using the shortcut field (user-defined abbreviation) + err := r.projectCollection.FindOne(ctx, bson.M{"shortcut": shortcut}).Decode(&project) + if err != nil { + if err == mongo.ErrNoDocuments { + log.Printf("DEBUG: Project with shortcut '%s' not found (this may be expected)", shortcut) + return nil, fmt.Errorf("project not found") + } + log.Printf("ERROR: MongoDB query failed for shortcut '%s': %v", shortcut, err) + return nil, fmt.Errorf("failed to find project: %w", err) + } + + log.Printf("INFO: Found project '%s' by shortcut '%s'", project.Name, shortcut) + return &project, nil +} + // FindByCreatedBy retrieves all projects created by a specific user // Results are sorted by creation date (newest first) for better user experience func (r *MongoProjectRepository) FindByCreatedBy(ctx context.Context, userID uuid.UUID) ([]*Project, error) { @@ -246,8 +275,13 @@ func (r *MongoProjectRepository) FindWithRequirements(ctx context.Context, id pr req.Status = "Entwurf" // Default status for new requirements } if req.RequirementID == "" { - // Generate a default requirement ID from the MongoDB ObjectID - req.RequirementID = fmt.Sprintf("REQ-%s", req.ID.Hex()[:6]) + // Prefer shortcut if available (for project-based requirements) + if req.Shortcut != "" { + req.RequirementID = req.Shortcut + } else { + // Fallback: Generate a default requirement ID from the MongoDB ObjectID + req.RequirementID = fmt.Sprintf("REQ-%s", req.ID.Hex()[:6]) + } } requirements = append(requirements, &req) @@ -275,6 +309,7 @@ func (r *MongoProjectRepository) Update(ctx context.Context, update *ProjectToUp now := time.Now() updateDoc := bson.M{ "$set": bson.M{ + "shortcut": update.Shortcut, // Updated project shortcut "name": update.Name, // Updated project name "description": update.Description, // Updated description "start_date": update.StartDate, // Updated start date @@ -362,6 +397,7 @@ func (r *MongoProjectRepository) Search(ctx context.Context, query string, userI {"name": bson.M{"$regex": query, "$options": "i"}}, // Project name {"description": bson.M{"$regex": query, "$options": "i"}}, // Project description {"project_id": bson.M{"$regex": query, "$options": "i"}}, // Project ID + {"shortcut": bson.M{"$regex": query, "$options": "i"}}, // Project shortcut }, }