initial commit
This commit is contained in:
41
backend/Domain/Entities/AmsSlot.cs
Normal file
41
backend/Domain/Entities/AmsSlot.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single slot within an AMS unit. Each slot can hold one spool
|
||||
/// and tracks the tray index, remaining weight, and which spool is loaded.
|
||||
/// </summary>
|
||||
public class AmsSlot : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// The 1-based tray/slot index within the AMS unit (1-4 per unit).
|
||||
/// </summary>
|
||||
public int TrayIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the AMS unit this slot belongs to.
|
||||
/// </summary>
|
||||
public Guid AmsUnitId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the parent AMS unit.
|
||||
/// </summary>
|
||||
public AmsUnit AmsUnit { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the spool currently loaded in this slot. Null if empty.
|
||||
/// </summary>
|
||||
public Guid? SpoolId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the spool currently loaded in this slot. Null if no spool is loaded.
|
||||
/// </summary>
|
||||
public Spool? Spool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Remaining filament weight in grams as reported by the AMS.
|
||||
/// Bambu Lab AMS reports remaining weight per tray.
|
||||
/// </summary>
|
||||
public decimal? RemainingWeightG { get; set; }
|
||||
}
|
||||
30
backend/Domain/Entities/AmsUnit.cs
Normal file
30
backend/Domain/Entities/AmsUnit.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an AMS (Automatic Material System) unit installed on a Bambu Lab printer.
|
||||
/// Each AMS unit contains multiple slots that hold spools.
|
||||
/// </summary>
|
||||
public class AmsUnit : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// The 1-based index of this AMS unit on the printer (e.g., AMS 1, AMS 2).
|
||||
/// </summary>
|
||||
public int UnitIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the parent Printer this AMS unit is installed on.
|
||||
/// </summary>
|
||||
public Guid PrinterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the parent Printer.
|
||||
/// </summary>
|
||||
public Printer Printer { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of slots in this AMS unit.
|
||||
/// </summary>
|
||||
public ICollection<AmsSlot> Slots { get; set; } = new List<AmsSlot>();
|
||||
}
|
||||
36
backend/Domain/Entities/MaterialBase.cs
Normal file
36
backend/Domain/Entities/MaterialBase.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Base polymer/material type. This is a lookup table enforcing consistent
|
||||
/// material naming across all spools. Free-text material names are not allowed.
|
||||
/// </summary>
|
||||
public class MaterialBase : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Human-readable name of the base material (e.g., "PLA", "PETG", "ABS").
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Density of the material in g/cm³ (g/mL). Used for deriving grams consumed
|
||||
/// from mm extruded: grams = mm × cross_section_area × density.
|
||||
/// </summary>
|
||||
public decimal DensityGperCm3 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of finishes available for this material base.
|
||||
/// </summary>
|
||||
public ICollection<MaterialFinish> Finishes { get; set; } = new List<MaterialFinish>();
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of modifiers applicable to this material base.
|
||||
/// </summary>
|
||||
public ICollection<MaterialModifier> Modifiers { get; set; } = new List<MaterialModifier>();
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of spools made from this material base.
|
||||
/// </summary>
|
||||
public ICollection<Spool> Spools { get; set; } = new List<Spool>();
|
||||
}
|
||||
30
backend/Domain/Entities/MaterialFinish.cs
Normal file
30
backend/Domain/Entities/MaterialFinish.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Surface finish descriptor for a material. This is REQUIRED on every spool
|
||||
/// record. The default value is "Basic" (not "Standard").
|
||||
/// </summary>
|
||||
public class MaterialFinish : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Human-readable name of the finish (e.g., "Basic", "Matte", "Silk", "Glitter").
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the parent MaterialBase. A finish belongs to exactly one base material.
|
||||
/// </summary>
|
||||
public Guid MaterialBaseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the parent MaterialBase.
|
||||
/// </summary>
|
||||
public MaterialBase MaterialBase { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of spools with this finish.
|
||||
/// </summary>
|
||||
public ICollection<Spool> Spools { get; set; } = new List<Spool>();
|
||||
}
|
||||
30
backend/Domain/Entities/MaterialModifier.cs
Normal file
30
backend/Domain/Entities/MaterialModifier.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Optional modifier/additive for a material (e.g., "Carbon Fiber", "Glass Fiber",
|
||||
/// "Wood Fill", "Glow-in-the-Dark"). Not every spool has a modifier.
|
||||
/// </summary>
|
||||
public class MaterialModifier : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Human-readable name of the modifier (e.g., "Carbon Fiber", "Wood Fill").
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the parent MaterialBase. A modifier belongs to exactly one base material.
|
||||
/// </summary>
|
||||
public Guid MaterialBaseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the parent MaterialBase.
|
||||
/// </summary>
|
||||
public MaterialBase MaterialBase { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of spools with this modifier.
|
||||
/// </summary>
|
||||
public ICollection<Spool> Spools { get; set; } = new List<Spool>();
|
||||
}
|
||||
100
backend/Domain/Entities/PrintJob.cs
Normal file
100
backend/Domain/Entities/PrintJob.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using Extrudex.Domain.Base;
|
||||
using Extrudex.Domain.Enums;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single print job. Tracks which printer and spool were used,
|
||||
/// how much filament was consumed, and audit snapshots of material properties
|
||||
/// at the time of printing (to preserve COGS accuracy even if material data
|
||||
/// changes later).
|
||||
/// </summary>
|
||||
public class PrintJob : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Foreign key to the printer that executed this print job.
|
||||
/// </summary>
|
||||
public Guid PrinterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the printer that executed this print job.
|
||||
/// </summary>
|
||||
public Printer Printer { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the spool that provided filament for this print job.
|
||||
/// </summary>
|
||||
public Guid SpoolId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the spool that provided filament for this print job.
|
||||
/// </summary>
|
||||
public Spool Spool { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable name or identifier for the print job.
|
||||
/// </summary>
|
||||
public string PrintName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Path or filename of the G-code file being printed.
|
||||
/// </summary>
|
||||
public string? GcodeFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total millimeters of filament extruded during this print job.
|
||||
/// The primary input to the COGS derivation formula.
|
||||
/// </summary>
|
||||
public decimal MmExtruded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Derived grams consumed for this print, calculated as:
|
||||
/// mm_extruded × cross_section_area × material_density_at_print.
|
||||
/// </summary>
|
||||
public decimal GramsDerived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calculated cost of goods sold (COGS) for this print job.
|
||||
/// Derived from grams consumed and the spool's purchase price.
|
||||
/// </summary>
|
||||
public decimal? CostPerPrint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp when the print job started (UTC).
|
||||
/// </summary>
|
||||
public DateTime? StartedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp when the print job completed or failed (UTC).
|
||||
/// </summary>
|
||||
public DateTime? CompletedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current status of the print job.
|
||||
/// </summary>
|
||||
public JobStatus Status { get; set; } = JobStatus.Queued;
|
||||
|
||||
/// <summary>
|
||||
/// The source of the print job data (which integration path provided it).
|
||||
/// </summary>
|
||||
public DataSource DataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Audit snapshot: the filament diameter (mm) recorded at the time of printing.
|
||||
/// Preserved so COGS calculations remain accurate even if the spool's
|
||||
/// diameter is later corrected.
|
||||
/// </summary>
|
||||
public decimal FilamentDiameterAtPrintMm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Audit snapshot: the material density (g/cm³) recorded at the time of printing.
|
||||
/// Preserved so COGS calculations remain accurate even if the material's
|
||||
/// density is later corrected.
|
||||
/// </summary>
|
||||
public decimal MaterialDensityAtPrint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional notes about the print job (e.g., "First layer adhesion issues").
|
||||
/// </summary>
|
||||
public string? Notes { get; set; }
|
||||
}
|
||||
97
backend/Domain/Entities/Printer.cs
Normal file
97
backend/Domain/Entities/Printer.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using Extrudex.Domain.Base;
|
||||
using Extrudex.Domain.Enums;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a 3D printer in the fleet. Stores connection details for
|
||||
/// MQTT (Bambu Lab) or Moonraker (Elegoo Centauri Carbon) integration.
|
||||
/// </summary>
|
||||
public class Printer : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Current operational status of the printer, updated via real-time telemetry.
|
||||
/// </summary>
|
||||
public PrinterStatus Status { get; set; } = PrinterStatus.Offline;
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable name for the printer (e.g., "Bambu X1C #1", "Elegoo Centauri").
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Manufacturer/brand of the printer (e.g., "Bambu Lab", "Elegoo").
|
||||
/// </summary>
|
||||
public string Manufacturer { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Model name (e.g., "X1 Carbon", "Centauri Carbon").
|
||||
/// </summary>
|
||||
public string Model { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The hardware type of the printer (FDM or Resin).
|
||||
/// </summary>
|
||||
public PrinterType PrinterType { get; set; } = PrinterType.Fdm;
|
||||
|
||||
/// <summary>
|
||||
/// The connectivity protocol used by this printer (MQTT or Moonraker).
|
||||
/// </summary>
|
||||
public ConnectionType ConnectionType { get; set; } = ConnectionType.Mqtt;
|
||||
|
||||
/// <summary>
|
||||
/// Hostname or IP address for connecting to the printer.
|
||||
/// </summary>
|
||||
public string HostnameOrIp { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Port number for the printer connection. Defaults: 8883 (MQTT/TLS), 7125 (Moonraker).
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MQTT username for Bambu Lab printer authentication.
|
||||
/// Stored only for MQTT connection type printers.
|
||||
/// </summary>
|
||||
public string MqttUsername { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// MQTT password for Bambu Lab printer authentication.
|
||||
/// Stored only for MQTT connection type printers.
|
||||
/// </summary>
|
||||
public string MqttPassword { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use TLS for the MQTT connection. Bambu Lab printers
|
||||
/// require TLS on port 8883.
|
||||
/// </summary>
|
||||
public bool MqttUseTls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Moonraker API key for Elegoo Centauri Carbon authentication.
|
||||
/// Stored only for Moonraker connection type printers.
|
||||
/// </summary>
|
||||
public string ApiKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this printer is currently active and available for print jobs.
|
||||
/// Inactive printers are retained for historical records.
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp of the last status update received from the printer (UTC).
|
||||
/// Used to detect stale connections.
|
||||
/// </summary>
|
||||
public DateTime? LastSeenAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of AMS units installed on this printer.
|
||||
/// </summary>
|
||||
public ICollection<AmsUnit> AmsUnits { get; set; } = new List<AmsUnit>();
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of print jobs executed on this printer.
|
||||
/// </summary>
|
||||
public ICollection<PrintJob> PrintJobs { get; set; } = new List<PrintJob>();
|
||||
}
|
||||
105
backend/Domain/Entities/Spool.cs
Normal file
105
backend/Domain/Entities/Spool.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using Extrudex.Domain.Base;
|
||||
|
||||
namespace Extrudex.Domain.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a physical spool of filament. Every spool must have a MaterialBase
|
||||
/// and MaterialFinish. MaterialModifier is optional.
|
||||
/// Spools are the core inventory unit and link to PrintJobs for COGS tracking.
|
||||
/// </summary>
|
||||
public class Spool : AuditableEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Foreign key to the base material. Every spool must specify a material base.
|
||||
/// </summary>
|
||||
public Guid MaterialBaseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the base material (e.g., PLA, PETG, ABS).
|
||||
/// </summary>
|
||||
public MaterialBase MaterialBase { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the material finish. REQUIRED on every spool — default is "Basic".
|
||||
/// </summary>
|
||||
public Guid MaterialFinishId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the material finish (e.g., Basic, Matte, Silk, Glitter).
|
||||
/// </summary>
|
||||
public MaterialFinish MaterialFinish { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Foreign key to the optional material modifier. Null if no modifier applies.
|
||||
/// </summary>
|
||||
public Guid? MaterialModifierId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Navigation to the optional material modifier (e.g., Carbon Fiber, Wood Fill).
|
||||
/// </summary>
|
||||
public MaterialModifier? MaterialModifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable brand name (e.g., "Bambu Lab", "Polymaker", "eSUN").
|
||||
/// </summary>
|
||||
public string Brand { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable color name (e.g., "Fire Engine Red", "Galaxy Black").
|
||||
/// </summary>
|
||||
public string ColorName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Hex color code for the filament (e.g., "#FF0000" for red).
|
||||
/// Enables color-based filtering and visual identification.
|
||||
/// </summary>
|
||||
public string ColorHex { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Total spool weight in grams when full (brand new, unopened).
|
||||
/// </summary>
|
||||
public decimal WeightTotalGrams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current remaining weight in grams. Updated via AMS data or manual check-in.
|
||||
/// </summary>
|
||||
public decimal WeightRemainingGrams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Filament diameter in millimeters. Typically 1.75mm for FDM printers.
|
||||
/// Used in the COGS derivation formula: grams = mm × cross_section_area × density.
|
||||
/// </summary>
|
||||
public decimal FilamentDiameterMm { get; set; } = 1.75m;
|
||||
|
||||
/// <summary>
|
||||
/// Manufacturer-assigned serial number for the spool. Used for barcode/QR scanning.
|
||||
/// Must be unique across all spools.
|
||||
/// </summary>
|
||||
public string SpoolSerial { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Purchase price per spool in the system currency. Used for COGS calculations.
|
||||
/// </summary>
|
||||
public decimal? PurchasePrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date the spool was purchased or received.
|
||||
/// </summary>
|
||||
public DateTime? PurchaseDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the spool is currently active and available for use.
|
||||
/// Inactive spools are retained for historical COGS records.
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of AMS slots where this spool is loaded.
|
||||
/// </summary>
|
||||
public ICollection<AmsSlot> AmsSlots { get; set; } = new List<AmsSlot>();
|
||||
|
||||
/// <summary>
|
||||
/// Navigation collection of print jobs that consumed filament from this spool.
|
||||
/// </summary>
|
||||
public ICollection<PrintJob> PrintJobs { get; set; } = new List<PrintJob>();
|
||||
}
|
||||
Reference in New Issue
Block a user