warrenchen 4631f82ee4 Add initial installer project and setup for MemberCenter
- Created MemberCenter.Installer project with references to Infrastructure, Application, and Domain projects.
- Added Program.cs with a basic console output.
- Generated MemberCenterDbContextModelSnapshot for database schema representation.
2026-02-03 15:04:18 +09:00

168 lines
6.6 KiB
C#

using MemberCenter.Domain.Entities;
using MemberCenter.Infrastructure.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace MemberCenter.Infrastructure.Persistence;
public class MemberCenterDbContext
: IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
public MemberCenterDbContext(DbContextOptions<MemberCenterDbContext> options)
: base(options)
{
}
public DbSet<Tenant> Tenants => Set<Tenant>();
public DbSet<NewsletterList> NewsletterLists => Set<NewsletterList>();
public DbSet<NewsletterSubscription> NewsletterSubscriptions => Set<NewsletterSubscription>();
public DbSet<EmailVerification> EmailVerifications => Set<EmailVerification>();
public DbSet<UnsubscribeToken> UnsubscribeTokens => Set<UnsubscribeToken>();
public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
public DbSet<SystemFlag> SystemFlags => Set<SystemFlag>();
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.UseOpenIddict();
builder.Entity<Tenant>(entity =>
{
entity.ToTable("tenants");
entity.HasKey(x => x.Id);
entity.Property(x => x.Name).IsRequired();
entity.Property(x => x.Status).IsRequired().HasDefaultValue("active");
entity.Property(x => x.Domains).HasColumnType("text[]");
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
});
builder.Entity<NewsletterList>(entity =>
{
entity.ToTable("newsletter_lists");
entity.HasKey(x => x.Id);
entity.Property(x => x.Name).IsRequired();
entity.Property(x => x.Status).IsRequired().HasDefaultValue("active");
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
entity.HasOne(x => x.Tenant)
.WithMany(t => t.NewsletterLists)
.HasForeignKey(x => x.TenantId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<NewsletterSubscription>(entity =>
{
entity.ToTable("newsletter_subscriptions");
entity.HasKey(x => x.Id);
entity.Property(x => x.Email).IsRequired();
entity.Property(x => x.Status).IsRequired().HasDefaultValue("pending");
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
entity.Property(x => x.Preferences)
.HasColumnType("jsonb")
.HasConversion(
v => v.RootElement.GetRawText(),
v => System.Text.Json.JsonDocument.Parse(v, new System.Text.Json.JsonDocumentOptions()));
entity.HasIndex(x => x.Email).HasDatabaseName("idx_newsletter_subscriptions_email");
entity.HasIndex(x => x.ListId).HasDatabaseName("idx_newsletter_subscriptions_list_id");
entity.HasIndex(x => new { x.ListId, x.Email }).IsUnique();
entity.HasOne(x => x.List)
.WithMany(l => l.Subscriptions)
.HasForeignKey(x => x.ListId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<EmailVerification>(entity =>
{
entity.ToTable("email_verifications");
entity.HasKey(x => x.Id);
entity.Property(x => x.Email).IsRequired();
entity.Property(x => x.TokenHash).IsRequired();
entity.Property(x => x.Purpose).IsRequired();
entity.HasIndex(x => x.Email).HasDatabaseName("idx_email_verifications_email");
entity.HasOne<Tenant>()
.WithMany()
.HasForeignKey(x => x.TenantId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<UnsubscribeToken>(entity =>
{
entity.ToTable("unsubscribe_tokens");
entity.HasKey(x => x.Id);
entity.Property(x => x.TokenHash).IsRequired();
entity.HasOne(x => x.Subscription)
.WithMany()
.HasForeignKey(x => x.SubscriptionId)
.OnDelete(DeleteBehavior.Cascade);
});
builder.Entity<AuditLog>(entity =>
{
entity.ToTable("audit_logs");
entity.HasKey(x => x.Id);
entity.Property(x => x.ActorType).IsRequired();
entity.Property(x => x.Action).IsRequired();
entity.Property(x => x.Payload)
.HasColumnType("jsonb")
.HasConversion(
v => v.RootElement.GetRawText(),
v => System.Text.Json.JsonDocument.Parse(v, new System.Text.Json.JsonDocumentOptions()));
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
});
builder.Entity<SystemFlag>(entity =>
{
entity.ToTable("system_flags");
entity.HasKey(x => x.Id);
entity.Property(x => x.Key).IsRequired();
entity.Property(x => x.Value).IsRequired();
entity.Property(x => x.UpdatedAt).HasDefaultValueSql("now()");
entity.HasIndex(x => x.Key).IsUnique();
});
builder.Entity<ApplicationUser>(entity =>
{
entity.ToTable("users");
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
});
builder.Entity<ApplicationRole>(entity =>
{
entity.ToTable("roles");
entity.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserRole<Guid>>(entity =>
{
entity.ToTable("user_roles");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserClaim<Guid>>(entity =>
{
entity.ToTable("user_claims");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityRoleClaim<Guid>>(entity =>
{
entity.ToTable("role_claims");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserLogin<Guid>>(entity =>
{
entity.ToTable("user_logins");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserToken<Guid>>(entity =>
{
entity.ToTable("user_tokens");
});
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserLogin<Guid>>().HasKey(l => new { l.LoginProvider, l.ProviderKey });
builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserToken<Guid>>().HasKey(t => new { t.UserId, t.LoginProvider, t.Name });
}
}