Compare commits
8 Commits
main
...
42e90f028a
| Author | SHA1 | Date | |
|---|---|---|---|
| 42e90f028a | |||
| 7d0369b8e9 | |||
| ff1fb621d7 | |||
| c8ac1fa283 | |||
|
|
4172e21fd1 | ||
|
|
c3def21220 | ||
|
|
458fc9a4e1 | ||
|
|
a0cdacc7be |
77
.gitea/workflows/dev.yml
Normal file
77
.gitea/workflows/dev.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
name: Dev Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [dev]
|
||||||
|
push:
|
||||||
|
branches: [dev]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: '9.0.x'
|
||||||
|
|
||||||
|
- name: Restore backend
|
||||||
|
run: dotnet restore
|
||||||
|
|
||||||
|
- name: Build backend
|
||||||
|
run: dotnet build --no-restore --configuration Release
|
||||||
|
|
||||||
|
- name: Test backend
|
||||||
|
run: dotnet test --no-build --configuration Release
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "24"
|
||||||
|
|
||||||
|
- name: Install frontend deps
|
||||||
|
run: npm ci
|
||||||
|
working-directory: ./frontend
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: npm run build
|
||||||
|
working-directory: ./frontend
|
||||||
|
|
||||||
|
deploy-dev:
|
||||||
|
needs: build-test
|
||||||
|
if: gitea.event_name == 'push'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Deploy dev
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.DEV_DEPLOY_SSH_KEY }}" > /tmp/dev_key
|
||||||
|
chmod 600 /tmp/dev_key
|
||||||
|
ssh -i /tmp/dev_key -o StrictHostKeyChecking=no \
|
||||||
|
${{ secrets.DEV_DEPLOY_USER }}@${{ secrets.DEV_DEPLOY_HOST }} \
|
||||||
|
"${{ secrets.DEV_DEPLOY_PATH }}/deploy.sh"
|
||||||
|
|
||||||
|
notify-success:
|
||||||
|
needs: [build-test, deploy-dev]
|
||||||
|
if: success() && gitea.event_name == 'push'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify Slack success
|
||||||
|
run: |
|
||||||
|
curl -X POST -H 'Content-type: application/json' \
|
||||||
|
--data "{\"text\":\"✅ Extrudex dev deployed successfully from dev branch.\"}" \
|
||||||
|
"${{ secrets.SLACK_WEBHOOK_URL }}"
|
||||||
|
|
||||||
|
notify-failure:
|
||||||
|
needs: [build-test, deploy-dev]
|
||||||
|
if: failure()
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify Slack failure
|
||||||
|
run: |
|
||||||
|
curl -X POST -H 'Content-type: application/json' \
|
||||||
|
--data "{\"text\":\"🚨 Extrudex dev pipeline failed. Check Gitea Actions for details.\"}" \
|
||||||
|
"${{ secrets.SLACK_WEBHOOK_URL }}"
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,3 +3,8 @@ obj/
|
|||||||
*.user
|
*.user
|
||||||
*.suo
|
*.suo
|
||||||
.vs/
|
.vs/
|
||||||
|
|
||||||
|
# Frontend build artifacts
|
||||||
|
frontend/dist/
|
||||||
|
frontend/node_modules/
|
||||||
|
frontend/.angular/
|
||||||
27
backend/.dockerignore
Normal file
27
backend/.dockerignore
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Build artifacts
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
|
||||||
|
# IDE / editor
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Environment & secrets
|
||||||
|
appsettings.Development.json
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
*.md
|
||||||
|
*.log
|
||||||
117
backend/API/Controllers/UsageLogsController.cs
Normal file
117
backend/API/Controllers/UsageLogsController.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using Extrudex.API.DTOs.UsageLogs;
|
||||||
|
using Extrudex.Domain.Enums;
|
||||||
|
using Extrudex.Domain.Interfaces;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Extrudex.API.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API controller for recording and querying filament usage logs.
|
||||||
|
/// Usage logs provide a fine-grained audit trail of filament consumption
|
||||||
|
/// from printer integrations or manual input.
|
||||||
|
/// </summary>
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public class UsageLogsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IUsageLogService _usageLogService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="UsageLogsController"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="usageLogService">The usage log service for recording and querying usage.</param>
|
||||||
|
public UsageLogsController(IUsageLogService usageLogService)
|
||||||
|
{
|
||||||
|
_usageLogService = usageLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Records a new filament usage entry.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">The usage entry details.</param>
|
||||||
|
/// <returns>The created usage log entry.</returns>
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(UsageLogResponse), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<UsageLogResponse>> Create([FromBody] CreateUsageLogRequest request)
|
||||||
|
{
|
||||||
|
if (!Enum.TryParse<DataSource>(request.DataSource, ignoreCase: true, out var dataSource))
|
||||||
|
{
|
||||||
|
return BadRequest($"Invalid data source: '{request.DataSource}'. Valid values: Mqtt, Moonraker, Manual.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry = await _usageLogService.RecordUsageAsync(
|
||||||
|
spoolId: request.SpoolId,
|
||||||
|
gramsUsed: request.GramsUsed,
|
||||||
|
dataSource: dataSource,
|
||||||
|
printerId: request.PrinterId,
|
||||||
|
printJobId: request.PrintJobId,
|
||||||
|
mmExtruded: request.MmExtruded,
|
||||||
|
usageTimestamp: request.UsageTimestamp,
|
||||||
|
notes: request.Notes
|
||||||
|
);
|
||||||
|
|
||||||
|
return CreatedAtAction(
|
||||||
|
nameof(GetBySpool),
|
||||||
|
new { spoolId = entry.SpoolId },
|
||||||
|
MapToResponse(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets usage logs for a specific spool, ordered by most recent first.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spoolId">The spool ID to filter by.</param>
|
||||||
|
/// <returns>A collection of usage log entries for the spool.</returns>
|
||||||
|
[HttpGet("spool/{spoolId:guid}")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<UsageLogResponse>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<IEnumerable<UsageLogResponse>>> GetBySpool(Guid spoolId)
|
||||||
|
{
|
||||||
|
var logs = await _usageLogService.GetBySpoolAsync(spoolId);
|
||||||
|
return Ok(logs.Select(MapToResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets usage logs for a specific printer, ordered by most recent first.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="printerId">The printer ID to filter by.</param>
|
||||||
|
/// <returns>A collection of usage log entries for the printer.</returns>
|
||||||
|
[HttpGet("printer/{printerId:guid}")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<UsageLogResponse>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<IEnumerable<UsageLogResponse>>> GetByPrinter(Guid printerId)
|
||||||
|
{
|
||||||
|
var logs = await _usageLogService.GetByPrinterAsync(printerId);
|
||||||
|
return Ok(logs.Select(MapToResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets usage logs for a specific print job, ordered by most recent first.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="printJobId">The print job ID to filter by.</param>
|
||||||
|
/// <returns>A collection of usage log entries for the print job.</returns>
|
||||||
|
[HttpGet("print-job/{printJobId:guid}")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<UsageLogResponse>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult<IEnumerable<UsageLogResponse>>> GetByPrintJob(Guid printJobId)
|
||||||
|
{
|
||||||
|
var logs = await _usageLogService.GetByPrintJobAsync(printJobId);
|
||||||
|
return Ok(logs.Select(MapToResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps a UsageLog domain entity to a UsageLogResponse DTO.
|
||||||
|
/// </summary>
|
||||||
|
private static UsageLogResponse MapToResponse(Domain.Entities.UsageLog log) => new()
|
||||||
|
{
|
||||||
|
Id = log.Id,
|
||||||
|
SpoolId = log.SpoolId,
|
||||||
|
PrinterId = log.PrinterId,
|
||||||
|
PrintJobId = log.PrintJobId,
|
||||||
|
GramsUsed = log.GramsUsed,
|
||||||
|
MmExtruded = log.MmExtruded,
|
||||||
|
UsageTimestamp = log.UsageTimestamp,
|
||||||
|
DataSource = log.DataSource.ToString(),
|
||||||
|
Notes = log.Notes,
|
||||||
|
CreatedAt = log.CreatedAt,
|
||||||
|
UpdatedAt = log.UpdatedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
115
backend/API/DTOs/UsageLogs/UsageLogDtos.cs
Normal file
115
backend/API/DTOs/UsageLogs/UsageLogDtos.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Extrudex.API.DTOs.UsageLogs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request DTO for recording a filament usage entry.
|
||||||
|
/// </summary>
|
||||||
|
public class CreateUsageLogRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the spool that provided the filament.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public Guid SpoolId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of grams of filament consumed.
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[Range(0.01, double.MaxValue, ErrorMessage = "GramsUsed must be a positive value.")]
|
||||||
|
public decimal GramsUsed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The source of the usage data (Mqtt, Moonraker, Manual).
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string DataSource { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the printer that consumed the filament. Optional.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrinterId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the print job associated with this usage. Optional.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrintJobId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of millimeters of filament extruded. Optional.
|
||||||
|
/// </summary>
|
||||||
|
public decimal? MmExtruded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the usage occurred (UTC). Defaults to now if not specified.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? UsageTimestamp { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional notes about this usage entry.
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(2000)]
|
||||||
|
public string? Notes { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Response DTO for a usage log entry.
|
||||||
|
/// </summary>
|
||||||
|
public class UsageLogResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Unique identifier for the usage log entry.
|
||||||
|
/// </summary>
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The spool that provided the filament.
|
||||||
|
/// </summary>
|
||||||
|
public Guid SpoolId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The printer that consumed the filament, if applicable.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrinterId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The print job associated with this usage, if applicable.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrintJobId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Grams of filament consumed.
|
||||||
|
/// </summary>
|
||||||
|
public decimal GramsUsed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Millimeters of filament extruded, if available.
|
||||||
|
/// </summary>
|
||||||
|
public decimal? MmExtruded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the usage occurred (UTC).
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UsageTimestamp { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Source of the usage data (Mqtt, Moonraker, Manual).
|
||||||
|
/// </summary>
|
||||||
|
public string DataSource { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional notes about this usage entry.
|
||||||
|
/// </summary>
|
||||||
|
public string? Notes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the record was created (UTC).
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the record was last updated (UTC).
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UpdatedAt { get; set; }
|
||||||
|
}
|
||||||
34
backend/Dockerfile
Normal file
34
backend/Dockerfile
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# ── Stage 1: Build ──────────────────────────────────────────
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# Copy csproj first for layer caching — restores before copying source
|
||||||
|
COPY Extrudex.csproj .
|
||||||
|
RUN dotnet restore
|
||||||
|
|
||||||
|
# Copy the rest of the source
|
||||||
|
COPY . .
|
||||||
|
RUN dotnet publish Extrudex.csproj \
|
||||||
|
-c Release \
|
||||||
|
-o /app/publish \
|
||||||
|
--no-restore
|
||||||
|
|
||||||
|
# ── Stage 2: Runtime ────────────────────────────────────────
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Non-root user for security
|
||||||
|
RUN adduser --disabled-password --gecos "" appuser
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Copy published output from build stage
|
||||||
|
COPY --from=build /app/publish .
|
||||||
|
|
||||||
|
# ASP.NET Core listens on 8080 by default in .NET 8+
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check against /health endpoint
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||||
|
CMD curl --fail http://localhost:8080/health || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["dotnet", "Extrudex.dll"]
|
||||||
72
backend/Domain/Entities/UsageLog.cs
Normal file
72
backend/Domain/Entities/UsageLog.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Extrudex.Domain.Base;
|
||||||
|
using Extrudex.Domain.Enums;
|
||||||
|
|
||||||
|
namespace Extrudex.Domain.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a single filament usage log entry. Records how much filament
|
||||||
|
/// was consumed, by which printer, at what time, and optionally linked to
|
||||||
|
/// a print job. This provides a fine-grained audit trail of filament consumption
|
||||||
|
/// independent of print job lifecycle.
|
||||||
|
/// </summary>
|
||||||
|
public class UsageLog : AuditableEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Foreign key to the spool that provided the filament.
|
||||||
|
/// </summary>
|
||||||
|
public Guid SpoolId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigation to the spool that provided the filament.
|
||||||
|
/// </summary>
|
||||||
|
public Spool Spool { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Foreign key to the printer that consumed the filament.
|
||||||
|
/// Nullable to support manual entries without a specific printer.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrinterId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigation to the printer that consumed the filament.
|
||||||
|
/// </summary>
|
||||||
|
public Printer? Printer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Foreign key to the print job associated with this usage entry.
|
||||||
|
/// Nullable because usage can be logged before or without a print job.
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PrintJobId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigation to the print job associated with this usage entry.
|
||||||
|
/// </summary>
|
||||||
|
public PrintJob? PrintJob { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of grams of filament consumed in this usage event.
|
||||||
|
/// </summary>
|
||||||
|
public decimal GramsUsed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of millimeters of filament extruded in this usage event.
|
||||||
|
/// Optional — may not be available for all data sources.
|
||||||
|
/// </summary>
|
||||||
|
public decimal? MmExtruded { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Timestamp when the usage occurred (UTC). This is the actual time of
|
||||||
|
/// consumption, which may differ from CreatedAt if the entry was recorded later.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UsageTimestamp { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The source of the usage data (which integration path provided it).
|
||||||
|
/// </summary>
|
||||||
|
public DataSource DataSource { get; set; } = DataSource.Manual;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional notes about this usage entry.
|
||||||
|
/// </summary>
|
||||||
|
public string? Notes { get; set; }
|
||||||
|
}
|
||||||
57
backend/Domain/Interfaces/IUsageLogService.cs
Normal file
57
backend/Domain/Interfaces/IUsageLogService.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using Extrudex.Domain.Entities;
|
||||||
|
using Extrudex.Domain.Enums;
|
||||||
|
|
||||||
|
namespace Extrudex.Domain.Interfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Service for recording filament usage entries. Writes to the usage_logs table
|
||||||
|
/// and provides query capabilities for usage history.
|
||||||
|
/// </summary>
|
||||||
|
public interface IUsageLogService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Records a filament usage entry.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spoolId">The spool that provided the filament.</param>
|
||||||
|
/// <param name="gramsUsed">Grams of filament consumed.</param>
|
||||||
|
/// <param name="dataSource">Where the data came from.</param>
|
||||||
|
/// <param name="printerId">Optional printer ID.</param>
|
||||||
|
/// <param name="printJobId">Optional print job ID.</param>
|
||||||
|
/// <param name="mmExtruded">Optional mm extruded.</param>
|
||||||
|
/// <param name="usageTimestamp">When the usage occurred (defaults to UTC now).</param>
|
||||||
|
/// <param name="notes">Optional notes.</param>
|
||||||
|
/// <returns>The created UsageLog entity.</returns>
|
||||||
|
Task<UsageLog> RecordUsageAsync(
|
||||||
|
Guid spoolId,
|
||||||
|
decimal gramsUsed,
|
||||||
|
DataSource dataSource,
|
||||||
|
Guid? printerId = null,
|
||||||
|
Guid? printJobId = null,
|
||||||
|
decimal? mmExtruded = null,
|
||||||
|
DateTime? usageTimestamp = null,
|
||||||
|
string? notes = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves usage logs for a specific spool, ordered by usage timestamp descending.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spoolId">The spool ID to filter by.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>A collection of usage logs for the spool.</returns>
|
||||||
|
Task<IEnumerable<UsageLog>> GetBySpoolAsync(Guid spoolId, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves usage logs for a specific printer, ordered by usage timestamp descending.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="printerId">The printer ID to filter by.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>A collection of usage logs for the printer.</returns>
|
||||||
|
Task<IEnumerable<UsageLog>> GetByPrinterAsync(Guid printerId, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves usage logs for a specific print job, ordered by usage timestamp descending.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="printJobId">The print job ID to filter by.</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token.</param>
|
||||||
|
/// <returns>A collection of usage logs for the print job.</returns>
|
||||||
|
Task<IEnumerable<UsageLog>> GetByPrintJobAsync(Guid printJobId, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
|
||||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
|
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3" />
|
||||||
|
|||||||
@@ -49,15 +49,26 @@ public abstract class BaseEntityConfiguration<TEntity> : IEntityTypeConfiguratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts PascalCase or camelCase to snake_case.
|
/// Converts PascalCase or camelCase entity name to plural snake_case table name.
|
||||||
|
/// e.g. MaterialBase → material_bases, AmsSlot → ams_slots
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static string ToSnakeCase(string name)
|
protected static string ToSnakeCase(string name)
|
||||||
{
|
{
|
||||||
return string.Concat(
|
var snake = string.Concat(
|
||||||
name.Select((ch, i) =>
|
name.Select((ch, i) =>
|
||||||
i > 0 && char.IsUpper(ch) && (char.IsLower(name[i - 1]) || (i + 1 < name.Length && char.IsLower(name[i + 1])))
|
i > 0 && char.IsUpper(ch) && (char.IsLower(name[i - 1]) || (i + 1 < name.Length && char.IsLower(name[i + 1])))
|
||||||
? "_" + ch
|
? "_" + ch
|
||||||
: ch.ToString()))
|
: ch.ToString()))
|
||||||
.ToLowerInvariant();
|
.ToLowerInvariant();
|
||||||
|
|
||||||
|
// Pluralize: add 's' (handles most cases; irregular plurals handled explicitly if needed)
|
||||||
|
// Special cases: already_plural stays, 'y' → 'ies', 's'/'x'/'ch'/'sh' → 'es'
|
||||||
|
if (snake.EndsWith("s"))
|
||||||
|
return snake; // Already plural or ambiguous — leave as-is
|
||||||
|
if (snake.EndsWith("y") && !snake.EndsWith("ay") && !snake.EndsWith("ey") && !snake.EndsWith("oy") && !snake.EndsWith("uy"))
|
||||||
|
return snake[..^1] + "ies";
|
||||||
|
if (snake.EndsWith("x") || snake.EndsWith("ch") || snake.EndsWith("sh"))
|
||||||
|
return snake + "es";
|
||||||
|
return snake + "s";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,14 @@ public class SpoolConfiguration : BaseEntityConfiguration<Spool>
|
|||||||
builder.HasIndex(e => e.MaterialBaseId)
|
builder.HasIndex(e => e.MaterialBaseId)
|
||||||
.HasDatabaseName("ix_spools_material_base_id");
|
.HasDatabaseName("ix_spools_material_base_id");
|
||||||
|
|
||||||
|
// Index on material_finish_id for spool filtering
|
||||||
|
builder.HasIndex(e => e.MaterialFinishId)
|
||||||
|
.HasDatabaseName("ix_spools_material_finish_id");
|
||||||
|
|
||||||
|
// Index on material_modifier_id for spool filtering
|
||||||
|
builder.HasIndex(e => e.MaterialModifierId)
|
||||||
|
.HasDatabaseName("ix_spools_material_modifier_id");
|
||||||
|
|
||||||
// Index on is_active for active spool queries
|
// Index on is_active for active spool queries
|
||||||
builder.HasIndex(e => e.IsActive)
|
builder.HasIndex(e => e.IsActive)
|
||||||
.HasDatabaseName("ix_spools_is_active");
|
.HasDatabaseName("ix_spools_is_active");
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
using Extrudex.Domain.Entities;
|
||||||
|
using Extrudex.Domain.Enums;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
|
namespace Extrudex.Infrastructure.Data.Configurations;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EF Core configuration for the UsageLog entity.
|
||||||
|
/// Maps to the usage_logs table with snake_case columns and appropriate indexes.
|
||||||
|
/// </summary>
|
||||||
|
public class UsageLogConfiguration : BaseEntityConfiguration<UsageLog>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Configure(EntityTypeBuilder<UsageLog> builder)
|
||||||
|
{
|
||||||
|
base.Configure(builder);
|
||||||
|
|
||||||
|
builder.Property(e => e.SpoolId)
|
||||||
|
.HasColumnName("spool_id")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(e => e.PrinterId)
|
||||||
|
.HasColumnName("printer_id");
|
||||||
|
|
||||||
|
builder.Property(e => e.PrintJobId)
|
||||||
|
.HasColumnName("print_job_id");
|
||||||
|
|
||||||
|
builder.Property(e => e.GramsUsed)
|
||||||
|
.HasColumnName("grams_used")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(e => e.MmExtruded)
|
||||||
|
.HasColumnName("mm_extruded")
|
||||||
|
.HasPrecision(12, 2);
|
||||||
|
|
||||||
|
builder.Property(e => e.UsageTimestamp)
|
||||||
|
.HasColumnName("usage_timestamp")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(e => e.DataSource)
|
||||||
|
.HasColumnName("data_source")
|
||||||
|
.HasConversion<string>()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
builder.Property(e => e.Notes)
|
||||||
|
.HasColumnName("notes")
|
||||||
|
.HasMaxLength(2000);
|
||||||
|
|
||||||
|
// Index on spool_id for querying usage by spool
|
||||||
|
builder.HasIndex(e => e.SpoolId)
|
||||||
|
.HasDatabaseName("ix_usage_logs_spool_id");
|
||||||
|
|
||||||
|
// Index on printer_id for querying usage by printer
|
||||||
|
builder.HasIndex(e => e.PrinterId)
|
||||||
|
.HasDatabaseName("ix_usage_logs_printer_id");
|
||||||
|
|
||||||
|
// Index on print_job_id for querying usage by print job
|
||||||
|
builder.HasIndex(e => e.PrintJobId)
|
||||||
|
.HasDatabaseName("ix_usage_logs_print_job_id");
|
||||||
|
|
||||||
|
// Index on usage_timestamp for chronological queries
|
||||||
|
builder.HasIndex(e => e.UsageTimestamp)
|
||||||
|
.HasDatabaseName("ix_usage_logs_usage_timestamp");
|
||||||
|
|
||||||
|
// Index on data_source for filtering by integration path
|
||||||
|
builder.HasIndex(e => e.DataSource)
|
||||||
|
.HasDatabaseName("ix_usage_logs_data_source");
|
||||||
|
|
||||||
|
// Relationships
|
||||||
|
builder.HasOne(e => e.Spool)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(e => e.SpoolId)
|
||||||
|
.HasConstraintName("fk_usage_logs_spool")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
builder.HasOne(e => e.Printer)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(e => e.PrinterId)
|
||||||
|
.HasConstraintName("fk_usage_logs_printer")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
|
builder.HasOne(e => e.PrintJob)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(e => e.PrintJobId)
|
||||||
|
.HasConstraintName("fk_usage_logs_print_job")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ public class ExtrudexDbContext : DbContext
|
|||||||
public DbSet<AmsUnit> AmsUnits => Set<AmsUnit>();
|
public DbSet<AmsUnit> AmsUnits => Set<AmsUnit>();
|
||||||
public DbSet<AmsSlot> AmsSlots => Set<AmsSlot>();
|
public DbSet<AmsSlot> AmsSlots => Set<AmsSlot>();
|
||||||
public DbSet<PrintJob> PrintJobs => Set<PrintJob>();
|
public DbSet<PrintJob> PrintJobs => Set<PrintJob>();
|
||||||
|
public DbSet<UsageLog> UsageLogs => Set<UsageLog>();
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
|
|||||||
958
backend/Infrastructure/Data/Migrations/20260426131419_InitialCreate.Designer.cs
generated
Normal file
958
backend/Infrastructure/Data/Migrations/20260426131419_InitialCreate.Designer.cs
generated
Normal file
@@ -0,0 +1,958 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Extrudex.Infrastructure.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Extrudex.Infrastructure.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ExtrudexDbContext))]
|
||||||
|
[Migration("20260426131419_InitialCreate")]
|
||||||
|
partial class InitialCreate
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.3")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.AmsSlot", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<Guid>("AmsUnitId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("ams_unit_id");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<decimal?>("RemainingWeightG")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.HasColumnType("numeric(10,2)")
|
||||||
|
.HasColumnName("remaining_weight_g");
|
||||||
|
|
||||||
|
b.Property<Guid?>("SpoolId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("spool_id");
|
||||||
|
|
||||||
|
b.Property<int>("TrayIndex")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("tray_index");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SpoolId")
|
||||||
|
.HasDatabaseName("ix_ams_slots_spool_id");
|
||||||
|
|
||||||
|
b.HasIndex("AmsUnitId", "TrayIndex")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_ams_slots_ams_unit_id_tray_index");
|
||||||
|
|
||||||
|
b.ToTable("ams_slots", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.AmsUnit", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<Guid>("PrinterId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("printer_id");
|
||||||
|
|
||||||
|
b.Property<int>("UnitIndex")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("unit_index");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PrinterId", "UnitIndex")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_ams_units_printer_id_unit_index");
|
||||||
|
|
||||||
|
b.ToTable("ams_units", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialBase", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<decimal>("DensityGperCm3")
|
||||||
|
.HasPrecision(10, 4)
|
||||||
|
.HasColumnType("numeric(10,4)")
|
||||||
|
.HasColumnName("density_g_per_cm3");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_material_bases_name");
|
||||||
|
|
||||||
|
b.ToTable("material_bases", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096),
|
||||||
|
DensityGperCm3 = 1.24m,
|
||||||
|
Name = "PLA",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620),
|
||||||
|
DensityGperCm3 = 1.27m,
|
||||||
|
Name = "PETG",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630),
|
||||||
|
DensityGperCm3 = 1.04m,
|
||||||
|
Name = "ABS",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638),
|
||||||
|
DensityGperCm3 = 1.07m,
|
||||||
|
Name = "ASA",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645),
|
||||||
|
DensityGperCm3 = 1.21m,
|
||||||
|
Name = "TPU",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1651),
|
||||||
|
DensityGperCm3 = 1.14m,
|
||||||
|
Name = "Nylon",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1652)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialFinish", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<Guid>("MaterialBaseId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("material_base_id");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("MaterialBaseId", "Name")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_material_finishes_material_base_id_name");
|
||||||
|
|
||||||
|
b.ToTable("material_finishes", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000001"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000002"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Matte",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000003"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Silk",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000004"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2055),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Glitter",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2056)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000005"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Marble",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000006"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Sparkle",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000007"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000008"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
Name = "Matte",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000009"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
Name = "Silk",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000010"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000011"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
Name = "Matte",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000012"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
Name = "Matte",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000014"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2132),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2133)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("20000000-0000-0000-0000-000000000015"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
Name = "Basic",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialModifier", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<Guid>("MaterialBaseId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("material_base_id");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("MaterialBaseId", "Name")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_material_modifiers_material_base_id_name");
|
||||||
|
|
||||||
|
b.ToTable("material_modifiers", (string)null);
|
||||||
|
|
||||||
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000001"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Carbon Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000002"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Glass Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000003"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Wood Fill",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000004"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2477),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
Name = "Glow-in-the-Dark",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2478)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000005"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
Name = "Carbon Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000006"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2490),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
Name = "Glass Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2491)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000007"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
Name = "Carbon Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000008"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
Name = "Glass Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000009"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
Name = "Carbon Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000010"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
Name = "Carbon Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516)
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("30000000-0000-0000-0000-000000000011"),
|
||||||
|
CreatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2522),
|
||||||
|
MaterialBaseId = new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
Name = "Glass Fiber",
|
||||||
|
UpdatedAt = new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2523)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.PrintJob", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("CompletedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("completed_at");
|
||||||
|
|
||||||
|
b.Property<decimal?>("CostPerPrint")
|
||||||
|
.HasPrecision(10, 4)
|
||||||
|
.HasColumnType("numeric(10,4)")
|
||||||
|
.HasColumnName("cost_per_print");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<string>("DataSource")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasColumnName("data_source");
|
||||||
|
|
||||||
|
b.Property<decimal>("FilamentDiameterAtPrintMm")
|
||||||
|
.HasPrecision(6, 3)
|
||||||
|
.HasColumnType("numeric(6,3)")
|
||||||
|
.HasColumnName("filament_diameter_at_print_mm");
|
||||||
|
|
||||||
|
b.Property<string>("GcodeFilePath")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("character varying(1000)")
|
||||||
|
.HasColumnName("gcode_file_path");
|
||||||
|
|
||||||
|
b.Property<decimal>("GramsDerived")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.HasColumnType("numeric(10,2)")
|
||||||
|
.HasColumnName("grams_derived");
|
||||||
|
|
||||||
|
b.Property<decimal>("MaterialDensityAtPrint")
|
||||||
|
.HasPrecision(10, 4)
|
||||||
|
.HasColumnType("numeric(10,4)")
|
||||||
|
.HasColumnName("material_density_at_print");
|
||||||
|
|
||||||
|
b.Property<decimal>("MmExtruded")
|
||||||
|
.HasPrecision(12, 2)
|
||||||
|
.HasColumnType("numeric(12,2)")
|
||||||
|
.HasColumnName("mm_extruded");
|
||||||
|
|
||||||
|
b.Property<string>("Notes")
|
||||||
|
.HasMaxLength(2000)
|
||||||
|
.HasColumnType("character varying(2000)")
|
||||||
|
.HasColumnName("notes");
|
||||||
|
|
||||||
|
b.Property<string>("PrintName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("character varying(500)")
|
||||||
|
.HasColumnName("print_name");
|
||||||
|
|
||||||
|
b.Property<Guid>("PrinterId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("printer_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("SpoolId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("spool_id");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("StartedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("started_at");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasDefaultValue("Queued")
|
||||||
|
.HasColumnName("status");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DataSource")
|
||||||
|
.HasDatabaseName("ix_print_jobs_data_source");
|
||||||
|
|
||||||
|
b.HasIndex("PrinterId")
|
||||||
|
.HasDatabaseName("ix_print_jobs_printer_id");
|
||||||
|
|
||||||
|
b.HasIndex("SpoolId")
|
||||||
|
.HasDatabaseName("ix_print_jobs_spool_id");
|
||||||
|
|
||||||
|
b.HasIndex("Status")
|
||||||
|
.HasDatabaseName("ix_print_jobs_status");
|
||||||
|
|
||||||
|
b.ToTable("print_jobs", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.Printer", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<string>("ApiKey")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("character varying(500)")
|
||||||
|
.HasColumnName("api_key");
|
||||||
|
|
||||||
|
b.Property<string>("ConnectionType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasColumnName("connection_type");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<string>("HostnameOrIp")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(255)
|
||||||
|
.HasColumnType("character varying(255)")
|
||||||
|
.HasColumnName("hostname_or_ip");
|
||||||
|
|
||||||
|
b.Property<bool>("IsActive")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasDefaultValue(true)
|
||||||
|
.HasColumnName("is_active");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastSeenAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_seen_at");
|
||||||
|
|
||||||
|
b.Property<string>("Manufacturer")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("manufacturer");
|
||||||
|
|
||||||
|
b.Property<string>("Model")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("model");
|
||||||
|
|
||||||
|
b.Property<string>("MqttPassword")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("character varying(500)")
|
||||||
|
.HasColumnName("mqtt_password");
|
||||||
|
|
||||||
|
b.Property<bool>("MqttUseTls")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasDefaultValue(false)
|
||||||
|
.HasColumnName("mqtt_use_tls");
|
||||||
|
|
||||||
|
b.Property<string>("MqttUsername")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("mqtt_username");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<int>("Port")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("port");
|
||||||
|
|
||||||
|
b.Property<string>("PrinterType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasColumnName("printer_type");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasDefaultValue("Offline")
|
||||||
|
.HasColumnName("status");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ConnectionType")
|
||||||
|
.HasDatabaseName("ix_printers_connection_type");
|
||||||
|
|
||||||
|
b.HasIndex("IsActive")
|
||||||
|
.HasDatabaseName("ix_printers_is_active");
|
||||||
|
|
||||||
|
b.HasIndex("PrinterType")
|
||||||
|
.HasDatabaseName("ix_printers_printer_type");
|
||||||
|
|
||||||
|
b.HasIndex("Status")
|
||||||
|
.HasDatabaseName("ix_printers_status");
|
||||||
|
|
||||||
|
b.ToTable("printers", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.Spool", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
b.Property<string>("Brand")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("brand");
|
||||||
|
|
||||||
|
b.Property<string>("ColorHex")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(7)
|
||||||
|
.HasColumnType("character varying(7)")
|
||||||
|
.HasColumnName("color_hex");
|
||||||
|
|
||||||
|
b.Property<string>("ColorName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("color_name");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<decimal>("FilamentDiameterMm")
|
||||||
|
.HasPrecision(6, 3)
|
||||||
|
.HasColumnType("numeric(6,3)")
|
||||||
|
.HasColumnName("filament_diameter_mm");
|
||||||
|
|
||||||
|
b.Property<bool>("IsActive")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasDefaultValue(true)
|
||||||
|
.HasColumnName("is_active");
|
||||||
|
|
||||||
|
b.Property<Guid>("MaterialBaseId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("material_base_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("MaterialFinishId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("material_finish_id");
|
||||||
|
|
||||||
|
b.Property<Guid?>("MaterialModifierId")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("material_modifier_id");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("PurchaseDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("purchase_date");
|
||||||
|
|
||||||
|
b.Property<decimal?>("PurchasePrice")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.HasColumnType("numeric(10,2)")
|
||||||
|
.HasColumnName("purchase_price");
|
||||||
|
|
||||||
|
b.Property<string>("SpoolSerial")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)")
|
||||||
|
.HasColumnName("spool_serial");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("updated_at")
|
||||||
|
.HasDefaultValueSql("now() at time zone 'utc'");
|
||||||
|
|
||||||
|
b.Property<decimal>("WeightRemainingGrams")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.HasColumnType("numeric(10,2)")
|
||||||
|
.HasColumnName("weight_remaining_grams");
|
||||||
|
|
||||||
|
b.Property<decimal>("WeightTotalGrams")
|
||||||
|
.HasPrecision(10, 2)
|
||||||
|
.HasColumnType("numeric(10,2)")
|
||||||
|
.HasColumnName("weight_total_grams");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IsActive")
|
||||||
|
.HasDatabaseName("ix_spools_is_active");
|
||||||
|
|
||||||
|
b.HasIndex("MaterialBaseId")
|
||||||
|
.HasDatabaseName("ix_spools_material_base_id");
|
||||||
|
|
||||||
|
b.HasIndex("MaterialFinishId")
|
||||||
|
.HasDatabaseName("ix_spools_material_finish_id");
|
||||||
|
|
||||||
|
b.HasIndex("MaterialModifierId")
|
||||||
|
.HasDatabaseName("ix_spools_material_modifier_id");
|
||||||
|
|
||||||
|
b.HasIndex("SpoolSerial")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_spools_spool_serial");
|
||||||
|
|
||||||
|
b.ToTable("spools", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.AmsSlot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.AmsUnit", "AmsUnit")
|
||||||
|
.WithMany("Slots")
|
||||||
|
.HasForeignKey("AmsUnitId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_ams_slots_ams_unit");
|
||||||
|
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.Spool", "Spool")
|
||||||
|
.WithMany("AmsSlots")
|
||||||
|
.HasForeignKey("SpoolId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("fk_ams_slots_spool");
|
||||||
|
|
||||||
|
b.Navigation("AmsUnit");
|
||||||
|
|
||||||
|
b.Navigation("Spool");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.AmsUnit", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.Printer", "Printer")
|
||||||
|
.WithMany("AmsUnits")
|
||||||
|
.HasForeignKey("PrinterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_ams_units_printer");
|
||||||
|
|
||||||
|
b.Navigation("Printer");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialFinish", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.MaterialBase", "MaterialBase")
|
||||||
|
.WithMany("Finishes")
|
||||||
|
.HasForeignKey("MaterialBaseId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_material_finishes_material_base");
|
||||||
|
|
||||||
|
b.Navigation("MaterialBase");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialModifier", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.MaterialBase", "MaterialBase")
|
||||||
|
.WithMany("Modifiers")
|
||||||
|
.HasForeignKey("MaterialBaseId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_material_modifiers_material_base");
|
||||||
|
|
||||||
|
b.Navigation("MaterialBase");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.PrintJob", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.Printer", "Printer")
|
||||||
|
.WithMany("PrintJobs")
|
||||||
|
.HasForeignKey("PrinterId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_print_jobs_printer");
|
||||||
|
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.Spool", "Spool")
|
||||||
|
.WithMany("PrintJobs")
|
||||||
|
.HasForeignKey("SpoolId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_print_jobs_spool");
|
||||||
|
|
||||||
|
b.Navigation("Printer");
|
||||||
|
|
||||||
|
b.Navigation("Spool");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.Spool", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.MaterialBase", "MaterialBase")
|
||||||
|
.WithMany("Spools")
|
||||||
|
.HasForeignKey("MaterialBaseId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_spools_material_base");
|
||||||
|
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.MaterialFinish", "MaterialFinish")
|
||||||
|
.WithMany("Spools")
|
||||||
|
.HasForeignKey("MaterialFinishId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_spools_material_finish");
|
||||||
|
|
||||||
|
b.HasOne("Extrudex.Domain.Entities.MaterialModifier", "MaterialModifier")
|
||||||
|
.WithMany("Spools")
|
||||||
|
.HasForeignKey("MaterialModifierId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull)
|
||||||
|
.HasConstraintName("fk_spools_material_modifier");
|
||||||
|
|
||||||
|
b.Navigation("MaterialBase");
|
||||||
|
|
||||||
|
b.Navigation("MaterialFinish");
|
||||||
|
|
||||||
|
b.Navigation("MaterialModifier");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.AmsUnit", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Slots");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialBase", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Finishes");
|
||||||
|
|
||||||
|
b.Navigation("Modifiers");
|
||||||
|
|
||||||
|
b.Navigation("Spools");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialFinish", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Spools");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.MaterialModifier", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Spools");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.Printer", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AmsUnits");
|
||||||
|
|
||||||
|
b.Navigation("PrintJobs");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Extrudex.Domain.Entities.Spool", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AmsSlots");
|
||||||
|
|
||||||
|
b.Navigation("PrintJobs");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,416 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
||||||
|
|
||||||
|
namespace Extrudex.Infrastructure.Data.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class InitialCreate : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "material_bases",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
|
density_g_per_cm3 = table.Column<decimal>(type: "numeric(10,4)", precision: 10, scale: 4, nullable: false),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_material_bases", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "printers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
status = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false, defaultValue: "Offline"),
|
||||||
|
name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
manufacturer = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
model = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
printer_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||||
|
connection_type = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||||
|
hostname_or_ip = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
|
||||||
|
port = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
mqtt_username = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
mqtt_password = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||||
|
mqtt_use_tls = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
|
||||||
|
api_key = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||||
|
is_active = table.Column<bool>(type: "boolean", nullable: false, defaultValue: true),
|
||||||
|
last_seen_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_printers", x => x.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "material_finishes",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
|
material_base_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_material_finishes", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_material_finishes_material_base",
|
||||||
|
column: x => x.material_base_id,
|
||||||
|
principalTable: "material_bases",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "material_modifiers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
|
material_base_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_material_modifiers", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_material_modifiers_material_base",
|
||||||
|
column: x => x.material_base_id,
|
||||||
|
principalTable: "material_bases",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ams_units",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
unit_index = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
printer_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ams_units", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_ams_units_printer",
|
||||||
|
column: x => x.printer_id,
|
||||||
|
principalTable: "printers",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "spools",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
material_base_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
material_finish_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
material_modifier_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
brand = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
color_name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
color_hex = table.Column<string>(type: "character varying(7)", maxLength: 7, nullable: false),
|
||||||
|
weight_total_grams = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
||||||
|
weight_remaining_grams = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
||||||
|
filament_diameter_mm = table.Column<decimal>(type: "numeric(6,3)", precision: 6, scale: 3, nullable: false),
|
||||||
|
spool_serial = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
purchase_price = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: true),
|
||||||
|
purchase_date = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
is_active = table.Column<bool>(type: "boolean", nullable: false, defaultValue: true),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_spools", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_spools_material_base",
|
||||||
|
column: x => x.material_base_id,
|
||||||
|
principalTable: "material_bases",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_spools_material_finish",
|
||||||
|
column: x => x.material_finish_id,
|
||||||
|
principalTable: "material_finishes",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_spools_material_modifier",
|
||||||
|
column: x => x.material_modifier_id,
|
||||||
|
principalTable: "material_modifiers",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ams_slots",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
tray_index = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
ams_unit_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
spool_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
remaining_weight_g = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: true),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ams_slots", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_ams_slots_ams_unit",
|
||||||
|
column: x => x.ams_unit_id,
|
||||||
|
principalTable: "ams_units",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_ams_slots_spool",
|
||||||
|
column: x => x.spool_id,
|
||||||
|
principalTable: "spools",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "print_jobs",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
printer_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
spool_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
print_name = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: false),
|
||||||
|
gcode_file_path = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
||||||
|
mm_extruded = table.Column<decimal>(type: "numeric(12,2)", precision: 12, scale: 2, nullable: false),
|
||||||
|
grams_derived = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
||||||
|
cost_per_print = table.Column<decimal>(type: "numeric(10,4)", precision: 10, scale: 4, nullable: true),
|
||||||
|
started_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
completed_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||||
|
status = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false, defaultValue: "Queued"),
|
||||||
|
data_source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||||
|
filament_diameter_at_print_mm = table.Column<decimal>(type: "numeric(6,3)", precision: 6, scale: 3, nullable: false),
|
||||||
|
material_density_at_print = table.Column<decimal>(type: "numeric(10,4)", precision: 10, scale: 4, nullable: false),
|
||||||
|
notes = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_print_jobs", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_print_jobs_printer",
|
||||||
|
column: x => x.printer_id,
|
||||||
|
principalTable: "printers",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_print_jobs_spool",
|
||||||
|
column: x => x.spool_id,
|
||||||
|
principalTable: "spools",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "material_bases",
|
||||||
|
columns: new[] { "id", "created_at", "density_g_per_cm3", "name", "updated_at" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000001"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096), 1.24m, "PLA", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096) },
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000002"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620), 1.27m, "PETG", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620) },
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000003"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630), 1.04m, "ABS", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630) },
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000004"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638), 1.07m, "ASA", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638) },
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000005"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645), 1.21m, "TPU", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645) },
|
||||||
|
{ new Guid("10000000-0000-0000-0000-000000000006"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1651), 1.14m, "Nylon", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1652) }
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "material_finishes",
|
||||||
|
columns: new[] { "id", "created_at", "material_base_id", "name", "updated_at" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000001"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850), new Guid("10000000-0000-0000-0000-000000000001"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000002"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041), new Guid("10000000-0000-0000-0000-000000000001"), "Matte", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000003"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049), new Guid("10000000-0000-0000-0000-000000000001"), "Silk", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000004"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2055), new Guid("10000000-0000-0000-0000-000000000001"), "Glitter", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2056) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000005"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062), new Guid("10000000-0000-0000-0000-000000000001"), "Marble", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000006"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068), new Guid("10000000-0000-0000-0000-000000000001"), "Sparkle", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000007"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075), new Guid("10000000-0000-0000-0000-000000000002"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000008"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081), new Guid("10000000-0000-0000-0000-000000000002"), "Matte", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000009"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100), new Guid("10000000-0000-0000-0000-000000000002"), "Silk", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000010"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107), new Guid("10000000-0000-0000-0000-000000000003"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000011"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113), new Guid("10000000-0000-0000-0000-000000000003"), "Matte", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000012"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120), new Guid("10000000-0000-0000-0000-000000000004"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000013"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126), new Guid("10000000-0000-0000-0000-000000000004"), "Matte", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000014"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2132), new Guid("10000000-0000-0000-0000-000000000005"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2133) },
|
||||||
|
{ new Guid("20000000-0000-0000-0000-000000000015"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139), new Guid("10000000-0000-0000-0000-000000000006"), "Basic", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139) }
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
columns: new[] { "id", "created_at", "material_base_id", "name", "updated_at" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000001"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304), new Guid("10000000-0000-0000-0000-000000000001"), "Carbon Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000002"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463), new Guid("10000000-0000-0000-0000-000000000001"), "Glass Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000003"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471), new Guid("10000000-0000-0000-0000-000000000001"), "Wood Fill", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000004"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2477), new Guid("10000000-0000-0000-0000-000000000001"), "Glow-in-the-Dark", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2478) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000005"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484), new Guid("10000000-0000-0000-0000-000000000002"), "Carbon Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000006"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2490), new Guid("10000000-0000-0000-0000-000000000002"), "Glass Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2491) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000007"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497), new Guid("10000000-0000-0000-0000-000000000003"), "Carbon Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000008"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503), new Guid("10000000-0000-0000-0000-000000000003"), "Glass Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000009"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510), new Guid("10000000-0000-0000-0000-000000000004"), "Carbon Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000010"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516), new Guid("10000000-0000-0000-0000-000000000006"), "Carbon Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516) },
|
||||||
|
{ new Guid("30000000-0000-0000-0000-000000000011"), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2522), new Guid("10000000-0000-0000-0000-000000000006"), "Glass Fiber", new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2523) }
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_ams_slots_ams_unit_id_tray_index",
|
||||||
|
table: "ams_slots",
|
||||||
|
columns: new[] { "ams_unit_id", "tray_index" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_ams_slots_spool_id",
|
||||||
|
table: "ams_slots",
|
||||||
|
column: "spool_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_ams_units_printer_id_unit_index",
|
||||||
|
table: "ams_units",
|
||||||
|
columns: new[] { "printer_id", "unit_index" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_material_bases_name",
|
||||||
|
table: "material_bases",
|
||||||
|
column: "name",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_material_finishes_material_base_id_name",
|
||||||
|
table: "material_finishes",
|
||||||
|
columns: new[] { "material_base_id", "name" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_material_modifiers_material_base_id_name",
|
||||||
|
table: "material_modifiers",
|
||||||
|
columns: new[] { "material_base_id", "name" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_print_jobs_data_source",
|
||||||
|
table: "print_jobs",
|
||||||
|
column: "data_source");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_print_jobs_printer_id",
|
||||||
|
table: "print_jobs",
|
||||||
|
column: "printer_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_print_jobs_spool_id",
|
||||||
|
table: "print_jobs",
|
||||||
|
column: "spool_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_print_jobs_status",
|
||||||
|
table: "print_jobs",
|
||||||
|
column: "status");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_printers_connection_type",
|
||||||
|
table: "printers",
|
||||||
|
column: "connection_type");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_printers_is_active",
|
||||||
|
table: "printers",
|
||||||
|
column: "is_active");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_printers_printer_type",
|
||||||
|
table: "printers",
|
||||||
|
column: "printer_type");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_printers_status",
|
||||||
|
table: "printers",
|
||||||
|
column: "status");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_spools_is_active",
|
||||||
|
table: "spools",
|
||||||
|
column: "is_active");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_spools_material_base_id",
|
||||||
|
table: "spools",
|
||||||
|
column: "material_base_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_spools_material_finish_id",
|
||||||
|
table: "spools",
|
||||||
|
column: "material_finish_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_spools_material_modifier_id",
|
||||||
|
table: "spools",
|
||||||
|
column: "material_modifier_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_spools_spool_serial",
|
||||||
|
table: "spools",
|
||||||
|
column: "spool_serial",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ams_slots");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "print_jobs");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ams_units");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "spools");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "printers");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "material_finishes");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "material_modifiers");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "material_bases");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1061
backend/Infrastructure/Data/Migrations/20260426184329_AddUsageLogTable.Designer.cs
generated
Normal file
1061
backend/Infrastructure/Data/Migrations/20260426184329_AddUsageLogTable.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,534 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Extrudex.Infrastructure.Data.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddUsageLogTable : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "usage_logs",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
spool_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||||
|
printer_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
print_job_id = table.Column<Guid>(type: "uuid", nullable: true),
|
||||||
|
grams_used = table.Column<decimal>(type: "numeric(10,2)", precision: 10, scale: 2, nullable: false),
|
||||||
|
mm_extruded = table.Column<decimal>(type: "numeric(12,2)", precision: 12, scale: 2, nullable: true),
|
||||||
|
usage_timestamp = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
data_source = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||||
|
notes = table.Column<string>(type: "character varying(2000)", maxLength: 2000, nullable: true),
|
||||||
|
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'"),
|
||||||
|
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false, defaultValueSql: "now() at time zone 'utc'")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_usage_logs", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_usage_logs_print_job",
|
||||||
|
column: x => x.print_job_id,
|
||||||
|
principalTable: "print_jobs",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_usage_logs_printer",
|
||||||
|
column: x => x.printer_id,
|
||||||
|
principalTable: "printers",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_usage_logs_spool",
|
||||||
|
column: x => x.spool_id,
|
||||||
|
principalTable: "spools",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(6535), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(6535) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7016), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7016) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7027), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7028) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7034), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7035) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7042), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7042) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7049), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7049) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7291), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7292) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7453), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7453) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7461), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7461) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7468), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7468) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7474), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7474) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7480), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7481) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000007"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7487), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7487) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000008"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7493), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7493) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000009"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7500), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7500) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000010"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7507), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7507) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000011"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7513), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7513) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000012"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7519), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7520) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7526), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7526) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000014"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7532), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7532) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000015"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7538), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7539) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7690), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7690) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7838), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7838) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7846), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7846) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7853), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7853) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7859), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7859) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7865), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7866) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000007"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7872), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7872) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000008"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7878), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7879) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000009"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7885), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7885) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000010"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7891), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7891) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000011"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7898), new DateTime(2026, 4, 26, 18, 43, 28, 895, DateTimeKind.Utc).AddTicks(7898) });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_usage_logs_data_source",
|
||||||
|
table: "usage_logs",
|
||||||
|
column: "data_source");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_usage_logs_print_job_id",
|
||||||
|
table: "usage_logs",
|
||||||
|
column: "print_job_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_usage_logs_printer_id",
|
||||||
|
table: "usage_logs",
|
||||||
|
column: "printer_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_usage_logs_spool_id",
|
||||||
|
table: "usage_logs",
|
||||||
|
column: "spool_id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_usage_logs_usage_timestamp",
|
||||||
|
table: "usage_logs",
|
||||||
|
column: "usage_timestamp");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "usage_logs");
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1096) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1620) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1630) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1638) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1645) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_bases",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("10000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1651), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1652) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(1850) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2041) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2049) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2055), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2056) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2062) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2068) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000007"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2075) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000008"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2081) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000009"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2100) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000010"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2107) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000011"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2113) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000012"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2120) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000013"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2126) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000014"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2132), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2133) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_finishes",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("20000000-0000-0000-0000-000000000015"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2139) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000001"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2304) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000002"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2463) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000003"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2471) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000004"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2477), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2478) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000005"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2484) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000006"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2490), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2491) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000007"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2497) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000008"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2503) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000009"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2510) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000010"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2516) });
|
||||||
|
|
||||||
|
migrationBuilder.UpdateData(
|
||||||
|
table: "material_modifiers",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: new Guid("30000000-0000-0000-0000-000000000011"),
|
||||||
|
columns: new[] { "created_at", "updated_at" },
|
||||||
|
values: new object[] { new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2522), new DateTime(2026, 4, 26, 13, 14, 18, 745, DateTimeKind.Utc).AddTicks(2523) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
81
backend/Infrastructure/Services/UsageLogService.cs
Normal file
81
backend/Infrastructure/Services/UsageLogService.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using Extrudex.Domain.Entities;
|
||||||
|
using Extrudex.Domain.Enums;
|
||||||
|
using Extrudex.Domain.Interfaces;
|
||||||
|
using Extrudex.Infrastructure.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Extrudex.Infrastructure.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implementation of <see cref="IUsageLogService"/> that persists usage entries
|
||||||
|
/// to the usage_logs table via EF Core.
|
||||||
|
/// </summary>
|
||||||
|
public class UsageLogService : IUsageLogService
|
||||||
|
{
|
||||||
|
private readonly ExtrudexDbContext _dbContext;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="UsageLogService"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dbContext">The EF Core database context for data persistence.</param>
|
||||||
|
public UsageLogService(ExtrudexDbContext dbContext)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<UsageLog> RecordUsageAsync(
|
||||||
|
Guid spoolId,
|
||||||
|
decimal gramsUsed,
|
||||||
|
DataSource dataSource,
|
||||||
|
Guid? printerId = null,
|
||||||
|
Guid? printJobId = null,
|
||||||
|
decimal? mmExtruded = null,
|
||||||
|
DateTime? usageTimestamp = null,
|
||||||
|
string? notes = null)
|
||||||
|
{
|
||||||
|
var entry = new UsageLog
|
||||||
|
{
|
||||||
|
SpoolId = spoolId,
|
||||||
|
GramsUsed = gramsUsed,
|
||||||
|
DataSource = dataSource,
|
||||||
|
PrinterId = printerId,
|
||||||
|
PrintJobId = printJobId,
|
||||||
|
MmExtruded = mmExtruded,
|
||||||
|
UsageTimestamp = usageTimestamp ?? DateTime.UtcNow,
|
||||||
|
Notes = notes
|
||||||
|
};
|
||||||
|
|
||||||
|
_dbContext.UsageLogs.Add(entry);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<IEnumerable<UsageLog>> GetBySpoolAsync(Guid spoolId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.UsageLogs
|
||||||
|
.Where(u => u.SpoolId == spoolId)
|
||||||
|
.OrderByDescending(u => u.UsageTimestamp)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<IEnumerable<UsageLog>> GetByPrinterAsync(Guid printerId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.UsageLogs
|
||||||
|
.Where(u => u.PrinterId == printerId)
|
||||||
|
.OrderByDescending(u => u.UsageTimestamp)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<IEnumerable<UsageLog>> GetByPrintJobAsync(Guid printJobId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return await _dbContext.UsageLogs
|
||||||
|
.Where(u => u.PrintJobId == printJobId)
|
||||||
|
.OrderByDescending(u => u.UsageTimestamp)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,9 @@ builder.Services.AddSwaggerGen(c =>
|
|||||||
// ── QR Code Generation ──────────────────────────────────────
|
// ── QR Code Generation ──────────────────────────────────────
|
||||||
builder.Services.AddSingleton<IQrCodeService, QrCodeService>();
|
builder.Services.AddSingleton<IQrCodeService, QrCodeService>();
|
||||||
|
|
||||||
|
// ── Usage Logging ───────────────────────────────────────────
|
||||||
|
builder.Services.AddScoped<IUsageLogService, UsageLogService>();
|
||||||
|
|
||||||
// ── FluentValidation ──────────────────────────────────────
|
// ── FluentValidation ──────────────────────────────────────
|
||||||
// Registers all validators from the API assembly into DI.
|
// Registers all validators from the API assembly into DI.
|
||||||
builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
|
builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
|
||||||
@@ -69,6 +72,10 @@ builder.Services.AddCors(options =>
|
|||||||
// ── SignalR (real-time printer updates) ────────────────────
|
// ── SignalR (real-time printer updates) ────────────────────
|
||||||
builder.Services.AddSignalR();
|
builder.Services.AddSignalR();
|
||||||
|
|
||||||
|
// ── Health Checks ───────────────────────────────────────────
|
||||||
|
builder.Services.AddHealthChecks()
|
||||||
|
.AddNpgSql(connectionString);
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// ── Middleware ──────────────────────────────────────────────
|
// ── Middleware ──────────────────────────────────────────────
|
||||||
@@ -85,6 +92,9 @@ app.MapControllers();
|
|||||||
// ── Hub Endpoints ───────────────────────────────────────────
|
// ── Hub Endpoints ───────────────────────────────────────────
|
||||||
app.MapHub<PrinterHub>("/hubs/printer");
|
app.MapHub<PrinterHub>("/hubs/printer");
|
||||||
|
|
||||||
|
// ── Health Check Endpoint ──────────────────────────────────
|
||||||
|
app.MapHealthChecks("/health");
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|
||||||
// Helper: builds a connection string from individual env vars.
|
// Helper: builds a connection string from individual env vars.
|
||||||
|
|||||||
33
deploy.sh
Executable file
33
deploy.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🔧 Deploying Extrudex Docker runtime..."
|
||||||
|
|
||||||
|
# Check if Docker Compose is available
|
||||||
|
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||||
|
echo "❌ Docker Compose is not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPOSE_CMD="docker compose"
|
||||||
|
if command -v docker-compose &> /dev/null; then
|
||||||
|
COMPOSE_CMD="docker-compose"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "📦 Building and starting services..."
|
||||||
|
$COMPOSE_CMD -f docker-compose.dev.yml up -d --build
|
||||||
|
|
||||||
|
echo "⏳ Waiting for services to become healthy..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
echo "✅ Deployment complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Services running:"
|
||||||
|
echo " • Extrudex API: http://localhost:5080"
|
||||||
|
echo " • Control Center Web: http://localhost:5081"
|
||||||
|
echo ""
|
||||||
|
echo "To view logs:"
|
||||||
|
echo " $COMPOSE_CMD -f docker-compose.dev.yml logs -f"
|
||||||
|
echo ""
|
||||||
|
echo "To stop:"
|
||||||
|
echo " $COMPOSE_CMD -f docker-compose.dev.yml down"
|
||||||
40
docker-compose.dev.yml
Normal file
40
docker-compose.dev.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
extrudex-api:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: extrudex-api
|
||||||
|
ports:
|
||||||
|
- "5080:8080"
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
|
- ASPNETCORE_URLS=http://+:8080
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
networks:
|
||||||
|
- extrudex-network
|
||||||
|
|
||||||
|
control-center-web:
|
||||||
|
build:
|
||||||
|
context: ../Control-Center/frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: control-center-web
|
||||||
|
ports:
|
||||||
|
- "5081:80"
|
||||||
|
depends_on:
|
||||||
|
extrudex-api:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- extrudex-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
extrudex-network:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user