Work on requirements management
This commit is contained in:
@@ -1,26 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <dbus/api/api.h>
|
||||
#include <sdi_toolBox/generic/uuid.h>
|
||||
|
||||
namespace api::requirement
|
||||
{
|
||||
//--------------------------------------------------------------
|
||||
using TimePoint = std::chrono::system_clock::time_point;
|
||||
//--------------------------------------------------------------
|
||||
enum class Status
|
||||
{
|
||||
Draft, // The requirement is in draft state and has not been finalized
|
||||
InReview, // The requirement is currently being reviewed by stakeholders
|
||||
Approved, // The requirement has been approved and is ready for implementation
|
||||
Rejected // The requirement has been rejected and will not be implemented
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
struct Metadata
|
||||
{
|
||||
std::string uuid; // Unique identifier for the requirement, generated automatically
|
||||
std::string id; // Unique identifier for the requirement, provided by the user (e.g., "REQ-001")
|
||||
std::string author; // Name of the person who created the requirement
|
||||
TimePoint created_at; // Creation timestamp
|
||||
TimePoint updated_at; // Last update timestamp
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
struct Details
|
||||
{
|
||||
std::string name; // Short name or title of the requirement
|
||||
std::string description; // Detailed description of the requirement
|
||||
std::string acceptance_criteria; // Criteria that must be met for the requirement to be considered complete
|
||||
bool is_smart; // SMART indicator (Specific, Measurable, Achievable, Relevant, Time-bound)
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
struct Classification
|
||||
{
|
||||
std::string type; // Type of the requirement (e.g., "Functional", "Non-Functional", "Performance", etc.)
|
||||
std::string category; // Category of the requirement (e.g., "UI", "Backend", "Security", etc.)
|
||||
int priority; // Priority level of the requirement (e.g., 1 for highest priority, 5 for lowest)
|
||||
Status status; // Current status of the requirement (e.g., "Draft", "In Review", "Approved", "Rejected", etc.)
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
struct Requirement
|
||||
{
|
||||
std::string uuid;
|
||||
std::string parent_uuid;
|
||||
std::string id;
|
||||
std::string type;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::vector<Requirement> sub_requirements;
|
||||
|
||||
/* Default constructor */
|
||||
Requirement()
|
||||
{
|
||||
uuid = sdi_toolBox::generic::UuidGenerator::uuid_v4(); // Generate a unique UUID for the requirement
|
||||
}
|
||||
Metadata metadata; // General information about the requirement
|
||||
Details details; // Detailed information about the requirement
|
||||
Classification classification; // Classification information about the requirement
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
|
||||
@@ -37,11 +62,11 @@ struct RequirementEvent : dBus::api::DefaultData<dBus::makeID("requirement.requi
|
||||
|
||||
[[nodiscard]] std::string toString() const override
|
||||
{
|
||||
return std::format("RequirementEvent: id={}, name={}, subRequirementsCount={}",
|
||||
requirementData.id,
|
||||
requirementData.name,
|
||||
requirementData.description,
|
||||
requirementData.sub_requirements.size());
|
||||
// return std::format("RequirementEvent: id={}, name={}, subRequirementsCount={}",
|
||||
// requirementData.id,
|
||||
// requirementData.name,
|
||||
// requirementData.description);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
|
||||
73
src/core/projectManager/RequirementManager.cpp
Normal file
73
src/core/projectManager/RequirementManager.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "RequirementManager.h"
|
||||
|
||||
#include "requirementItem.h"
|
||||
|
||||
#include <sdi_toolBox/generic/uuid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace core::project;
|
||||
//--------------------------------------------------------------
|
||||
/* Default constructor */
|
||||
RequirementManager::RequirementManager()
|
||||
{
|
||||
m_rootRequirement = make_shared<RequirementItem>(*this); // Create the root requirement item and set it as the root requirement
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the root requirement */
|
||||
RequirementManager::RequirementItemPtr RequirementManager::getRootRequirement() const
|
||||
{
|
||||
return m_rootRequirement; // Return the root requirement item pointer
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the vector of child requirement items of the root requirement */
|
||||
std::vector<RequirementManager::RequirementItemPtr> RequirementManager::getRootRequirementChild() const
|
||||
{
|
||||
return m_rootRequirement->getChildren(); // Return the vector of child requirement items of the root requirement
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get a requirement by its UUID */
|
||||
RequirementManager::RequirementItemPtr RequirementManager::getRequirement(const std::string &uuid) const
|
||||
{
|
||||
if (m_requirementsByUuid.contains(uuid))
|
||||
return m_requirementsByUuid.at(uuid); // Return the requirement item pointer if found in the map
|
||||
return {}; // Return nullptr if the requirement with the given UUID is not found
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the vector of child requirement items of a requirement by its UUID */
|
||||
std::vector<RequirementManager::RequirementItemPtr> RequirementManager::getRequirementChildren(const std::string &uuid) const
|
||||
{
|
||||
if (m_requirementsByUuid.contains(uuid))
|
||||
return m_requirementsByUuid.at(uuid)->getChildren(); // Return the vector of child requirement items if the requirement with the given UUID is found in the map
|
||||
return {}; // Return an empty vector if the requirement with the given UUID is not found
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Generate a unique UUID string that is not already registered in the manager's internal map */
|
||||
std::string RequirementManager::generateUniqueUuid() const
|
||||
{
|
||||
std::string uuid;
|
||||
do
|
||||
{
|
||||
uuid = sdi_toolBox::generic::UuidGenerator::uuid_v4(); // Generate a random UUID v4 string
|
||||
} while (isRequirementRegistered(uuid)); // Check if the generated UUID is already registered
|
||||
|
||||
return uuid; // Return the unique UUID string
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Check if a requirement with the given UUID is registered in the manager's internal map */
|
||||
bool RequirementManager::isRequirementRegistered(const std::string &uuid) const
|
||||
{
|
||||
return m_requirementsByUuid.contains(uuid);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Register a requirement in the manager's internal map for quick lookup by UUID */
|
||||
void RequirementManager::registerRequirement(const RequirementItemPtr &requirement)
|
||||
{
|
||||
m_requirementsByUuid[requirement->metadata.uuid] = requirement;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Unregister a requirement from the manager's internal map */
|
||||
void RequirementManager::unregisterRequirement(const std::string &uuid)
|
||||
{
|
||||
m_requirementsByUuid.erase(uuid);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
42
src/core/projectManager/RequirementManager.h
Normal file
42
src/core/projectManager/RequirementManager.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace core::project
|
||||
{
|
||||
class RequirementItem;
|
||||
//--------------------------------------------------------------
|
||||
class RequirementManager
|
||||
{
|
||||
using RequirementItemPtr = std::shared_ptr<RequirementItem>;
|
||||
|
||||
public:
|
||||
RequirementManager(); // Default constructor
|
||||
virtual ~RequirementManager() = default; // Default destructor
|
||||
RequirementManager(const RequirementManager &obj) = delete; // Copy constructor
|
||||
RequirementManager(RequirementManager &&obj) noexcept = delete; // Move constructor
|
||||
RequirementManager &operator=(const RequirementManager &obj) = delete; // Copy assignment operator
|
||||
RequirementManager &operator=(RequirementManager &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
[[nodiscard]] RequirementItemPtr getRootRequirement() const; // Get the root requirement
|
||||
[[nodiscard]] std::vector<RequirementItemPtr> getRootRequirementChild() const; // Get the vector of child requirement items of the root requirement
|
||||
|
||||
[[nodiscard]] RequirementItemPtr getRequirement(const std::string &uuid) const; // Get a requirement by its UUID
|
||||
[[nodiscard]] std::vector<RequirementItemPtr> getRequirementChildren(const std::string &uuid) const; // Get the vector of child requirement items of a requirement by its UUID
|
||||
|
||||
// Requirement management functions
|
||||
[[nodiscard]] std::string generateUniqueUuid() const; // Generate a unique UUID string that is not already registered in the manager's internal map
|
||||
[[nodiscard]] bool isRequirementRegistered(const std::string &uuid) const; // Check if a requirement with the given UUID is registered in the manager's internal map
|
||||
void registerRequirement(const RequirementItemPtr &requirement); // Register a requirement in the manager's internal map for quick lookup by UUID
|
||||
void unregisterRequirement(const std::string &uuid); // Unregister a requirement from the manager's internal map
|
||||
|
||||
protected:
|
||||
RequirementItemPtr m_rootRequirement; // Root requirement of the current project
|
||||
std::unordered_map<std::string, RequirementItemPtr> m_requirementsByUuid; // Map of requirement UUID to requirement pointer for quick lookup
|
||||
|
||||
private:
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace core::project
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "projectData.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace core::project;
|
||||
//--------------------------------------------------------------
|
||||
/* Get the root requirement */
|
||||
ProjectData::RequirementPtr ProjectData::getRootRequirement()
|
||||
{
|
||||
return m_rootRequirement;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <api/requirement.h>
|
||||
#include <memory>
|
||||
|
||||
namespace core::project
|
||||
{
|
||||
//--------------------------------------------------------------
|
||||
class ProjectData
|
||||
{
|
||||
using RequirementPtr = std::shared_ptr<api::requirement::Requirement>;
|
||||
|
||||
public:
|
||||
ProjectData() = default; // Default constructor
|
||||
virtual ~ProjectData() = default; // Default destructor
|
||||
ProjectData(const ProjectData &obj) = delete; // Copy constructor
|
||||
ProjectData(ProjectData &&obj) noexcept = delete; // Move constructor
|
||||
ProjectData &operator=(const ProjectData &obj) = delete; // Copy assignment operator
|
||||
ProjectData &operator=(ProjectData &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
RequirementPtr getRootRequirement(); // Get the root requirement
|
||||
|
||||
protected:
|
||||
RequirementPtr m_rootRequirement; // Root requirement of the current project
|
||||
|
||||
private:
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace core::project
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "projectManager.h"
|
||||
|
||||
#include "projectData.h"
|
||||
#include "RequirementManager.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace core::project;
|
||||
@@ -117,7 +117,7 @@ void ProjectManager::on_projectOperationEvent(const ProjectOperationMessage_ptr
|
||||
/* Process a file creation event */
|
||||
void ProjectManager::on_projectCreateFileEvent(const ProjectOperationMessage_ptr &message)
|
||||
{
|
||||
m_projectData = make_shared<ProjectData>();
|
||||
m_requirementManager = make_shared<RequirementManager>();
|
||||
|
||||
message->responsePromise.set_value();
|
||||
}
|
||||
@@ -165,7 +165,7 @@ void ProjectManager::on_projectSaveFileEvent(const ProjectOperationMessage_ptr &
|
||||
/* Process a file close event */
|
||||
void ProjectManager::on_projectCloseFileEvent(const ProjectOperationMessage_ptr &message)
|
||||
{
|
||||
m_projectData = {};
|
||||
m_requirementManager = {};
|
||||
message->responsePromise.set_value();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
namespace core::project
|
||||
{
|
||||
class ProjectData;
|
||||
class RequirementManager;
|
||||
//--------------------------------------------------------------
|
||||
class ProjectManager : public dBus::Node
|
||||
{
|
||||
using ProjectPtr = std::shared_ptr<ProjectData>;
|
||||
using RequirementManagerPtr = std::shared_ptr<RequirementManager>;
|
||||
|
||||
public:
|
||||
ProjectManager() = delete; // Default constructor
|
||||
@@ -27,7 +27,7 @@ class ProjectManager : public dBus::Node
|
||||
protected:
|
||||
std::filesystem::path m_filePath; // Path of the currently opened project file
|
||||
|
||||
ProjectPtr m_projectData; // Current project data, including the root requirement and all its sub-requirements
|
||||
RequirementManagerPtr m_requirementManager; // Pointer to the requirement manager of the current project
|
||||
|
||||
private:
|
||||
void openFile(const std::filesystem::path &filePath); // Open a project file and load the requirements
|
||||
|
||||
56
src/core/projectManager/requirementItem.cpp
Normal file
56
src/core/projectManager/requirementItem.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "requirementItem.h"
|
||||
|
||||
#include "RequirementManager.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace core::project;
|
||||
//--------------------------------------------------------------
|
||||
/* Constructor */
|
||||
RequirementItem::RequirementItem(RequirementManager &manager, const std::shared_ptr<RequirementItem> &parentRequirement)
|
||||
: m_requirementManager(manager)
|
||||
{
|
||||
// Initialization
|
||||
metadata.uuid = m_requirementManager.generateUniqueUuid(); // Generate a unique UUID for this requirement item
|
||||
m_parent = parentRequirement; // Set the m_parent requirement item
|
||||
|
||||
// Register this requirement item in the manager's internal map
|
||||
m_requirementManager.registerRequirement(shared_from_this());
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Append a child requirement item to this requirement item */
|
||||
void RequirementItem::appendChild(const api::requirement::Requirement &child)
|
||||
{
|
||||
// Create a new requirement item for the child requirement and set this requirement item as its m_parent
|
||||
const auto childItem = make_shared<RequirementItem>(m_requirementManager);
|
||||
childItem->metadata = child.metadata;
|
||||
childItem->details = child.details;
|
||||
childItem->classification = child.classification;
|
||||
|
||||
// Prepare requirement links
|
||||
childItem->metadata.uuid = m_requirementManager.generateUniqueUuid(); // Generate a unique UUID for this requirement item
|
||||
childItem->m_parent = shared_from_this();
|
||||
|
||||
// Register this requirement item in the manager's internal map
|
||||
m_requirementManager.registerRequirement(childItem);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Remove a child requirement item from this requirement item by its UUID */
|
||||
void RequirementItem::removeChild(const std::string &childUuid)
|
||||
{
|
||||
// Unregister the child requirement item from the manager's internal map
|
||||
m_requirementManager.unregisterRequirement(childUuid);
|
||||
|
||||
// Find the child requirement item with the given UUID
|
||||
const auto it = ranges::find_if(m_children,
|
||||
[&childUuid](const RequirementItemPtr &child)
|
||||
{ return child->metadata.uuid == childUuid; });
|
||||
if (it != m_children.end())
|
||||
m_children.erase(it); // Remove the child requirement item from the vector of children
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
/* Get the vector of child requirement items of this requirement item */
|
||||
std::vector<RequirementItem::RequirementItemPtr> RequirementItem::getChildren() const
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
38
src/core/projectManager/requirementItem.h
Normal file
38
src/core/projectManager/requirementItem.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <api/requirement.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace core::project
|
||||
{
|
||||
class RequirementManager;
|
||||
//--------------------------------------------------------------
|
||||
class RequirementItem : public std::enable_shared_from_this<RequirementItem>
|
||||
, public api::requirement::Requirement
|
||||
{
|
||||
using RequirementItemPtr = std::shared_ptr<RequirementItem>;
|
||||
|
||||
public:
|
||||
RequirementItem() = delete; // Default constructor
|
||||
virtual ~RequirementItem() = default; // Default destructor
|
||||
RequirementItem(const RequirementItem &obj) = delete; // Copy constructor
|
||||
RequirementItem(RequirementItem &&obj) noexcept = delete; // Move constructor
|
||||
RequirementItem &operator=(const RequirementItem &obj) = delete; // Copy assignment operator
|
||||
RequirementItem &operator=(RequirementItem &&obj) noexcept = delete; // Move assignment operator
|
||||
|
||||
explicit RequirementItem(RequirementManager &manager, // Constructor
|
||||
const std::shared_ptr<RequirementItem> &parentRequirement = nullptr);
|
||||
|
||||
// Children management functions
|
||||
void appendChild(const api::requirement::Requirement &child); // Append a child requirement item to this requirement item
|
||||
void removeChild(const std::string &childUuid); // Remove a child requirement item from this requirement item by its UUID
|
||||
[[nodiscard]] std::vector<RequirementItemPtr> getChildren() const; // Get the vector of child requirement items of this requirement item
|
||||
|
||||
protected:
|
||||
RequirementManager &m_requirementManager; // Reference to the requirement manager that owns this requirement item
|
||||
std::weak_ptr<RequirementItem> m_parent; // Weak pointer to the m_parent requirement item (nullptr for root)
|
||||
std::vector<RequirementItemPtr> m_children; // Vector of shared pointers to child requirement items
|
||||
};
|
||||
//--------------------------------------------------------------
|
||||
} // namespace core::project
|
||||
Reference in New Issue
Block a user