Files
marechai/Marechai.Database/Migrations/20260507111459_AddMessagingSystemAndDropAdminNotifications.cs
Natalia Portillo cb153d92b5 Add user messaging service
- Added Italian resource file for MessagingService with translations for various message-related terms.
- Removed English resource file for NotificationService as it is no longer needed.
- Updated German, Spanish, French, and Italian navigation menus to include "Message Reports" link.
- Introduced MessagingService to handle messaging functionalities, replacing the NotificationService.
- Updated AdminNavMenu and MainLayout to reflect changes in messaging and notification handling.
2026-05-07 13:03:46 +01:00

328 lines
16 KiB
C#

using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marechai.Database.Migrations
{
/// <inheritdoc />
public partial class AddMessagingSystemAndDropAdminNotifications : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AdminNotifications");
migrationBuilder.AddColumn<bool>(
name: "IsSystemAccount",
table: "AspNetUsers",
type: "bit(1)",
nullable: false,
defaultValue: false);
migrationBuilder.CreateTable(
name: "Conversations",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Subject = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsSystemThread = table.Column<bool>(type: "bit(1)", nullable: false),
CreatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UpdatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn)
},
constraints: table =>
{
table.PrimaryKey("PK_Conversations", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ConversationParticipants",
columns: table => new
{
ConversationId = table.Column<long>(type: "bigint", nullable: false),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
JoinedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false),
LeftOn = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_ConversationParticipants", x => new { x.ConversationId, x.UserId });
table.ForeignKey(
name: "FK_ConversationParticipants_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_ConversationParticipants_Conversations_ConversationId",
column: x => x.ConversationId,
principalTable: "Conversations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
ConversationId = table.Column<long>(type: "bigint", nullable: false),
SenderId = table.Column<string>(type: "varchar(255)", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Body = table.Column<string>(type: "varchar(5000)", maxLength: 5000, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsSystemAuthored = table.Column<bool>(type: "bit(1)", nullable: false),
ParentMessageId = table.Column<long>(type: "bigint", nullable: true),
CreatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UpdatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.Id);
table.ForeignKey(
name: "FK_Messages_AspNetUsers_SenderId",
column: x => x.SenderId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_Messages_Conversations_ConversationId",
column: x => x.ConversationId,
principalTable: "Conversations",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Messages_Messages_ParentMessageId",
column: x => x.ParentMessageId,
principalTable: "Messages",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "MessageReports",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
ReporterId = table.Column<string>(type: "varchar(255)", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
MessageId = table.Column<long>(type: "bigint", nullable: true),
Reason = table.Column<int>(type: "int", nullable: false),
Explanation = table.Column<string>(type: "varchar(2048)", maxLength: 2048, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IsResolved = table.Column<bool>(type: "bit(1)", nullable: false),
ResolvedByUserId = table.Column<string>(type: "varchar(255)", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ResolvedOn = table.Column<DateTime>(type: "datetime(6)", nullable: true),
CreatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UpdatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn)
},
constraints: table =>
{
table.PrimaryKey("PK_MessageReports", x => x.Id);
table.ForeignKey(
name: "FK_MessageReports_AspNetUsers_ReporterId",
column: x => x.ReporterId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_MessageReports_AspNetUsers_ResolvedByUserId",
column: x => x.ResolvedByUserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_MessageReports_Messages_MessageId",
column: x => x.MessageId,
principalTable: "Messages",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "MessageStates",
columns: table => new
{
MessageId = table.Column<long>(type: "bigint", nullable: false),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsRead = table.Column<bool>(type: "bit(1)", nullable: false),
ReadAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
DeletedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_MessageStates", x => new { x.MessageId, x.UserId });
table.ForeignKey(
name: "FK_MessageStates_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_MessageStates_Messages_MessageId",
column: x => x.MessageId,
principalTable: "Messages",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_ConversationParticipants_UserId",
table: "ConversationParticipants",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Conversations_IsSystemThread",
table: "Conversations",
column: "IsSystemThread");
migrationBuilder.CreateIndex(
name: "IX_MessageReports_IsResolved",
table: "MessageReports",
column: "IsResolved");
migrationBuilder.CreateIndex(
name: "IX_MessageReports_MessageId",
table: "MessageReports",
column: "MessageId");
migrationBuilder.CreateIndex(
name: "IX_MessageReports_ReporterId",
table: "MessageReports",
column: "ReporterId");
migrationBuilder.CreateIndex(
name: "IX_MessageReports_ResolvedByUserId",
table: "MessageReports",
column: "ResolvedByUserId");
migrationBuilder.CreateIndex(
name: "IX_Messages_ConversationId_CreatedOn",
table: "Messages",
columns: new[] { "ConversationId", "CreatedOn" });
migrationBuilder.CreateIndex(
name: "IX_Messages_ParentMessageId",
table: "Messages",
column: "ParentMessageId");
migrationBuilder.CreateIndex(
name: "IX_Messages_SenderId",
table: "Messages",
column: "SenderId");
migrationBuilder.CreateIndex(
name: "IX_MessageStates_UserId_IsRead_DeletedAt",
table: "MessageStates",
columns: new[] { "UserId", "IsRead", "DeletedAt" });
// Seed the built-in `system` user used for bot-authored messages (e.g. report notifications).
// Locked out indefinitely, no password, EmailConfirmed = false so it can never sign in.
// Idempotent — only inserted if it does not already exist.
migrationBuilder.Sql(
@"INSERT INTO `AspNetUsers`
(`Id`, `UserName`, `NormalizedUserName`, `Email`, `NormalizedEmail`, `EmailConfirmed`,
`PasswordHash`, `SecurityStamp`, `ConcurrencyStamp`, `PhoneNumber`, `PhoneNumberConfirmed`,
`TwoFactorEnabled`, `LockoutEnd`, `LockoutEnabled`, `AccessFailedCount`,
`DisplayName`, `UseGravatar`, `IsSystemAccount`)
SELECT '00000000-0000-0000-0000-00000000sys', 'system', 'SYSTEM', 'system@local', 'SYSTEM@LOCAL', 0,
NULL, UUID(), UUID(), NULL, 0,
0, '9999-12-31 23:59:59.000000', 1, 0,
'System', 0, 1
WHERE NOT EXISTS (SELECT 1 FROM `AspNetUsers` WHERE `Id` = '00000000-0000-0000-0000-00000000sys');");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(
"DELETE FROM `AspNetUsers` WHERE `Id` = '00000000-0000-0000-0000-00000000sys';");
migrationBuilder.DropTable(
name: "ConversationParticipants");
migrationBuilder.DropTable(
name: "MessageReports");
migrationBuilder.DropTable(
name: "MessageStates");
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable(
name: "Conversations");
migrationBuilder.DropColumn(
name: "IsSystemAccount",
table: "AspNetUsers");
migrationBuilder.CreateTable(
name: "AdminNotifications",
columns: table => new
{
Id = table.Column<long>(type: "bigint", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
TargetUserId = table.Column<string>(type: "varchar(255)", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
CreatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
IsRead = table.Column<bool>(type: "bit(1)", nullable: false),
LinkText = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
LinkUrl = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Message = table.Column<string>(type: "varchar(1024)", maxLength: 1024, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
NotificationType = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Title = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
UpdatedOn = table.Column<DateTime>(type: "datetime(6)", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.ComputedColumn)
},
constraints: table =>
{
table.PrimaryKey("PK_AdminNotifications", x => x.Id);
table.ForeignKey(
name: "FK_AdminNotifications_AspNetUsers_TargetUserId",
column: x => x.TargetUserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AdminNotifications_IsRead_TargetUserId",
table: "AdminNotifications",
columns: new[] { "IsRead", "TargetUserId" });
migrationBuilder.CreateIndex(
name: "IX_AdminNotifications_TargetUserId",
table: "AdminNotifications",
column: "TargetUserId");
}
}
}