diff --git a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs index 57eb4b8..9c3b181 100644 --- a/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs +++ b/Api.SeaHavenIndustries/Controllers/WorkOrderController.cs @@ -21,7 +21,7 @@ using SeaHaven.DataServices.Interfaces; namespace Api.SeaHavenIndustries.Controllers { - // [Authorize] + [Authorize] [ApiController] [Route("api/WorkOrder")] [Route("api/workorders")] diff --git a/Api.SeaHavenIndustries/Filters/ConcurrencyExceptionFilter.cs b/Api.SeaHavenIndustries/Filters/ConcurrencyExceptionFilter.cs new file mode 100644 index 0000000..6b84ee6 --- /dev/null +++ b/Api.SeaHavenIndustries/Filters/ConcurrencyExceptionFilter.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.EntityFrameworkCore; + +namespace Api.SeaHavenIndustries.Filters +{ + public class ConcurrencyExceptionFilter : IExceptionFilter + { + public void OnException(ExceptionContext context) + { + if (context.Exception is not DbUpdateConcurrencyException) return; + + context.Result = new ConflictObjectResult(new + { + status = "Conflict", + message = "The record was modified by another user. Refresh and retry.", + code = 409 + }); + context.ExceptionHandled = true; + } + } +} diff --git a/Api.SeaHavenIndustries/Program.cs b/Api.SeaHavenIndustries/Program.cs index a826847..6dc0e95 100644 --- a/Api.SeaHavenIndustries/Program.cs +++ b/Api.SeaHavenIndustries/Program.cs @@ -22,7 +22,10 @@ builder.Services.AddIdentity(options => .AddEntityFrameworkStores() .AddDefaultTokenProviders(); -builder.Services.AddControllers().AddJsonOptions(options => +builder.Services.AddControllers(options => +{ + options.Filters.Add(); +}).AddJsonOptions(options => { options.JsonSerializerOptions.MaxDepth = 264; // or any other desired value }); diff --git a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs index ea60e8e..a34d5d4 100644 --- a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs +++ b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs @@ -33,6 +33,24 @@ namespace Data.SeaHavenIndustries .HasIndex(u => new { u.DispatchId, u.Status }) .IsUnique() .HasFilter("[Status] = 'Pending'"); + + builder.Entity() + .HasIndex(l => new { l.WorkOrderId, l.FieldName }) + .IsUnique(); + + builder.Entity() + .Property(w => w.RowVersion) + .IsRowVersion(); + + builder.Entity() + .Property(d => d.RowVersion) + .IsRowVersion(); + + builder.Entity() + .HasOne(w => w.PrimaryDispatch) + .WithMany() + .HasForeignKey(w => w.PrimaryDispatchId) + .OnDelete(DeleteBehavior.Restrict); } public DbSet Categories { get; set; } public DbSet Locations { get; set; } @@ -47,6 +65,7 @@ namespace Data.SeaHavenIndustries public DbSet workOrderCategories { get; set; } public DbSet workOrderAttachments { get; set; } public DbSet WorkOrderAuditLogs { get; set; } + public DbSet WorkOrderFieldLocks { get; set; } public DbSet DropdownOptions { get; set; } public DbSet Vendors { get; set; } public DbSet VendorAccessTokens { get; set; } @@ -88,6 +107,8 @@ namespace Data.SeaHavenIndustries public DateTime? DeletedDate { get; set; } public bool? IsDeleted { get; set; } public string? UserImage { get; set; } + public string? Initials { get; set; } + public string? Color { get; set; } public int? Type { get; set; } // 1 for users 0 for admin public ICollection