diff --git a/booking.rest b/booking.rest index 390ef61..5dc528d 100644 --- a/booking.rest +++ b/booking.rest @@ -56,6 +56,21 @@ authorization: bearer {{Authenticate.response.body.access_token}} GET {{flight-api}} ### +### +# @name Create_Seat +Post {{api-gateway}}/api/v1/flight/seat +accept: application/json +Content-Type: application/json +authorization: bearer {{Authenticate.response.body.access_token}} + +{ + "seatNumber": "12H9", + "type": 1, + "class": 1, + "flightId": 1 +} +### + ### # @name Reserve_Seat @@ -66,7 +81,7 @@ authorization: bearer {{Authenticate.response.body.access_token}} { "flightId": 1, - "seatNumber": "12C" + "seatNumber": "12H9" } ### @@ -181,9 +196,9 @@ Content-Type: application/json authorization: bearer {{Authenticate.response.body.access_token}} { - "name": "airbus", - "model": "320", - "manufacturingYear": 2010 + "name": "airbus2", + "model": "322", + "manufacturingYear": 2012 } ### diff --git a/src/BuildingBlocks/Contracts/EventBus.Messages/FlighContracts.cs b/src/BuildingBlocks/Contracts/EventBus.Messages/FlighContracts.cs index c6d9bba..72b7a62 100644 --- a/src/BuildingBlocks/Contracts/EventBus.Messages/FlighContracts.cs +++ b/src/BuildingBlocks/Contracts/EventBus.Messages/FlighContracts.cs @@ -7,3 +7,5 @@ public record FlightUpdated(long Id) : IIntegrationEvent; public record FlightDeleted(long Id) : IIntegrationEvent; public record AircraftCreated(long Id) : IIntegrationEvent; public record AirportCreated(long Id) : IIntegrationEvent; +public record SeatCreated(long Id) : IIntegrationEvent; +public record SeatReserved(long Id) : IIntegrationEvent; diff --git a/src/Services/Flight/src/Flight/Aircrafts/Features/CreateAircraft/CreateAircraftCommand.cs b/src/Services/Flight/src/Flight/Aircrafts/Features/CreateAircraft/CreateAircraftCommand.cs index 2777974..71f0407 100644 --- a/src/Services/Flight/src/Flight/Aircrafts/Features/CreateAircraft/CreateAircraftCommand.cs +++ b/src/Services/Flight/src/Flight/Aircrafts/Features/CreateAircraft/CreateAircraftCommand.cs @@ -1,10 +1,11 @@ +using BuildingBlocks.Core.CQRS; using BuildingBlocks.IdsGenerator; using Flight.Aircrafts.Dtos; using MediatR; namespace Flight.Aircrafts.Features.CreateAircraft; -public record CreateAircraftCommand(string Name, string Model, int ManufacturingYear) : IRequest, IInternalCommand +public record CreateAircraftCommand(string Name, string Model, int ManufacturingYear) : ICommand, IInternalCommand { public long Id { get; set; } = SnowFlakIdGenerator.NewId(); } diff --git a/src/Services/Flight/src/Flight/Airports/Features/CreateAirport/CreateAirportCommand.cs b/src/Services/Flight/src/Flight/Airports/Features/CreateAirport/CreateAirportCommand.cs index b86d5d4..77f9eec 100644 --- a/src/Services/Flight/src/Flight/Airports/Features/CreateAirport/CreateAirportCommand.cs +++ b/src/Services/Flight/src/Flight/Airports/Features/CreateAirport/CreateAirportCommand.cs @@ -1,10 +1,11 @@ +using BuildingBlocks.Core.CQRS; using BuildingBlocks.IdsGenerator; using Flight.Airports.Dtos; using MediatR; namespace Flight.Airports.Features.CreateAirport; -public record CreateAirportCommand(string Name, string Address, string Code) : IRequest, IInternalCommand +public record CreateAirportCommand(string Name, string Address, string Code) : ICommand, IInternalCommand { public long Id { get; set; } = SnowFlakIdGenerator.NewId(); } diff --git a/src/Services/Flight/src/Flight/Data/FlightReadDbContext.cs b/src/Services/Flight/src/Flight/Data/FlightReadDbContext.cs index 7202e2a..e1b4540 100644 --- a/src/Services/Flight/src/Flight/Data/FlightReadDbContext.cs +++ b/src/Services/Flight/src/Flight/Data/FlightReadDbContext.cs @@ -3,6 +3,7 @@ using Flight.Aircrafts.Models.Reads; using Flight.Airports.Models; using Flight.Airports.Models.Reads; using Flight.Flights.Models.Reads; +using Flight.Seats.Models.Reads; using Humanizer; using Microsoft.Extensions.Options; using MongoDB.Driver; @@ -16,9 +17,11 @@ public class FlightReadDbContext : MongoDbContext Flight = GetCollection(nameof(Flight).Underscore()); Aircraft = GetCollection(nameof(Aircraft).Underscore()); Airport = GetCollection(nameof(Airport).Underscore()); + Seat = GetCollection(nameof(Seat).Underscore()); } public IMongoCollection Flight { get; } public IMongoCollection Aircraft { get; } public IMongoCollection Airport { get; } + public IMongoCollection Seat { get; } } diff --git a/src/Services/Flight/src/Flight/EventMapper.cs b/src/Services/Flight/src/Flight/EventMapper.cs index 8b1fbc9..44a6894 100644 --- a/src/Services/Flight/src/Flight/EventMapper.cs +++ b/src/Services/Flight/src/Flight/EventMapper.cs @@ -9,6 +9,9 @@ using Flight.Flights.Events.Domain; using Flight.Flights.Features.CreateFlight.Reads; using Flight.Flights.Features.DeleteFlight.Reads; using Flight.Flights.Features.UpdateFlight.Reads; +using Flight.Seats.Events; +using Flight.Seats.Features.CreateSeat.Reads; +using Flight.Seats.Features.ReserveSeat.Reads; namespace Flight; @@ -24,6 +27,8 @@ public sealed class EventMapper : IEventMapper FlightDeletedDomainEvent e => new FlightDeleted(e.Id), AirportCreatedDomainEvent e => new AirportCreated(e.Id), AircraftCreatedDomainEvent e => new AircraftCreated(e.Id), + SeatCreatedDomainEvent e => new SeatCreated(e.Id), + SeatReservedDomainEvent e => new SeatReserved(e.Id), _ => null }; } @@ -40,6 +45,8 @@ public sealed class EventMapper : IEventMapper e.ArriveDate, e.ArriveAirportId, e.DurationMinutes, e.FlightDate, e.Status, e.Price, e.IsDeleted), AircraftCreatedDomainEvent e => new CreateAircraftMongoCommand(e.Id, e.Name, e.Model, e.ManufacturingYear, e.IsDeleted), AirportCreatedDomainEvent e => new CreateAirportMongoCommand(e.Id, e.Name, e.Address, e.Code, e.IsDeleted), + SeatCreatedDomainEvent e => new CreateSeatMongoCommand(e.Id, e.SeatNumber, e.Type, e.Class, e.FlightId, e.IsDeleted), + SeatReservedDomainEvent e => new ReserveSeatMongoCommand(e.Id, e.SeatNumber, e.Type, e.Class, e.FlightId, e.IsDeleted), _ => null }; } diff --git a/src/Services/Flight/src/Flight/Flight.csproj b/src/Services/Flight/src/Flight/Flight.csproj index 46314ef..2eaa1a9 100644 --- a/src/Services/Flight/src/Flight/Flight.csproj +++ b/src/Services/Flight/src/Flight/Flight.csproj @@ -16,7 +16,6 @@ - diff --git a/src/Services/Flight/src/Flight/Flights/Features/GetAvailableFlights/GetAvailableFlightsQueryHandler.cs b/src/Services/Flight/src/Flight/Flights/Features/GetAvailableFlights/GetAvailableFlightsQueryHandler.cs index 717169f..8470dc9 100644 --- a/src/Services/Flight/src/Flight/Flights/Features/GetAvailableFlights/GetAvailableFlightsQueryHandler.cs +++ b/src/Services/Flight/src/Flight/Flights/Features/GetAvailableFlights/GetAvailableFlightsQueryHandler.cs @@ -8,20 +8,19 @@ using Flight.Data; using Flight.Flights.Dtos; using Flight.Flights.Exceptions; using MapsterMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; +using MongoDB.Driver; namespace Flight.Flights.Features.GetAvailableFlights; public class GetAvailableFlightsQueryHandler : IQueryHandler> { - private readonly FlightDbContext _flightDbContext; private readonly IMapper _mapper; + private readonly FlightReadDbContext _flightReadDbContext; - public GetAvailableFlightsQueryHandler(IMapper mapper, FlightDbContext flightDbContext) + public GetAvailableFlightsQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext) { _mapper = mapper; - _flightDbContext = flightDbContext; + _flightReadDbContext = flightReadDbContext; } public async Task> Handle(GetAvailableFlightsQuery query, @@ -29,7 +28,8 @@ public class GetAvailableFlightsQueryHandler : IQueryHandler !x.IsDeleted); if (!flight.Any()) throw new FlightNotFountException(); diff --git a/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdEndpoint.cs b/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdEndpoint.cs index d6678ad..ab355c2 100644 --- a/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdEndpoint.cs +++ b/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdEndpoint.cs @@ -10,18 +10,16 @@ using Swashbuckle.AspNetCore.Annotations; namespace Flight.Flights.Features.GetFlightById; [Route(BaseApiPath + "/flight")] -public class GetFlightByIdEndpoint: BaseController +public class GetFlightByIdEndpoint : BaseController { - // [Authorize] + [Authorize] [HttpGet("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [SwaggerOperation(Summary = "Get flight by id", Description = "Get flight by id")] public async Task GetById([FromRoute] GetFlightByIdQuery query, CancellationToken cancellationToken) { - throw new Exception(); var result = await Mediator.Send(query, cancellationToken); - return Ok(result); } } diff --git a/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdQueryHandler.cs b/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdQueryHandler.cs index ee41c89..4dc154f 100644 --- a/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdQueryHandler.cs +++ b/src/Services/Flight/src/Flight/Flights/Features/GetFlightById/GetFlightByIdQueryHandler.cs @@ -6,20 +6,20 @@ using Flight.Data; using Flight.Flights.Dtos; using Flight.Flights.Exceptions; using MapsterMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; +using MongoDB.Driver; +using MongoDB.Driver.Linq; namespace Flight.Flights.Features.GetFlightById; public class GetFlightByIdQueryHandler : IQueryHandler { - private readonly FlightDbContext _flightDbContext; private readonly IMapper _mapper; + private readonly FlightReadDbContext _flightReadDbContext; - public GetFlightByIdQueryHandler(IMapper mapper, FlightDbContext flightDbContext) + public GetFlightByIdQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext) { _mapper = mapper; - _flightDbContext = flightDbContext; + _flightReadDbContext = flightReadDbContext; } public async Task Handle(GetFlightByIdQuery query, CancellationToken cancellationToken) @@ -27,7 +27,7 @@ public class GetFlightByIdQueryHandler : IQueryHandler x.Id == query.Id, cancellationToken); + await _flightReadDbContext.Flight.AsQueryable().SingleOrDefaultAsync(x => x.Id == query.Id, cancellationToken); if (flight is null) throw new FlightNotFountException(); diff --git a/src/Services/Flight/src/Flight/Seats/Events/SeatCreatedDomainEvent.cs b/src/Services/Flight/src/Flight/Seats/Events/SeatCreatedDomainEvent.cs index ecd610e..294b3a5 100644 --- a/src/Services/Flight/src/Flight/Seats/Events/SeatCreatedDomainEvent.cs +++ b/src/Services/Flight/src/Flight/Seats/Events/SeatCreatedDomainEvent.cs @@ -3,4 +3,4 @@ using Flight.Seats.Models; namespace Flight.Seats.Events; -public record SeatCreatedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : IDomainEvent; +public record SeatCreatedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId, bool IsDeleted) : IDomainEvent; diff --git a/src/Services/Flight/src/Flight/Seats/Events/SeatReservedDomainEvent.cs b/src/Services/Flight/src/Flight/Seats/Events/SeatReservedDomainEvent.cs new file mode 100644 index 0000000..2fe4ca4 --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Events/SeatReservedDomainEvent.cs @@ -0,0 +1,6 @@ +using BuildingBlocks.Core.Event; +using Flight.Seats.Models; + +namespace Flight.Seats.Events; + +public record SeatReservedDomainEvent(long Id, string SeatNumber, SeatType Type, SeatClass Class, long FlightId, bool IsDeleted) : IDomainEvent; diff --git a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommand.cs b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommand.cs index fb44da7..a054583 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommand.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommand.cs @@ -1,11 +1,11 @@ +using BuildingBlocks.Core.CQRS; using BuildingBlocks.IdsGenerator; using Flight.Seats.Dtos; using Flight.Seats.Models; -using MediatR; namespace Flight.Seats.Features.CreateSeat; -public record CreateSeatCommand(string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : IRequest +public record CreateSeatCommand(string SeatNumber, SeatType Type, SeatClass Class, long FlightId) : ICommand, IInternalCommand { public long Id { get; set; } = SnowFlakIdGenerator.NewId(); } diff --git a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommandHandler.cs b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommandHandler.cs index 59eb3bc..08b26c9 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommandHandler.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/CreateSeatCommandHandler.cs @@ -40,8 +40,6 @@ public class CreateSeatCommandHandler : IRequestHandler(newSeat.Entity); } } diff --git a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommand.cs b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommand.cs new file mode 100644 index 0000000..5673895 --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommand.cs @@ -0,0 +1,25 @@ +using BuildingBlocks.Core.Event; +using Flight.Seats.Models; + +namespace Flight.Seats.Features.CreateSeat.Reads; + +public class CreateSeatMongoCommand : InternalCommand +{ + public CreateSeatMongoCommand(long id, string seatNumber, SeatType type, SeatClass @class, + long flightId, bool isDeleted) + { + Id = id; + SeatNumber = seatNumber; + Type = type; + Class = @class; + FlightId = flightId; + IsDeleted = isDeleted; + } + + public long Id { get; } + public string SeatNumber { get; } + public SeatType Type { get; } + public SeatClass Class { get; } + public long FlightId { get; } + public bool IsDeleted { get; } +} diff --git a/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommandHandler.cs b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommandHandler.cs new file mode 100644 index 0000000..47487fa --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Features/CreateSeat/Reads/CreateSeatMongoCommandHandler.cs @@ -0,0 +1,44 @@ +using System.Threading; +using System.Threading.Tasks; +using Ardalis.GuardClauses; +using BuildingBlocks.Core.CQRS; +using Flight.Data; +using Flight.Seats.Exceptions; +using Flight.Seats.Models.Reads; +using MapsterMapper; +using MediatR; +using MongoDB.Driver; +using MongoDB.Driver.Linq; + +namespace Flight.Seats.Features.CreateSeat.Reads; + +public class CreateSeatMongoCommandHandler : ICommandHandler +{ + private readonly FlightReadDbContext _flightReadDbContext; + private readonly IMapper _mapper; + + public CreateSeatMongoCommandHandler( + FlightReadDbContext flightReadDbContext, + IMapper mapper) + { + _flightReadDbContext = flightReadDbContext; + _mapper = mapper; + } + + public async Task Handle(CreateSeatMongoCommand command, CancellationToken cancellationToken) + { + Guard.Against.Null(command, nameof(command)); + + var seatReadModel = _mapper.Map(command); + + var seat = await _flightReadDbContext.Seat.AsQueryable() + .FirstOrDefaultAsync(x => x.Id == seatReadModel.Id, cancellationToken); + + if (seat is not null) + throw new SeatAlreadyExistException(); + + await _flightReadDbContext.Seat.InsertOneAsync(seatReadModel, cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQuery.cs b/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQuery.cs index 0c9df58..cf9e936 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQuery.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQuery.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; +using BuildingBlocks.Core.CQRS; using Flight.Seats.Dtos; using MediatR; namespace Flight.Seats.Features.GetAvailableSeats; -public record GetAvailableSeatsQuery(long FlightId) : IRequest>; +public record GetAvailableSeatsQuery(long FlightId) : IQuery>; diff --git a/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQueryHandler.cs b/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQueryHandler.cs index c88bf71..af0bb54 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQueryHandler.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/GetAvailableSeats/GetAvailableSeatsQueryHandler.cs @@ -8,19 +8,19 @@ using Flight.Seats.Dtos; using Flight.Seats.Exceptions; using MapsterMapper; using MediatR; -using Microsoft.EntityFrameworkCore; +using MongoDB.Driver; namespace Flight.Seats.Features.GetAvailableSeats; public class GetAvailableSeatsQueryHandler : IRequestHandler> { - private readonly FlightDbContext _flightDbContext; private readonly IMapper _mapper; + private readonly FlightReadDbContext _flightReadDbContext; - public GetAvailableSeatsQueryHandler(IMapper mapper, FlightDbContext flightDbContext) + public GetAvailableSeatsQueryHandler(IMapper mapper, FlightReadDbContext flightReadDbContext) { _mapper = mapper; - _flightDbContext = flightDbContext; + _flightReadDbContext = flightReadDbContext; } @@ -28,7 +28,8 @@ public class GetAvailableSeatsQueryHandler : IRequestHandler x.FlightId == query.FlightId).ToListAsync(cancellationToken); + var seats = (await _flightReadDbContext.Seat.AsQueryable().ToListAsync(cancellationToken)) + .Where(x => !x.IsDeleted); if (!seats.Any()) throw new AllSeatsFullException(); diff --git a/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommand.cs b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommand.cs new file mode 100644 index 0000000..bb9f5f8 --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommand.cs @@ -0,0 +1,25 @@ +using BuildingBlocks.Core.Event; +using Flight.Seats.Models; + +namespace Flight.Seats.Features.ReserveSeat.Reads; + +public class ReserveSeatMongoCommand : InternalCommand +{ + public ReserveSeatMongoCommand(long id, string seatNumber, SeatType type, SeatClass @class, long flightId, + bool isDeleted) + { + Id = id; + SeatNumber = seatNumber; + Type = type; + Class = @class; + FlightId = flightId; + IsDeleted = isDeleted; + } + + public long Id { get; } + public string SeatNumber { get; } + public SeatType Type { get; } + public SeatClass Class { get; } + public long FlightId { get; } + public bool IsDeleted { get; } +} diff --git a/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommandHandler.cs b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommandHandler.cs new file mode 100644 index 0000000..c479951 --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/Reads/ReserveSeatMongoCommandHandler.cs @@ -0,0 +1,40 @@ +using System.Threading; +using System.Threading.Tasks; +using Ardalis.GuardClauses; +using BuildingBlocks.Core.CQRS; +using Flight.Data; +using Flight.Seats.Models.Reads; +using MapsterMapper; +using MediatR; +using MongoDB.Driver; + +namespace Flight.Seats.Features.ReserveSeat.Reads; + +public class ReserveSeatMongoCommandHandler : ICommandHandler +{ + private readonly FlightReadDbContext _flightReadDbContext; + private readonly IMapper _mapper; + + public ReserveSeatMongoCommandHandler( + FlightReadDbContext flightReadDbContext, + IMapper mapper) + { + _flightReadDbContext = flightReadDbContext; + _mapper = mapper; + } + + public async Task Handle(ReserveSeatMongoCommand command, CancellationToken cancellationToken) + { + Guard.Against.Null(command, nameof(command)); + + var seatReadModel = _mapper.Map(command); + + await _flightReadDbContext.Seat.UpdateOneAsync( + x => x.SeatId == seatReadModel.SeatId, + Builders.Update + .Set(x => x.IsDeleted, seatReadModel.IsDeleted), + cancellationToken: cancellationToken); + + return Unit.Value; + } +} diff --git a/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/ReserveSeatCommand.cs b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/ReserveSeatCommand.cs index 96ae1d6..e291523 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/ReserveSeatCommand.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/ReserveSeat/ReserveSeatCommand.cs @@ -1,6 +1,6 @@ +using BuildingBlocks.Core.CQRS; using Flight.Seats.Dtos; -using MediatR; namespace Flight.Seats.Features.ReserveSeat; -public record ReserveSeatCommand(long FlightId, string SeatNumber) : IRequest; +public record ReserveSeatCommand(long FlightId, string SeatNumber) : ICommand, IInternalCommand; diff --git a/src/Services/Flight/src/Flight/Seats/Features/SeatMappings.cs b/src/Services/Flight/src/Flight/Seats/Features/SeatMappings.cs index d7c5c7e..4f62a2a 100644 --- a/src/Services/Flight/src/Flight/Seats/Features/SeatMappings.cs +++ b/src/Services/Flight/src/Flight/Seats/Features/SeatMappings.cs @@ -1,5 +1,9 @@ +using BuildingBlocks.IdsGenerator; using Flight.Seats.Dtos; +using Flight.Seats.Features.CreateSeat.Reads; +using Flight.Seats.Features.ReserveSeat.Reads; using Flight.Seats.Models; +using Flight.Seats.Models.Reads; using Mapster; namespace Flight.Seats.Features; @@ -9,6 +13,10 @@ public class SeatMappings : IRegister public void Register(TypeAdapterConfig config) { config.NewConfig(); + config.NewConfig() + .Map(d => d.Id, s => SnowFlakIdGenerator.NewId()) + .Map(d => d.SeatId, s => s.Id); + config.NewConfig() + .Map(d => d.SeatId, s => s.Id); } } - diff --git a/src/Services/Flight/src/Flight/Seats/Models/Reads/SeatReadModel.cs b/src/Services/Flight/src/Flight/Seats/Models/Reads/SeatReadModel.cs new file mode 100644 index 0000000..1d5bd1e --- /dev/null +++ b/src/Services/Flight/src/Flight/Seats/Models/Reads/SeatReadModel.cs @@ -0,0 +1,12 @@ +namespace Flight.Seats.Models.Reads; + +public class SeatReadModel +{ + public long Id { get; init; } + public long SeatId { get; init; } + public string SeatNumber { get; init; } + public SeatType Type { get; init; } + public SeatClass Class { get; init; } + public long FlightId { get; init; } + public bool IsDeleted { get; init; } +} diff --git a/src/Services/Flight/src/Flight/Seats/Models/Seat.cs b/src/Services/Flight/src/Flight/Seats/Models/Seat.cs index 098177f..2006556 100644 --- a/src/Services/Flight/src/Flight/Seats/Models/Seat.cs +++ b/src/Services/Flight/src/Flight/Seats/Models/Seat.cs @@ -1,12 +1,14 @@ using System; using System.Threading.Tasks; using BuildingBlocks.Core.Model; +using Flight.Seats.Events; namespace Flight.Seats.Models; public class Seat : Aggregate { - public static Seat Create(long id, string seatNumber, SeatType type, SeatClass @class, long flightId) + public static Seat Create(long id, string seatNumber, SeatType type, SeatClass @class, long flightId, + bool isDeleted = false) { var seat = new Seat() { @@ -14,9 +16,20 @@ public class Seat : Aggregate Class = @class, Type = type, SeatNumber = seatNumber, - FlightId = flightId + FlightId = flightId, + IsDeleted = isDeleted }; + var @event = new SeatCreatedDomainEvent( + seat.Id, + seat.SeatNumber, + seat.Type, + seat.Class, + seat.FlightId, + isDeleted); + + seat.AddDomainEvent(@event); + return seat; } @@ -24,6 +37,17 @@ public class Seat : Aggregate { seat.IsDeleted = true; seat.LastModified = DateTime.Now; + + var @event = new SeatReservedDomainEvent( + seat.Id, + seat.SeatNumber, + seat.Type, + seat.Class, + seat.FlightId, + seat.IsDeleted); + + seat.AddDomainEvent(@event); + return Task.FromResult(this); }