61991bf6cd
Adds the access foundation everything else enforces against. SharedKernel (shared access contracts, no Identity dependency for consumers): - ScopeRef/ScopeType, RoleType, Capability, AccessPolicy (role x capability matrix), ICurrentUser, IPermissionService (scope-chain evaluation). Identity module: - Member, Membership, Invitation entities; internal IdentityDbContext (schema "identity") + InitialIdentity migration; design-time factory. - JWT auth (HS256) issuing membership claims; PasswordHasher<Member>; CurrentUser (claims -> ICurrentUser) and PermissionService implementations. - Public IMemberDirectory contract for other modules to resolve member display info. - Endpoints: POST /bootstrap (first owner), /auth/login, GET /me, POST /invitations, POST /invitations/accept. Owner-only actions enforced via IPermissionService. - Web host wires UseAuthentication/UseAuthorization and string-enum JSON. Verified: build green; ArchitectureTests 8/8 (Identity references only SharedKernel); IntegrationTests 11/11 incl. a new end-to-end flow — bootstrap -> login -> /me -> invite -> accept -> login as invitee, and a Member is 403'd from inviting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
154 lines
5.3 KiB
C#
154 lines
5.3 KiB
C#
// <auto-generated />
|
|
using System;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
using TeamUp.Modules.Identity.Persistence;
|
|
|
|
#nullable disable
|
|
|
|
namespace TeamUp.Modules.Identity.Persistence.Migrations
|
|
{
|
|
[DbContext(typeof(IdentityDbContext))]
|
|
partial class IdentityDbContextModelSnapshot : ModelSnapshot
|
|
{
|
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
|
{
|
|
#pragma warning disable 612, 618
|
|
modelBuilder
|
|
.HasDefaultSchema("identity")
|
|
.HasAnnotation("ProductVersion", "10.0.8")
|
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
|
|
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
|
|
|
modelBuilder.Entity("TeamUp.Modules.Identity.Domain.Invitation", b =>
|
|
{
|
|
b.Property<Guid>("Id")
|
|
.ValueGeneratedOnAdd()
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<DateTimeOffset?>("AcceptedAtUtc")
|
|
.HasColumnType("timestamp with time zone");
|
|
|
|
b.Property<DateTimeOffset>("CreatedAtUtc")
|
|
.HasColumnType("timestamp with time zone");
|
|
|
|
b.Property<string>("Email")
|
|
.IsRequired()
|
|
.HasMaxLength(256)
|
|
.HasColumnType("character varying(256)");
|
|
|
|
b.Property<Guid>("InvitedByMemberId")
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<string>("Role")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.Property<Guid>("ScopeId")
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<string>("ScopeType")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.Property<string>("Status")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.Property<string>("Token")
|
|
.IsRequired()
|
|
.HasMaxLength(128)
|
|
.HasColumnType("character varying(128)");
|
|
|
|
b.HasKey("Id");
|
|
|
|
b.HasIndex("Email");
|
|
|
|
b.HasIndex("Token")
|
|
.IsUnique();
|
|
|
|
b.ToTable("invitations", "identity");
|
|
});
|
|
|
|
modelBuilder.Entity("TeamUp.Modules.Identity.Domain.Member", b =>
|
|
{
|
|
b.Property<Guid>("Id")
|
|
.ValueGeneratedOnAdd()
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<DateTimeOffset>("CreatedAtUtc")
|
|
.HasColumnType("timestamp with time zone");
|
|
|
|
b.Property<string>("DisplayName")
|
|
.IsRequired()
|
|
.HasMaxLength(128)
|
|
.HasColumnType("character varying(128)");
|
|
|
|
b.Property<string>("Email")
|
|
.IsRequired()
|
|
.HasMaxLength(256)
|
|
.HasColumnType("character varying(256)");
|
|
|
|
b.Property<string>("PasswordHash")
|
|
.IsRequired()
|
|
.HasMaxLength(512)
|
|
.HasColumnType("character varying(512)");
|
|
|
|
b.Property<string>("Status")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.HasKey("Id");
|
|
|
|
b.HasIndex("Email")
|
|
.IsUnique();
|
|
|
|
b.ToTable("members", "identity");
|
|
});
|
|
|
|
modelBuilder.Entity("TeamUp.Modules.Identity.Domain.Membership", b =>
|
|
{
|
|
b.Property<Guid>("Id")
|
|
.ValueGeneratedOnAdd()
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<DateTimeOffset>("CreatedAtUtc")
|
|
.HasColumnType("timestamp with time zone");
|
|
|
|
b.Property<Guid>("MemberId")
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<string>("Role")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.Property<Guid>("ScopeId")
|
|
.HasColumnType("uuid");
|
|
|
|
b.Property<string>("ScopeType")
|
|
.IsRequired()
|
|
.HasMaxLength(32)
|
|
.HasColumnType("character varying(32)");
|
|
|
|
b.HasKey("Id");
|
|
|
|
b.HasIndex("MemberId");
|
|
|
|
b.HasIndex("MemberId", "ScopeType", "ScopeId", "Role")
|
|
.IsUnique();
|
|
|
|
b.ToTable("memberships", "identity");
|
|
});
|
|
#pragma warning restore 612, 618
|
|
}
|
|
}
|
|
}
|