mirror of
https://github.com/azaion/missions.git
synced 2026-06-21 17:21:06 +00:00
2840ccb9b6
ci/woodpecker/push/build-arm Pipeline was successful
This commit transitions the project from Azaion.Flights to Azaion.Missions, updating namespaces, DTOs, services, and database entities accordingly. The Docker configuration and entry points have been modified to reflect the new project structure. Additionally, the README and documentation have been updated to clarify the ongoing renaming process and its implications. All references to flights have been replaced with missions, ensuring consistency across the codebase.
135 lines
4.9 KiB
C#
135 lines
4.9 KiB
C#
using System.Data;
|
|
using Azaion.Missions.Database;
|
|
using Azaion.Missions.Database.Entities;
|
|
using Azaion.Missions.DTOs;
|
|
|
|
namespace Azaion.Missions.Services;
|
|
|
|
public class VehicleService(AppDataConnection db)
|
|
{
|
|
// B12 (Option A): "exactly one default vehicle" is the user-visible truth.
|
|
// Every code path that sets is_default=true clears existing defaults and
|
|
// assigns the new default inside a Serializable transaction so two
|
|
// concurrent default-set ops cannot leave 0 or 2 defaults. The DB-level
|
|
// partial unique index `ux_vehicles_one_default` (DatabaseMigrator) is the
|
|
// belt-and-braces backstop if a future code path forgets the transaction.
|
|
public async Task<Vehicle> CreateVehicle(CreateVehicleRequest request)
|
|
{
|
|
var vehicle = new Vehicle
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Type = request.Type,
|
|
Model = request.Model,
|
|
Name = request.Name,
|
|
FuelType = request.FuelType,
|
|
BatteryCapacity = request.BatteryCapacity,
|
|
EngineConsumption = request.EngineConsumption,
|
|
EngineConsumptionIdle = request.EngineConsumptionIdle,
|
|
IsDefault = request.IsDefault
|
|
};
|
|
|
|
if (request.IsDefault)
|
|
{
|
|
await using var tx = await db.BeginTransactionAsync(IsolationLevel.Serializable);
|
|
await db.Vehicles.Where(v => v.IsDefault).Set(v => v.IsDefault, false).UpdateAsync();
|
|
await db.InsertAsync(vehicle);
|
|
await tx.CommitAsync();
|
|
}
|
|
else
|
|
{
|
|
await db.InsertAsync(vehicle);
|
|
}
|
|
|
|
return vehicle;
|
|
}
|
|
|
|
public async Task<Vehicle> UpdateVehicle(Guid id, UpdateVehicleRequest request)
|
|
{
|
|
var vehicle = await db.Vehicles.FirstOrDefaultAsync(v => v.Id == id)
|
|
?? throw new KeyNotFoundException($"Vehicle {id} not found");
|
|
|
|
if (request.Type.HasValue)
|
|
vehicle.Type = request.Type.Value;
|
|
if (request.Model != null)
|
|
vehicle.Model = request.Model;
|
|
if (request.Name != null)
|
|
vehicle.Name = request.Name;
|
|
if (request.FuelType.HasValue)
|
|
vehicle.FuelType = request.FuelType.Value;
|
|
if (request.BatteryCapacity.HasValue)
|
|
vehicle.BatteryCapacity = request.BatteryCapacity.Value;
|
|
if (request.EngineConsumption.HasValue)
|
|
vehicle.EngineConsumption = request.EngineConsumption.Value;
|
|
if (request.EngineConsumptionIdle.HasValue)
|
|
vehicle.EngineConsumptionIdle = request.EngineConsumptionIdle.Value;
|
|
|
|
if (request.IsDefault is true)
|
|
{
|
|
await using var tx = await db.BeginTransactionAsync(IsolationLevel.Serializable);
|
|
await db.Vehicles.Where(v => v.IsDefault && v.Id != id).Set(v => v.IsDefault, false).UpdateAsync();
|
|
vehicle.IsDefault = true;
|
|
await db.UpdateAsync(vehicle);
|
|
await tx.CommitAsync();
|
|
}
|
|
else
|
|
{
|
|
if (request.IsDefault is false)
|
|
vehicle.IsDefault = false;
|
|
await db.UpdateAsync(vehicle);
|
|
}
|
|
|
|
return vehicle;
|
|
}
|
|
|
|
public async Task<Vehicle> GetVehicle(Guid id)
|
|
{
|
|
var vehicle = await db.Vehicles.FirstOrDefaultAsync(v => v.Id == id)
|
|
?? throw new KeyNotFoundException($"Vehicle {id} not found");
|
|
return vehicle;
|
|
}
|
|
|
|
public async Task<List<Vehicle>> GetVehicles(GetVehiclesQuery query)
|
|
{
|
|
var q = db.Vehicles.AsQueryable();
|
|
|
|
if (!string.IsNullOrEmpty(query.Name))
|
|
q = q.Where(v => v.Name.ToLower().Contains(query.Name.ToLower()));
|
|
if (query.IsDefault.HasValue)
|
|
q = q.Where(v => v.IsDefault == query.IsDefault.Value);
|
|
|
|
return await q.OrderBy(v => v.Name).ToListAsync();
|
|
}
|
|
|
|
public async Task DeleteVehicle(Guid id)
|
|
{
|
|
var hasMissions = await db.Missions.AnyAsync(m => m.VehicleId == id);
|
|
if (hasMissions)
|
|
throw new InvalidOperationException($"Vehicle {id} is referenced by missions");
|
|
|
|
var vehicle = await db.Vehicles.FirstOrDefaultAsync(v => v.Id == id)
|
|
?? throw new KeyNotFoundException($"Vehicle {id} not found");
|
|
|
|
await db.Vehicles.DeleteAsync(v => v.Id == id);
|
|
}
|
|
|
|
public async Task SetDefault(Guid id, SetDefaultRequest request)
|
|
{
|
|
var vehicle = await db.Vehicles.FirstOrDefaultAsync(v => v.Id == id)
|
|
?? throw new KeyNotFoundException($"Vehicle {id} not found");
|
|
|
|
if (request.IsDefault)
|
|
{
|
|
await using var tx = await db.BeginTransactionAsync(IsolationLevel.Serializable);
|
|
await db.Vehicles.Where(v => v.IsDefault && v.Id != id).Set(v => v.IsDefault, false).UpdateAsync();
|
|
vehicle.IsDefault = true;
|
|
await db.UpdateAsync(vehicle);
|
|
await tx.CommitAsync();
|
|
}
|
|
else
|
|
{
|
|
vehicle.IsDefault = false;
|
|
await db.UpdateAsync(vehicle);
|
|
}
|
|
}
|
|
}
|