using Dapper;using FastEndpoints;using Npgsql;using Shared.Problems;
namespace Modules.ERP.Items.Deactivate;
public sealed record Request(long Version);
public sealed record Response(Guid Id,long Version,string Status);
public sealed class Endpoint(NpgsqlDataSource dataSource):Endpoint<Request,Response>{public override void Configure(){Post("/api/erp/items/{id}/deactivate");Permissions("erp.item.write");}public override async Task HandleAsync(Request req,CancellationToken ct){var id=Route<Guid>("id");await using var c=await dataSource.OpenConnectionAsync(ct);await using var tx=await c.BeginTransactionAsync(ct);var current=await c.QuerySingleOrDefaultAsync<(long Version,bool Active)>(new CommandDefinition("select d.version as Version,i.is_active as Active from catalog.items i join catalog.item_details d on d.item_id=i.id where i.id=@Id for update",new{Id=id},tx,cancellationToken:ct));if(current.Version==0){await Send.ResponseAsync(KbxNotFoundProblem.Create("ITEM_NOT_FOUND","품목을 찾을 수 없습니다."),404,cancellation:ct);return;}if(current.Version!=req.Version){await Send.ResponseAsync(KbxConflictProblem.Version(current.Version),409,cancellation:ct);return;}var next=current.Version+1;var actor=User.Identity?.Name??"unknown";await c.ExecuteAsync(new CommandDefinition(@"update catalog.items set is_active=false where id=@Id;update catalog.item_details set version=@Version,updated_at=now(),updated_by=@Actor where item_id=@Id;update erp_item_search_projection set active=false,version=@Version where id=@Id;insert into audit.entries(id,aggregate_type,aggregate_id,action,actor,occurred_at,data) values(@AuditId,'Item',@Id,'ITEM_DEACTIVATED',@Actor,now(),jsonb_build_object('version',@Version));insert into integration.outbox(id,event_type,aggregate_id,payload,occurred_at,status) values(@EventId,'ItemDeactivated',@Id,jsonb_build_object('itemId',@Id,'version',@Version),now(),'PENDING');",new{Id=id,Version=next,Actor=actor,AuditId=Guid.NewGuid(),EventId=Guid.NewGuid()},tx,cancellationToken:ct));await tx.CommitAsync(ct);await Send.OkAsync(new(id,next,"사용중지"),ct);}}
