using System.Text.Json; using Microsoft.Data.Sqlite; public sealed record CreateOrder(string OrderId,int Quantity); public sealed record InboxInput(string MessageId,string Payload,int Amount); public sealed record OrderedInput(string MessageId,string AggregateId,int Sequence,int Amount); public static class MessagingLabs { public static void Map(WebApplication app) { app.MapGet("/messaging/counts",(Store store)=>store.Counts()); app.MapPost("/outbox/orders", (CreateOrder input, bool? failBeforeCommit, Store store) => { if(input.OrderId!="demo" || input.Quantity is <1 or >10) return Results.BadRequest(); using var c=store.Open(); using var tx=c.BeginTransaction(); try { Store.Execute(c,"INSERT INTO orders(order_id,quantity) VALUES($id,$quantity)",tx,("$id",input.OrderId),("$quantity",input.Quantity)); Store.Execute(c,"INSERT INTO outbox(event_key,aggregate_id,sequence,payload) VALUES($key,$id,1,$payload)",tx,("$key","order-demo-v1"),("$id",input.OrderId),("$payload","quantity:"+input.Quantity)); } catch(SqliteException ex) when(ex.SqliteErrorCode==19) { tx.Rollback(); return Results.Conflict(new { error="Order or event identity already exists" }); } if(failBeforeCommit==true) { tx.Rollback(); return Results.Problem(statusCode:503,title:"Controlled pre-commit failure"); } tx.Commit(); return Results.Created("/outbox/orders/demo",new { input.OrderId,input.Quantity }); }); app.MapPost("/outbox/claim/{owner}",(string owner,Store store)=> { if(owner!="one"&&owner!="two") return Results.BadRequest(); long now=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); using var c=store.Open(); using var tx=c.BeginTransaction(); using var command=Store.Command(c,"UPDATE outbox SET owner=$owner,lease_until=$until,attempts=attempts+1 WHERE id=(SELECT id FROM outbox WHERE status='pending' AND (lease_until IS NULL OR lease_until<=$now) ORDER BY id LIMIT 1) RETURNING id,payload,attempts",tx,("$owner",owner),("$until",now+500),("$now",now)); object? row=null; using(var read=command.ExecuteReader()) if(read.Read()) row=new { id=read.GetInt64(0),payload=read.GetString(1),attempts=read.GetInt32(2),owner }; tx.Commit(); return row is null ? Results.NoContent() : Results.Ok(row); }); app.MapPost("/outbox/ack/{id:long}/{owner}",(long id,string owner,int generation,Store store)=> { using var c=store.Open(); int changed=Store.Execute(c,"UPDATE outbox SET status='sent' WHERE id=$id AND owner=$owner AND status='pending' AND lease_until>$now AND attempts=$generation",null,("$id",id),("$owner",owner),("$now",DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()),("$generation",generation)); return changed==1 ? Results.NoContent() : Results.Conflict(new { error="Lease is not currently owned" }); }); app.MapPost("/inbox/apply",(InboxInput input,bool? failBeforeCommit,Store store)=> { if(input.MessageId!="demo" || (string.IsNullOrWhiteSpace(input.Payload)||input.Payload.Length>50) || input.Amount is <1 or >10) return Results.BadRequest(); string canonical=JsonSerializer.Serialize(new { input.Payload,input.Amount }); using var c=store.Open(); using var tx=c.BeginTransaction(); using var check=Store.Command(c,"SELECT payload FROM inbox WHERE message_id=$id",tx,("$id",input.MessageId)); string? prior=check.ExecuteScalar() as string; if(prior is not null) { tx.Rollback(); return prior==canonical ? Results.Ok(new { replay=true }) : Results.Conflict(new { error="Payload conflict" }); } Store.Execute(c,"INSERT INTO inbox(message_id,payload) VALUES($id,$payload)",tx,("$id",input.MessageId),("$payload",canonical)); Store.Execute(c,"UPDATE effects SET total=total+$amount WHERE id=1",tx,("$amount",input.Amount)); if(failBeforeCommit==true) { tx.Rollback(); return Results.Problem(statusCode:503,title:"Controlled inbox failure"); } tx.Commit(); return Results.Ok(new { replay=false }); }); app.MapPost("/ordered/apply",(OrderedInput input,Store store)=> { if((string.IsNullOrWhiteSpace(input.MessageId)||input.MessageId.Length>20) || input.AggregateId!="demo" || input.Sequence is <1 or >10) return Results.BadRequest(); using var c=store.Open(); using var tx=c.BeginTransaction(); string canonical=JsonSerializer.Serialize(new { input.AggregateId,input.Sequence,input.Amount }); using var priorCommand=Store.Command(c,"SELECT payload FROM ordered_inbox WHERE message_id=$id",tx,("$id",input.MessageId)); string? prior=priorCommand.ExecuteScalar() as string; if(prior is not null) { tx.Rollback(); return prior==canonical ? Results.Ok(new { outcome="replay" }) : Results.Conflict(new { outcome="payload conflict" }); } Store.Execute(c,"INSERT OR IGNORE INTO aggregate_state VALUES($id,0,0)",tx,("$id",input.AggregateId)); long last=Store.Number(c,"SELECT last_sequence FROM aggregate_state WHERE aggregate_id=$id",tx,("$id",input.AggregateId)); if(input.Sequence!=last+1) { tx.Rollback(); return Results.Conflict(new { outcome=input.Sequence>last+1 ? "gap" : "stale",expected=last+1 }); } if(input.Amount<0) { Store.Execute(c,"INSERT OR IGNORE INTO deadletters VALUES($id,'negative amount')",tx,("$id",input.MessageId)); tx.Commit(); return Results.UnprocessableEntity(new { outcome="quarantined",expected=last+1 }); } Store.Execute(c,"INSERT INTO ordered_inbox VALUES($id,$payload)",tx,("$id",input.MessageId),("$payload",canonical)); Store.Execute(c,"UPDATE aggregate_state SET last_sequence=$sequence,total=total+$amount WHERE aggregate_id=$id",tx,("$sequence",input.Sequence),("$amount",input.Amount),("$id",input.AggregateId)); tx.Commit(); return Results.Ok(new { outcome="applied",sequence=input.Sequence }); }); app.MapGet("/ordered/state",(Store store)=> { using var c=store.Open(); return new { applied=Store.Number(c,"SELECT COUNT(*) FROM ordered_inbox"),deadletters=Store.Number(c,"SELECT COUNT(*) FROM deadletters"),last=Store.Number(c,"SELECT COALESCE(MAX(last_sequence),0) FROM aggregate_state") }; }); } }