Initial commit

This commit is contained in:
2026-07-13 09:25:40 +07:00
parent c08ff54676
commit bccfb156d7
1938 changed files with 641646 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
using RobotNet.VDA5050.Type;
namespace RobotNet10.MapEditor.Shared.DTOs.Edge;
/// <summary>
/// Corridor data transfer object for VDA5050 Order
/// Maps to: edge.corridor
/// Definition of boundaries in which a vehicle can deviate from its trajectory, e.g. to avoid obstacles.
/// </summary>
public class CorridorDto
{
/// <summary>
/// Defines the width of the corridor in meters to the left related to the trajectory of the vehicle.
/// Minimum: 0.0
/// </summary>
public double? LeftWidth { get; set; }
/// <summary>
/// Defines the width of the corridor in meters to the right related to the trajectory of the vehicle.
/// Minimum: 0.0
/// </summary>
public double? RightWidth { get; set; }
/// <summary>
/// Defines whether the boundaries are valid for the kinematic center or the contour of the vehicle.
/// Optional: KINEMATICCENTER, CONTOUR
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public CorridorRefPoint? CorridorRefPoint { get; set; }
}

View File

@@ -0,0 +1,32 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Edge;
/// <summary>
/// Edge data transfer object with full details including vehicle properties
/// </summary>
public class EdgeDto
{
public Guid Id { get; set; }
public Guid LevelId { get; set; }
public string EdgeId { get; set; } = string.Empty;
public string? EdgeName { get; set; }
public string? EdgeDescription { get; set; }
public Guid StartNodeId { get; set; }
public Guid EndNodeId { get; set; }
/// <summary>
/// Start node details (for convenience)
/// </summary>
public Node.NodeDto? StartNode { get; set; }
/// <summary>
/// End node details (for convenience)
/// </summary>
public Node.NodeDto? EndNode { get; set; }
/// <summary>
/// Vehicle-specific properties for this edge
/// </summary>
public List<EdgeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,93 @@
using System.Text.Json.Serialization;
using RobotNet.VDA5050.Type;
namespace RobotNet10.MapEditor.Shared.DTOs.Edge;
/// <summary>
/// Edge vehicle property data transfer object
/// </summary>
public class EdgeVehiclePropertyDto
{
public Guid Id { get; set; }
public Guid EdgeId { get; set; }
public Guid VehicleTypeId { get; set; }
/// <summary>
/// Vehicle type identifier (for reference)
/// </summary>
public string? VehicleTypeIdString { get; set; }
public double? VehicleOrientation { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public OrientationType? OrientationType { get; set; }
public bool? RotationAllowed { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public RotationDirection? RotationAtStartNodeAllowed { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public RotationDirection? RotationAtEndNodeAllowed { get; set; }
public double? MaxSpeed { get; set; }
public double? MaxRotationSpeed { get; set; }
public double? MinHeight { get; set; }
public double? MaxHeight { get; set; }
/// <summary>
/// Load restriction for this edge (VDMA LIF: loadRestriction)
/// </summary>
public LoadRestrictionDto? LoadRestriction { get; set; }
/// <summary>
/// Trajectory degree (NURBS curve degree) - Optional
/// Values: 1 (linear), 2 (quadratic), 3 (cubic)
/// </summary>
public int? TrajectoryDegree { get; set; }
/// <summary>
/// Trajectory control point 1 X coordinate (meters) - Optional
/// Used for degree 2 and 3 curves
/// </summary>
public double? TrajectoryControlPoint1X { get; set; }
/// <summary>
/// Trajectory control point 1 Y coordinate (meters) - Optional
/// Used for degree 2 and 3 curves
/// </summary>
public double? TrajectoryControlPoint1Y { get; set; }
/// <summary>
/// Trajectory control point 2 X coordinate (meters) - Optional
/// Used for degree 3 curves only
/// </summary>
public double? TrajectoryControlPoint2X { get; set; }
/// <summary>
/// Trajectory control point 2 Y coordinate (meters) - Optional
/// Used for degree 3 curves only
/// </summary>
public double? TrajectoryControlPoint2Y { get; set; }
/// <summary>
/// Actions as JSON array (VDMA LIF format)
/// </summary>
public string? Actions { get; set; }
/// <summary>
/// Corridor left width (meters) - Optional
/// Defines the width of the corridor to the left related to the trajectory
/// </summary>
public double? CorridorLeftWidth { get; set; }
/// <summary>
/// Corridor right width (meters) - Optional
/// Defines the width of the corridor to the right related to the trajectory
/// </summary>
public double? CorridorRightWidth { get; set; }
/// <summary>
/// Corridor reference point (VDA5050: corridorRefPoint) - Optional
/// Defines whether the boundaries are valid for the kinematic center or the contour of the vehicle
/// Values: KINEMATICCENTER, CONTOUR
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public CorridorRefPoint? CorridorRefPoint { get; set; }
}

View File

@@ -0,0 +1,25 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Edge;
/// <summary>
/// Load restriction data transfer object for VDMA LIF
/// Maps to: edge.vehicleTypeEdgeProperties[].loadRestriction
/// </summary>
public class LoadRestrictionDto
{
/// <summary>
/// Indicates if the edge can be traversed without a load
/// </summary>
public bool? Unloaded { get; set; }
/// <summary>
/// Indicates if the edge can be traversed with a load
/// </summary>
public bool? Loaded { get; set; }
/// <summary>
/// Names of the load sets allowed on this edge (optional)
/// </summary>
public List<string>? LoadSetNames { get; set; }
}

View File

@@ -0,0 +1,23 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Layout;
/// <summary>
/// Layout data transfer object
/// </summary>
public class LayoutDto
{
public Guid Id { get; set; }
public string LayoutId { get; set; } = string.Empty;
public string LayoutName { get; set; } = string.Empty;
public string? Description { get; set; }
public bool IsActive { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string? CreatedBy { get; set; }
public string? ModifiedBy { get; set; }
/// <summary>
/// List of versions (optional, for detailed queries)
/// </summary>
public List<LayoutVersionDto>? Versions { get; set; }
}

View File

@@ -0,0 +1,20 @@
using RobotNet10.MapEditor.Shared.Models;
namespace RobotNet10.MapEditor.Shared.DTOs.Layout;
/// <summary>
/// Layout level data transfer object
/// </summary>
public class LayoutLevelDto
{
public Guid Id { get; set; }
public Guid VersionId { get; set; }
public string LayoutLevelId { get; set; } = string.Empty;
public int LevelOrder { get; set; }
/// <summary>
/// Editor settings including coordinate system
/// </summary>
public LayoutLevelEditorSettingsDto? EditorSettings { get; set; }
}

View File

@@ -0,0 +1,38 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Layout;
/// <summary>
/// Layout level editor settings data transfer object
/// </summary>
public class LayoutLevelEditorSettingsDto
{
public Guid Id { get; set; }
public Guid LevelId { get; set; }
// Edge Settings
public double EdgeMinLengthCreate { get; set; }
public bool EdgeNameAutoGenerate { get; set; }
// Node Settings
public bool NodeNameAutoGenerate { get; set; }
public double NodeProximityRadius { get; set; }
// Coordinate System
public double OriginX { get; set; }
public double OriginY { get; set; }
public double Resolution { get; set; }
// Coordinate Bounds
public double? BoundsMinX { get; set; }
public double? BoundsMaxX { get; set; }
public double? BoundsMinY { get; set; }
public double? BoundsMaxY { get; set; }
// Background Image
public double? ImageWidth { get; set; }
public double? ImageHeight { get; set; }
// Metadata
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}

View File

@@ -0,0 +1,21 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Layout;
/// <summary>
/// Layout version data transfer object
/// </summary>
public class LayoutVersionDto
{
public Guid Id { get; set; }
public Guid LayoutId { get; set; }
public string Version { get; set; } = string.Empty;
public string? LayoutDescription { get; set; }
public string? CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public bool IsActive { get; set; }
/// <summary>
/// List of levels (optional, for detailed queries)
/// </summary>
public List<LayoutLevelDto>? Levels { get; set; }
}

View File

@@ -0,0 +1,18 @@
using RobotNet10.MapEditor.Shared.DTOs.Edge;
using RobotNet10.MapEditor.Shared.DTOs.Node;
using RobotNet10.MapEditor.Shared.DTOs.Station;
namespace RobotNet10.MapEditor.Shared.DTOs.LayoutData;
/// <summary>
/// Complete layout data for a single layout level
/// Includes nodes, edges, and stations with all nested properties
/// </summary>
public class LayoutDataDto
{
public Guid LayoutLevelId { get; set; }
public List<NodeDto> Nodes { get; set; } = new();
public List<EdgeDto> Edges { get; set; } = new();
public List<StationDto> Stations { get; set; } = new();
}

View File

@@ -0,0 +1,30 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Node;
/// <summary>
/// Node data transfer object with full details including vehicle properties
/// </summary>
public class NodeDto
{
public Guid Id { get; set; }
public Guid LevelId { get; set; }
public string NodeId { get; set; } = string.Empty;
public string? NodeName { get; set; }
public string? NodeDescription { get; set; }
public string? MapId { get; set; }
/// <summary>
/// X coordinate in METERS
/// </summary>
public double X { get; set; }
/// <summary>
/// Y coordinate in METERS
/// </summary>
public double Y { get; set; }
/// <summary>
/// Vehicle-specific properties for this node
/// </summary>
public List<NodeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,44 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Node;
/// <summary>
/// Node vehicle property data transfer object
/// </summary>
public class NodeVehiclePropertyDto
{
public Guid Id { get; set; }
public Guid NodeId { get; set; }
public Guid VehicleTypeId { get; set; }
/// <summary>
/// Vehicle type identifier (for reference)
/// </summary>
public string? VehicleTypeIdString { get; set; }
/// <summary>
/// Theta orientation in radians (optional)
/// Range: [-Pi ... Pi]
/// </summary>
public double? Theta { get; set; }
/// <summary>
/// Actions as JSON array (VDMA LIF format)
/// </summary>
public string? Actions { get; set; }
/// <summary>
/// Allowed deviation radius in meters (VDA5050: allowedDeviationXY)
/// Indicates how exact an AGV has to drive over a node in order for it to count as traversed.
/// If = 0: no deviation is allowed.
/// If > 0: allowed deviation-radius in meters.
/// Minimum: 0
/// </summary>
public double? AllowedDeviationXY { get; set; }
/// <summary>
/// Allowed deviation of theta angle in radians (VDA5050: allowedDeviationTheta)
/// Indicates how big the deviation of theta angle can be.
/// Range: [0.0 ... 3.141592654] (0 to Pi)
/// </summary>
public double? AllowedDeviationTheta { get; set; }
}

View File

@@ -0,0 +1,34 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to copy selected nodes and edges with an offset
/// </summary>
public class CopyNodesRequest
{
/// <summary>
/// Layout level ID
/// </summary>
public Guid LayoutLevelId { get; set; }
/// <summary>
/// List of node IDs to copy
/// </summary>
public List<Guid> NodeIds { get; set; } = new();
/// <summary>
/// List of edge IDs to copy (only edges where both nodes are in NodeIds will be copied)
/// </summary>
public List<Guid> EdgeIds { get; set; } = new();
/// <summary>
/// Offset X in world coordinates (meters)
/// </summary>
public double OffsetX { get; set; }
/// <summary>
/// Offset Y in world coordinates (meters)
/// </summary>
public double OffsetY { get; set; }
}

View File

@@ -0,0 +1,50 @@
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new edge
/// Coordinates in METERS (world coordinates)
/// </summary>
public class CreateEdgeRequest
{
public Guid LayoutLevelId { get; set; }
/// <summary>
/// Start point X coordinate in METERS
/// </summary>
public double X1 { get; set; }
/// <summary>
/// Start point Y coordinate in METERS
/// </summary>
public double Y1 { get; set; }
/// <summary>
/// End point X coordinate in METERS
/// </summary>
public double X2 { get; set; }
/// <summary>
/// End point Y coordinate in METERS
/// </summary>
public double Y2 { get; set; }
/// <summary>
/// Optional edge name (if not provided, auto-generated)
/// </summary>
[System.ComponentModel.DataAnnotations.StringLength(256, ErrorMessage = "EdgeName must not exceed 256 characters")]
public string? EdgeName { get; set; }
/// <summary>
/// Optional edge description
/// </summary>
[System.ComponentModel.DataAnnotations.StringLength(10000, ErrorMessage = "EdgeDescription must not exceed 10000 characters")]
public string? EdgeDescription { get; set; }
/// <summary>
/// Optional vehicle properties for this edge
/// </summary>
public List<EdgeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using RobotNet10.MapEditor.Shared.Models;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new layout level
/// </summary>
public class CreateLayoutLevelRequest
{
[Required(ErrorMessage = "LayoutLevelId is required")]
[StringLength(64, ErrorMessage = "LayoutLevelId must not exceed 64 characters")]
public string LayoutLevelId { get; set; } = string.Empty;
public int LevelOrder { get; set; }
/// <summary>
/// Optional coordinate system configuration
/// If not provided, defaults will be used
/// </summary>
public CoordinateSystemInfo? CoordinateSystem { get; set; }
}

View File

@@ -0,0 +1,23 @@
using System.ComponentModel.DataAnnotations;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new layout
/// </summary>
public class CreateLayoutRequest
{
[Required(ErrorMessage = "LayoutId is required")]
[StringLength(64, ErrorMessage = "LayoutId must not exceed 64 characters")]
public string LayoutId { get; set; } = string.Empty;
[Required(ErrorMessage = "LayoutName is required")]
[StringLength(256, ErrorMessage = "LayoutName must not exceed 256 characters")]
public string LayoutName { get; set; } = string.Empty;
[StringLength(10000, ErrorMessage = "Description must not exceed 10000 characters")]
public string? Description { get; set; }
public string? CreatedBy { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new layout version
/// </summary>
public class CreateLayoutVersionRequest
{
public string Version { get; set; } = string.Empty;
public string? LayoutDescription { get; set; }
public string? CreatedBy { get; set; }
}

View File

@@ -0,0 +1,43 @@
using System.ComponentModel.DataAnnotations;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new station
/// </summary>
public class CreateStationRequest
{
public Guid LayoutLevelId { get; set; }
[Required(ErrorMessage = "StationId is required")]
[StringLength(64, ErrorMessage = "StationId must not exceed 64 characters")]
public string StationId { get; set; } = string.Empty;
[StringLength(256, ErrorMessage = "StationName must not exceed 256 characters")]
public string? StationName { get; set; }
[StringLength(10000, ErrorMessage = "StationDescription must not exceed 10000 characters")]
public string? StationDescription { get; set; }
public double? StationHeight { get; set; }
/// <summary>
/// X coordinate in METERS
/// </summary>
public double X { get; set; }
/// <summary>
/// Y coordinate in METERS
/// </summary>
public double Y { get; set; }
/// <summary>
/// Theta orientation in radians (optional)
/// </summary>
public double? Theta { get; set; }
/// <summary>
/// Node IDs to link as interaction nodes
/// </summary>
public List<Guid>? InteractionNodeIds { get; set; }
}

View File

@@ -0,0 +1,42 @@
using System.ComponentModel.DataAnnotations;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to create a new vehicle type
/// </summary>
public class CreateVehicleTypeRequest
{
[Required(ErrorMessage = "VehicleTypeId is required")]
[StringLength(64, ErrorMessage = "VehicleTypeId must not exceed 64 characters")]
[RegularExpression(@"^[a-zA-Z0-9\-_]+$",
ErrorMessage = "VehicleTypeId must contain only alphanumeric characters, hyphens, and underscores")]
public string VehicleTypeId { get; set; } = string.Empty;
[Required(ErrorMessage = "VehicleTypeName is required")]
[StringLength(256, ErrorMessage = "VehicleTypeName must not exceed 256 characters")]
public string VehicleTypeName { get; set; } = string.Empty;
[MaxLength(10000, ErrorMessage = "Description must not exceed 10000 characters")]
public string? Description { get; set; }
[MaxLength(50000, ErrorMessage = "Specifications must not exceed 50000 characters")]
public string? Specifications { get; set; }
/// <summary>
/// Actions default that vehicle can perform (VDMA LIF: actions)
/// JSON array format:
/// [
/// {
/// "actionType": "pick",
/// "actionDescription": "...",
/// "requirementType": "REQUIRED", // Enum: REQUIRED, CONDITIONAL, OPTIONAL
/// "blockingType": "HARD",
/// "actionParameters": [{"key": "...", "value": "..."}]
/// }
/// ]
/// </summary>
[MaxLength(50000, ErrorMessage = "Actions must not exceed 50000 characters")]
public string? Actions { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to delete multiple edges in a transaction
/// </summary>
public class DeleteEdgesRequest
{
public List<Guid> EdgeIds { get; set; } = new();
}

View File

@@ -0,0 +1,28 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to merge multiple nodes into one
/// </summary>
public class MergeNodesRequest
{
public Guid LevelId { get; set; }
/// <summary>
/// List of node IDs to merge
/// </summary>
public List<Guid> NodeIds { get; set; } = new();
/// <summary>
/// Optional: Specify center position for merged node
/// If not provided, will calculate center from nodes
/// </summary>
public double? CenterX { get; set; }
/// <summary>
/// Optional: Specify center position for merged node
/// If not provided, will calculate center from nodes
/// </summary>
public double? CenterY { get; set; }
}

View File

@@ -0,0 +1,52 @@
using RobotNet10.MapEditor.Shared.DTOs.Node;
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to save all layout changes (nodes and edges) in a batch operation
/// </summary>
public class SaveLayoutDataRequest
{
/// <summary>
/// Layout level ID
/// </summary>
public Guid LayoutLevelId { get; set; }
/// <summary>
/// Nodes to update (only modified nodes should be included)
/// </summary>
public List<NodeUpdateItem> Nodes { get; set; } = new();
/// <summary>
/// Edges to update (only modified edges should be included)
/// </summary>
public List<EdgeUpdateItem> Edges { get; set; } = new();
}
/// <summary>
/// Node update item for batch save
/// </summary>
public class NodeUpdateItem
{
public Guid Id { get; set; }
public double? X { get; set; }
public double? Y { get; set; }
public string? NodeName { get; set; }
public string? NodeDescription { get; set; }
public string? MapId { get; set; }
public List<NodeVehiclePropertyDto>? VehicleProperties { get; set; }
}
/// <summary>
/// Edge update item for batch save
/// </summary>
public class EdgeUpdateItem
{
public Guid Id { get; set; }
public string? EdgeName { get; set; }
public string? EdgeDescription { get; set; }
public List<EdgeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,28 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to split a node into multiple nodes
/// </summary>
public class SplitNodeRequest
{
public Guid LevelId { get; set; }
/// <summary>
/// Node ID to split
/// </summary>
public Guid NodeId { get; set; }
/// <summary>
/// Optional: Offset distance for new nodes (in meters)
/// Default: 0.1m (10cm)
/// </summary>
public double? OffsetDistance { get; set; }
/// <summary>
/// Optional: Node ID to assign station to (if original node had station)
/// If not provided, station will be assigned to first new node
/// </summary>
public Guid? StationNodeId { get; set; }
}

View File

@@ -0,0 +1,18 @@
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update an existing edge
/// </summary>
public class UpdateEdgeRequest
{
public string? EdgeName { get; set; }
public string? EdgeDescription { get; set; }
/// <summary>
/// Updated vehicle properties (replaces existing)
/// </summary>
public List<EdgeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,23 @@
using RobotNet10.MapEditor.Shared.Models;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update a layout level
/// </summary>
public class UpdateLayoutLevelRequest
{
public string? LayoutLevelId { get; set; }
public int? LevelOrder { get; set; }
/// <summary>
/// Optional coordinate system configuration update
/// </summary>
public CoordinateSystemInfo? CoordinateSystem { get; set; }
/// <summary>
/// Optional editor settings configuration update
/// </summary>
public EditorSettingsInfo? EditorSettings { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update an existing layout
/// </summary>
public class UpdateLayoutRequest
{
public string LayoutName { get; set; } = string.Empty;
public string? Description { get; set; }
public string? ModifiedBy { get; set; }
}

View File

@@ -0,0 +1,21 @@
using RobotNet10.MapEditor.Shared.DTOs.Node;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update an existing node
/// </summary>
public class UpdateNodeRequest
{
public double? X { get; set; }
public double? Y { get; set; }
public string? NodeName { get; set; }
public string? NodeDescription { get; set; }
public string? MapId { get; set; }
/// <summary>
/// Updated vehicle properties (replaces existing)
/// </summary>
public List<NodeVehiclePropertyDto>? VehicleProperties { get; set; }
}

View File

@@ -0,0 +1,20 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update an existing station
/// </summary>
public class UpdateStationRequest
{
public string? StationName { get; set; }
public string? StationDescription { get; set; }
public double? StationHeight { get; set; }
public double? X { get; set; }
public double? Y { get; set; }
public double? Theta { get; set; }
/// <summary>
/// Updated interaction node IDs (replaces existing links)
/// </summary>
public List<Guid>? InteractionNodeIds { get; set; }
}

View File

@@ -0,0 +1,37 @@
using System.ComponentModel.DataAnnotations;
namespace RobotNet10.MapEditor.Shared.DTOs.Requests;
/// <summary>
/// Request to update an existing vehicle type
/// </summary>
public class UpdateVehicleTypeRequest
{
[StringLength(256, ErrorMessage = "VehicleTypeName must not exceed 256 characters")]
public string? VehicleTypeName { get; set; }
[MaxLength(10000, ErrorMessage = "Description must not exceed 10000 characters")]
public string? Description { get; set; }
[MaxLength(50000, ErrorMessage = "Specifications must not exceed 50000 characters")]
public string? Specifications { get; set; }
/// <summary>
/// Actions default that vehicle can perform (VDMA LIF: actions)
/// JSON array format:
/// [
/// {
/// "actionType": "pick",
/// "actionDescription": "...",
/// "requirementType": "REQUIRED", // Enum: REQUIRED, CONDITIONAL, OPTIONAL
/// "blockingType": "HARD",
/// "actionParameters": [{"key": "...", "value": "..."}]
/// }
/// ]
/// </summary>
[MaxLength(50000, ErrorMessage = "Actions must not exceed 50000 characters")]
public string? Actions { get; set; }
public bool? IsActive { get; set; }
}

View File

@@ -0,0 +1,37 @@
using RobotNet10.MapEditor.Shared.DTOs.Node;
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Responses;
/// <summary>
/// Response from copy nodes operation
/// </summary>
public class CopyNodesResponse
{
/// <summary>
/// Whether the copy operation was successful
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Error message if copy failed
/// </summary>
public string? ErrorMessage { get; set; }
/// <summary>
/// Newly created nodes
/// </summary>
public List<NodeDto> NewNodes { get; set; } = new();
/// <summary>
/// Newly created edges
/// </summary>
public List<EdgeDto> NewEdges { get; set; } = new();
/// <summary>
/// Mapping from original node ID to new node ID
/// </summary>
public Dictionary<Guid, Guid> NodeIdMapping { get; set; } = new();
}

View File

@@ -0,0 +1,25 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Responses;
/// <summary>
/// Standard error response DTO
/// </summary>
public class ErrorResponseDto
{
/// <summary>
/// Error message
/// </summary>
public string Error { get; set; } = string.Empty;
/// <summary>
/// Error code for programmatic handling
/// </summary>
public string? ErrorCode { get; set; }
/// <summary>
/// Additional error details
/// </summary>
public Dictionary<string, object>? Details { get; set; }
}

View File

@@ -0,0 +1,27 @@
using RobotNet10.MapEditor.Shared.DTOs.Node;
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Responses;
/// <summary>
/// Response from merge nodes operation
/// </summary>
public class MergeNodesResponse
{
/// <summary>
/// The newly created merged node
/// </summary>
public NodeDto MergedNode { get; set; } = null!;
/// <summary>
/// List of edges that were updated (StartNodeId or EndNodeId changed)
/// </summary>
public List<EdgeDto> UpdatedEdges { get; set; } = new();
/// <summary>
/// List of node IDs that were deleted (original nodes)
/// </summary>
public List<Guid> DeletedNodeIds { get; set; } = new();
}

View File

@@ -0,0 +1,39 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Responses;
/// <summary>
/// Response from batch save operation
/// </summary>
public class SaveLayoutDataResponse
{
/// <summary>
/// Whether the save operation was successful
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Error message if save failed
/// </summary>
public string? ErrorMessage { get; set; }
/// <summary>
/// Number of nodes updated
/// </summary>
public int NodesUpdated { get; set; }
/// <summary>
/// Number of edges updated
/// </summary>
public int EdgesUpdated { get; set; }
/// <summary>
/// List of node IDs that were not found (skipped)
/// </summary>
public List<Guid> SkippedNodeIds { get; set; } = new();
/// <summary>
/// List of edge IDs that were not found (skipped)
/// </summary>
public List<Guid> SkippedEdgeIds { get; set; } = new();
}

View File

@@ -0,0 +1,27 @@
using RobotNet10.MapEditor.Shared.DTOs.Node;
using RobotNet10.MapEditor.Shared.DTOs.Edge;
namespace RobotNet10.MapEditor.Shared.DTOs.Responses;
/// <summary>
/// Response from split node operation
/// </summary>
public class SplitNodeResponse
{
/// <summary>
/// List of newly created nodes (one for each connected edge)
/// </summary>
public List<NodeDto> NewNodes { get; set; } = new();
/// <summary>
/// List of edges that were updated (StartNodeId or EndNodeId changed)
/// </summary>
public List<EdgeDto> UpdatedEdges { get; set; } = new();
/// <summary>
/// ID of the original node that was split (now deleted)
/// </summary>
public Guid DeletedNodeId { get; set; }
}

View File

@@ -0,0 +1,35 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Station;
/// <summary>
/// Station data transfer object with full details including interaction nodes
/// </summary>
public class StationDto
{
public Guid Id { get; set; }
public Guid LevelId { get; set; }
public string StationId { get; set; } = string.Empty;
public string? StationName { get; set; }
public string? StationDescription { get; set; }
public double? StationHeight { get; set; }
/// <summary>
/// X coordinate in METERS
/// </summary>
public double X { get; set; }
/// <summary>
/// Y coordinate in METERS
/// </summary>
public double Y { get; set; }
/// <summary>
/// Theta orientation in radians (optional)
/// </summary>
public double? Theta { get; set; }
/// <summary>
/// Interaction nodes linked to this station
/// </summary>
public List<StationInteractionNodeDto>? InteractionNodes { get; set; }
}

View File

@@ -0,0 +1,17 @@
namespace RobotNet10.MapEditor.Shared.DTOs.Station;
/// <summary>
/// Station interaction node data transfer object
/// </summary>
public class StationInteractionNodeDto
{
public Guid Id { get; set; }
public Guid StationId { get; set; }
public Guid NodeId { get; set; }
/// <summary>
/// Node details (for convenience)
/// </summary>
public Node.NodeDto? Node { get; set; }
}

View File

@@ -0,0 +1,49 @@
using RobotNet.VDA5050.Type;
using System.Text.Json.Serialization;
namespace RobotNet10.MapEditor.Shared.DTOs.VehicleType;
/// <summary>
/// Action data transfer object for VDMA LIF actions
/// Used in VehicleType.Actions, NodeVehicleProperty.Actions, EdgeVehicleProperty.Actions
/// </summary>
public class ActionDto
{
/// <summary>
/// Type of action (e.g., "pick", "drop", "charge")
/// </summary>
public string ActionType { get; set; } = string.Empty;
/// <summary>
/// Description of the action
/// </summary>
public string? ActionDescription { get; set; }
/// <summary>
/// Requirement type: REQUIRED, CONDITIONAL, OPTIONAL
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public RequirementType RequirementType { get; set; }
/// <summary>
/// Blocking type: NONE, SOFT, HARD
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public BlockingType BlockingType { get; set; }
/// <summary>
/// Action parameters as key-value pairs
/// </summary>
public List<ActionParameterDto> ActionParameters { get; set; } = [];
}
/// <summary>
/// Action parameter key-value pair
/// </summary>
public class ActionParameterDto
{
public string Key { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
}

View File

@@ -0,0 +1,37 @@
namespace RobotNet10.MapEditor.Shared.DTOs.VehicleType;
/// <summary>
/// Vehicle type data transfer object
/// </summary>
public class VehicleTypeDto
{
public Guid Id { get; set; }
public string VehicleTypeId { get; set; } = string.Empty;
public string VehicleTypeName { get; set; } = string.Empty;
public string? Description { get; set; }
/// <summary>
/// Specifications as JSON
/// Physical specs, capabilities, etc.
/// </summary>
public string? Specifications { get; set; }
/// <summary>
/// Actions default that vehicle can perform (VDMA LIF: actions)
/// JSON array format:
/// [
/// {
/// "actionType": "pick",
/// "actionDescription": "...",
/// "requirementType": "REQUIRED", // Enum: REQUIRED, CONDITIONAL, OPTIONAL (RequirementType enum)
/// "blockingType": "HARD",
/// "actionParameters": [{"key": "...", "value": "..."}]
/// }
/// ]
/// </summary>
public string? Actions { get; set; }
public bool IsActive { get; set; }
public DateTime CreatedDate { get; set; }
}

View File

@@ -0,0 +1,46 @@
namespace RobotNet10.MapEditor.Shared.DTOs.VehicleType;
/// <summary>
/// Vehicle type usage information DTO
/// Provides information about how a vehicle type is being used in the system
/// </summary>
public class VehicleTypeUsageInfoDto
{
/// <summary>
/// Vehicle type database ID
/// </summary>
public Guid VehicleTypeId { get; set; }
/// <summary>
/// Vehicle type identifier string
/// </summary>
public string VehicleTypeIdString { get; set; } = string.Empty;
/// <summary>
/// Vehicle type name
/// </summary>
public string VehicleTypeName { get; set; } = string.Empty;
/// <summary>
/// Number of node properties using this vehicle type
/// </summary>
public int NodePropertiesCount { get; set; }
/// <summary>
/// Number of edge properties using this vehicle type
/// </summary>
public int EdgePropertiesCount { get; set; }
/// <summary>
/// Total usage count (NodePropertiesCount + EdgePropertiesCount)
/// </summary>
public int TotalUsageCount { get; set; }
/// <summary>
/// Whether this vehicle type can be deleted (no references)
/// </summary>
public bool CanDelete { get; set; }
}