Add notification entities, DbContext config, and migration
Creates MemberChannelBinding, LineBindingCode, MessagingGroup, and NotificationLog entities under ROLAC.API.Entities.Notifications; wires DbSets and fluent config into AppDbContext; generates EF migration AddNotifications creating the four tables. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ROLAC.API.Data.Logging;
|
using ROLAC.API.Data.Logging;
|
||||||
using ROLAC.API.Entities;
|
using ROLAC.API.Entities;
|
||||||
|
using ROLAC.API.Entities.Notifications;
|
||||||
|
|
||||||
namespace ROLAC.API.Data;
|
namespace ROLAC.API.Data;
|
||||||
|
|
||||||
@@ -26,6 +27,11 @@ public class AppDbContext : IdentityDbContext<AppUser, AppRole, string>
|
|||||||
public DbSet<MealAttendance> MealAttendances => Set<MealAttendance>();
|
public DbSet<MealAttendance> MealAttendances => Set<MealAttendance>();
|
||||||
public DbSet<RolePermission> RolePermissions => Set<RolePermission>();
|
public DbSet<RolePermission> RolePermissions => Set<RolePermission>();
|
||||||
|
|
||||||
|
public DbSet<MemberChannelBinding> MemberChannelBindings => Set<MemberChannelBinding>();
|
||||||
|
public DbSet<LineBindingCode> LineBindingCodes => Set<LineBindingCode>();
|
||||||
|
public DbSet<MessagingGroup> MessagingGroups => Set<MessagingGroup>();
|
||||||
|
public DbSet<NotificationLog> NotificationLogs => Set<NotificationLog>();
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
base.OnModelCreating(builder);
|
base.OnModelCreating(builder);
|
||||||
@@ -326,6 +332,49 @@ public class AppDbContext : IdentityDbContext<AppUser, AppRole, string>
|
|||||||
entity.HasIndex(e => new { e.Year, e.Month }).IsUnique();
|
entity.HasIndex(e => new { e.Year, e.Month }).IsUnique();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── Notifications (email + Line) ─────────────────────────────────────
|
||||||
|
builder.Entity<MemberChannelBinding>(entity =>
|
||||||
|
{
|
||||||
|
entity.Property(e => e.Channel).HasMaxLength(20).IsRequired();
|
||||||
|
entity.Property(e => e.ExternalId).HasMaxLength(100).IsRequired();
|
||||||
|
entity.HasIndex(e => new { e.MemberId, e.Channel }).IsUnique();
|
||||||
|
entity.HasIndex(e => new { e.Channel, e.ExternalId }).IsUnique();
|
||||||
|
entity.HasOne(e => e.Member).WithMany()
|
||||||
|
.HasForeignKey(e => e.MemberId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<LineBindingCode>(entity =>
|
||||||
|
{
|
||||||
|
entity.Property(e => e.Code).HasMaxLength(20).IsRequired();
|
||||||
|
entity.HasIndex(e => e.Code);
|
||||||
|
entity.HasOne(e => e.Member).WithMany()
|
||||||
|
.HasForeignKey(e => e.MemberId).OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<MessagingGroup>(entity =>
|
||||||
|
{
|
||||||
|
entity.Property(e => e.Channel).HasMaxLength(20).IsRequired();
|
||||||
|
entity.Property(e => e.ExternalId).HasMaxLength(100).IsRequired();
|
||||||
|
entity.Property(e => e.Name).HasMaxLength(200);
|
||||||
|
entity.HasIndex(e => new { e.Channel, e.ExternalId }).IsUnique();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Entity<NotificationLog>(entity =>
|
||||||
|
{
|
||||||
|
entity.Property(e => e.Channel).HasMaxLength(20).IsRequired();
|
||||||
|
entity.Property(e => e.TargetType).HasMaxLength(20).IsRequired();
|
||||||
|
entity.Property(e => e.TargetExternalId).HasMaxLength(200).IsRequired();
|
||||||
|
entity.Property(e => e.Subject).HasMaxLength(300);
|
||||||
|
entity.Property(e => e.Status).HasMaxLength(20).IsRequired();
|
||||||
|
entity.Property(e => e.SentByUserId).HasMaxLength(450).IsRequired();
|
||||||
|
entity.HasIndex(e => e.SentAt);
|
||||||
|
entity.HasIndex(e => e.Channel);
|
||||||
|
entity.HasOne(e => e.Member).WithMany()
|
||||||
|
.HasForeignKey(e => e.MemberId).OnDelete(DeleteBehavior.SetNull);
|
||||||
|
entity.HasOne(e => e.MessagingGroup).WithMany()
|
||||||
|
.HasForeignKey(e => e.MessagingGroupId).OnDelete(DeleteBehavior.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
// ── SystemLog / AuditLog (append-only) ───────────────────────────────
|
// ── SystemLog / AuditLog (append-only) ───────────────────────────────
|
||||||
// Mapped here for SCHEMA only — there are deliberately no DbSets on this
|
// Mapped here for SCHEMA only — there are deliberately no DbSets on this
|
||||||
// context, so business code can't write logs through the audited context.
|
// context, so business code can't write logs through the audited context.
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using ROLAC.API.Entities;
|
||||||
|
|
||||||
|
namespace ROLAC.API.Entities.Notifications;
|
||||||
|
|
||||||
|
/// <summary>A short-lived code a member types to the Line bot to complete account binding.</summary>
|
||||||
|
public class LineBindingCode
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Code { get; set; } = null!;
|
||||||
|
public int MemberId { get; set; }
|
||||||
|
public Member? Member { get; set; }
|
||||||
|
public DateTime ExpiresAt { get; set; }
|
||||||
|
public DateTime? ConsumedAt { get; set; } // null = unused
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using ROLAC.API.Entities;
|
||||||
|
|
||||||
|
namespace ROLAC.API.Entities.Notifications;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Binds a member to an external channel account (e.g. a Line userId). Separate table so future
|
||||||
|
/// channels don't require changes to Member.
|
||||||
|
/// </summary>
|
||||||
|
public class MemberChannelBinding
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int MemberId { get; set; }
|
||||||
|
public Member? Member { get; set; }
|
||||||
|
public string Channel { get; set; } = null!; // "line"
|
||||||
|
public string ExternalId { get; set; } = null!; // Line userId
|
||||||
|
public DateTime BoundAt { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace ROLAC.API.Entities.Notifications;
|
||||||
|
|
||||||
|
/// <summary>A Line group the bot was added to. Named by an admin after the join event.</summary>
|
||||||
|
public class MessagingGroup
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Channel { get; set; } = null!; // "line"
|
||||||
|
public string ExternalId { get; set; } = null!; // Line groupId
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public bool IsActive { get; set; } = true;
|
||||||
|
public DateTime RegisteredAt { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using ROLAC.API.Entities;
|
||||||
|
|
||||||
|
namespace ROLAC.API.Entities.Notifications;
|
||||||
|
|
||||||
|
/// <summary>An append-only audit row for every email or Line send (success or failure).</summary>
|
||||||
|
public class NotificationLog
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string Channel { get; set; } = null!; // "email" | "line"
|
||||||
|
public string TargetType { get; set; } = null!; // "email" | "user" | "group"
|
||||||
|
public string TargetExternalId { get; set; } = null!; // email address OR Line id
|
||||||
|
public string? Subject { get; set; } // email only
|
||||||
|
public int? MemberId { get; set; }
|
||||||
|
public Member? Member { get; set; }
|
||||||
|
public int? MessagingGroupId { get; set; }
|
||||||
|
public MessagingGroup? MessagingGroup { get; set; }
|
||||||
|
public string Body { get; set; } = null!;
|
||||||
|
public string Status { get; set; } = null!; // "sent" | "failed"
|
||||||
|
public string? Error { get; set; }
|
||||||
|
public string SentByUserId { get; set; } = null!;
|
||||||
|
public DateTime SentAt { get; set; }
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,176 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ROLAC.API.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddNotifications : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "LineBindingCodes",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Code = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
MemberId = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
ExpiresAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||||
|
ConsumedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_LineBindingCodes", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_LineBindingCodes_Members_MemberId",
|
||||||
|
column: x => x.MemberId,
|
||||||
|
principalTable: "Members",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "MemberChannelBindings",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
MemberId = table.Column<int>(type: "integer", nullable: false),
|
||||||
|
Channel = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
ExternalId = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
|
BoundAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_MemberChannelBindings", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_MemberChannelBindings_Members_MemberId",
|
||||||
|
column: x => x.MemberId,
|
||||||
|
principalTable: "Members",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "MessagingGroups",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Channel = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
ExternalId = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
||||||
|
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
RegisteredAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_MessagingGroups", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "NotificationLogs",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
Channel = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
TargetType = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
TargetExternalId = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||||
|
Subject = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: true),
|
||||||
|
MemberId = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
MessagingGroupId = table.Column<int>(type: "integer", nullable: true),
|
||||||
|
Body = table.Column<string>(type: "text", nullable: false),
|
||||||
|
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||||
|
Error = table.Column<string>(type: "text", nullable: true),
|
||||||
|
SentByUserId = table.Column<string>(type: "character varying(450)", maxLength: 450, nullable: false),
|
||||||
|
SentAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_NotificationLogs", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_NotificationLogs_Members_MemberId",
|
||||||
|
column: x => x.MemberId,
|
||||||
|
principalTable: "Members",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_NotificationLogs_MessagingGroups_MessagingGroupId",
|
||||||
|
column: x => x.MessagingGroupId,
|
||||||
|
principalTable: "MessagingGroups",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.SetNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_LineBindingCodes_Code",
|
||||||
|
table: "LineBindingCodes",
|
||||||
|
column: "Code");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_LineBindingCodes_MemberId",
|
||||||
|
table: "LineBindingCodes",
|
||||||
|
column: "MemberId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_MemberChannelBindings_Channel_ExternalId",
|
||||||
|
table: "MemberChannelBindings",
|
||||||
|
columns: new[] { "Channel", "ExternalId" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_MemberChannelBindings_MemberId_Channel",
|
||||||
|
table: "MemberChannelBindings",
|
||||||
|
columns: new[] { "MemberId", "Channel" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_MessagingGroups_Channel_ExternalId",
|
||||||
|
table: "MessagingGroups",
|
||||||
|
columns: new[] { "Channel", "ExternalId" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_NotificationLogs_Channel",
|
||||||
|
table: "NotificationLogs",
|
||||||
|
column: "Channel");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_NotificationLogs_MemberId",
|
||||||
|
table: "NotificationLogs",
|
||||||
|
column: "MemberId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_NotificationLogs_MessagingGroupId",
|
||||||
|
table: "NotificationLogs",
|
||||||
|
column: "MessagingGroupId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_NotificationLogs_SentAt",
|
||||||
|
table: "NotificationLogs",
|
||||||
|
column: "SentAt");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "LineBindingCodes");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "MemberChannelBindings");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "NotificationLogs");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "MessagingGroups");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1323,6 +1323,174 @@ namespace ROLAC.API.Migrations
|
|||||||
b.ToTable("MonthlyStatements");
|
b.ToTable("MonthlyStatements");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.LineBindingCode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Code")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("ConsumedAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<int>("MemberId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Code");
|
||||||
|
|
||||||
|
b.HasIndex("MemberId");
|
||||||
|
|
||||||
|
b.ToTable("LineBindingCodes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.MemberChannelBinding", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("BoundAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Channel")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<int>("MemberId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Channel", "ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("MemberId", "Channel")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("MemberChannelBindings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.MessagingGroup", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Channel")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("ExternalId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsActive")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RegisteredAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Channel", "ExternalId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("MessagingGroups");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.NotificationLog", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
|
||||||
|
|
||||||
|
b.Property<string>("Body")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Channel")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("Error")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<int?>("MemberId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<int?>("MessagingGroupId")
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
b.Property<DateTime>("SentAt")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("SentByUserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(450)
|
||||||
|
.HasColumnType("character varying(450)");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.Property<string>("Subject")
|
||||||
|
.HasMaxLength(300)
|
||||||
|
.HasColumnType("character varying(300)");
|
||||||
|
|
||||||
|
b.Property<string>("TargetExternalId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("character varying(200)");
|
||||||
|
|
||||||
|
b.Property<string>("TargetType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Channel");
|
||||||
|
|
||||||
|
b.HasIndex("MemberId");
|
||||||
|
|
||||||
|
b.HasIndex("MessagingGroupId");
|
||||||
|
|
||||||
|
b.HasIndex("SentAt");
|
||||||
|
|
||||||
|
b.ToTable("NotificationLogs");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ROLAC.API.Entities.OfferingSession", b =>
|
modelBuilder.Entity("ROLAC.API.Entities.OfferingSession", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -1645,6 +1813,45 @@ namespace ROLAC.API.Migrations
|
|||||||
b.Navigation("FamilyUnit");
|
b.Navigation("FamilyUnit");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.LineBindingCode", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ROLAC.API.Entities.Member", "Member")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("MemberId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Member");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.MemberChannelBinding", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ROLAC.API.Entities.Member", "Member")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("MemberId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Member");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("ROLAC.API.Entities.Notifications.NotificationLog", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("ROLAC.API.Entities.Member", "Member")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("MemberId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
|
b.HasOne("ROLAC.API.Entities.Notifications.MessagingGroup", "MessagingGroup")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("MessagingGroupId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
|
b.Navigation("Member");
|
||||||
|
|
||||||
|
b.Navigation("MessagingGroup");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("ROLAC.API.Entities.RefreshToken", b =>
|
modelBuilder.Entity("ROLAC.API.Entities.RefreshToken", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("ROLAC.API.Entities.AppUser", "User")
|
b.HasOne("ROLAC.API.Entities.AppUser", "User")
|
||||||
|
|||||||
Reference in New Issue
Block a user