feat(guild): invite state machine

Add surrogate PK (IDENTITY bigint) to GuildInvite for wire invite_id.
Implement InviteAsync, CancelInviteAsync, RejectInviteAsync,
ListOutgoingInvitesAsync, ListInvitedGuildsAsync in GuildService.
Wire 5 endpoints: invite_user_list, invited_guild_list, invite,
cancel_invite, reject_invite in GuildController.
Migration: AddGuildInviteSurrogatePk — drops composite PK, adds Id
IDENTITY column, adds unique index on (GuildId, InviteeViewerId).
6 integration tests in GuildInviteFlowTests all green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-27 13:21:57 -04:00
parent c103ab6a87
commit 1b7fa2d525
12 changed files with 5574 additions and 22 deletions

View File

@@ -171,15 +171,21 @@ namespace SVSim.Database.Migrations
modelBuilder.Entity("SVSim.Database.Entities.Guild.GuildInvite", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<int>("GuildId")
.HasColumnType("integer");
b.Property<long>("InviteeViewerId")
.HasColumnType("bigint");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone");
b.Property<long>("InviterViewerId")
.HasColumnType("bigint");
@@ -189,7 +195,10 @@ namespace SVSim.Database.Migrations
b.Property<int>("Status")
.HasColumnType("integer");
b.HasKey("GuildId", "InviteeViewerId");
b.HasKey("Id");
b.HasIndex("GuildId", "InviteeViewerId")
.IsUnique();
b.HasIndex("InviteeViewerId", "Status");