feat(api): .NET 10 multi-tenant REST API
Full backend implementation: - Multi-tenant cafe/restaurant management (menus, orders, tables, staff) - POS order flow with ZarinPal and Snappfood payment integration - OTP authentication via Kavenegar SMS - QR digital menu with public discover/finder endpoints - Customer loyalty, coupons, CRM - PostgreSQL via EF Core, Redis for caching/sessions - Background jobs, webhook handlers - Full migration history Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Meezi.Infrastructure.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SystemAdminPlatform : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsSuspended",
|
||||
table: "Cafes",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CafeFeatureOverrides",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
FeatureKey = table.Column<string>(type: "character varying(80)", maxLength: 80, nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
CafeId = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CafeFeatureOverrides", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CafeFeatureOverrides_Cafes_CafeId",
|
||||
column: x => x.CafeId,
|
||||
principalTable: "Cafes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PlatformFeatures",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Key = table.Column<string>(type: "character varying(80)", maxLength: 80, nullable: false),
|
||||
DisplayNameFa = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
DisplayNameEn = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
||||
ModuleGroup = table.Column<string>(type: "character varying(60)", maxLength: 60, nullable: false),
|
||||
IsEnabledGlobally = table.Column<bool>(type: "boolean", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PlatformFeatures", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PlatformPlanDefinitions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Tier = table.Column<int>(type: "integer", nullable: false),
|
||||
DisplayNameFa = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
DisplayNameEn = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: true),
|
||||
MonthlyPriceToman = table.Column<decimal>(type: "numeric(18,0)", precision: 18, scale: 0, nullable: false),
|
||||
IsBillableOnline = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
SortOrder = table.Column<int>(type: "integer", nullable: false),
|
||||
LimitsJson = table.Column<string>(type: "character varying(4000)", maxLength: 4000, nullable: false),
|
||||
FeaturesJson = table.Column<string>(type: "character varying(4000)", maxLength: 4000, nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PlatformPlanDefinitions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PlatformSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Key = table.Column<string>(type: "character varying(120)", maxLength: 120, nullable: false),
|
||||
Value = table.Column<string>(type: "character varying(8000)", maxLength: 8000, nullable: false),
|
||||
Category = table.Column<string>(type: "character varying(60)", maxLength: 60, nullable: false),
|
||||
DescriptionFa = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PlatformSettings", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SupportTickets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Subject = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
|
||||
Status = table.Column<int>(type: "integer", nullable: false),
|
||||
Priority = table.Column<int>(type: "integer", nullable: false),
|
||||
CreatedByEmployeeId = table.Column<string>(type: "text", nullable: false),
|
||||
AssignedAdminId = table.Column<string>(type: "text", nullable: true),
|
||||
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ClosedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
CafeId = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SupportTickets", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SupportTickets_Cafes_CafeId",
|
||||
column: x => x.CafeId,
|
||||
principalTable: "Cafes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_SupportTickets_Employees_CreatedByEmployeeId",
|
||||
column: x => x.CreatedByEmployeeId,
|
||||
principalTable: "Employees",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SystemAdmins",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Phone = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SystemAdmins", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "SupportTicketMessages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
TicketId = table.Column<string>(type: "text", nullable: false),
|
||||
SenderKind = table.Column<int>(type: "integer", nullable: false),
|
||||
SenderId = table.Column<string>(type: "text", nullable: false),
|
||||
Body = table.Column<string>(type: "character varying(8000)", maxLength: 8000, nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DeletedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_SupportTicketMessages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_SupportTicketMessages_SupportTickets_TicketId",
|
||||
column: x => x.TicketId,
|
||||
principalTable: "SupportTickets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CafeFeatureOverrides_CafeId_FeatureKey",
|
||||
table: "CafeFeatureOverrides",
|
||||
columns: new[] { "CafeId", "FeatureKey" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PlatformFeatures_Key",
|
||||
table: "PlatformFeatures",
|
||||
column: "Key",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PlatformPlanDefinitions_Tier",
|
||||
table: "PlatformPlanDefinitions",
|
||||
column: "Tier",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PlatformSettings_Key",
|
||||
table: "PlatformSettings",
|
||||
column: "Key",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SupportTicketMessages_TicketId_CreatedAt",
|
||||
table: "SupportTicketMessages",
|
||||
columns: new[] { "TicketId", "CreatedAt" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SupportTickets_CafeId_Status_UpdatedAt",
|
||||
table: "SupportTickets",
|
||||
columns: new[] { "CafeId", "Status", "UpdatedAt" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SupportTickets_CreatedByEmployeeId",
|
||||
table: "SupportTickets",
|
||||
column: "CreatedByEmployeeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_SystemAdmins_Phone",
|
||||
table: "SystemAdmins",
|
||||
column: "Phone",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "CafeFeatureOverrides");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PlatformFeatures");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PlatformPlanDefinitions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PlatformSettings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SupportTicketMessages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SystemAdmins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "SupportTickets");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsSuspended",
|
||||
table: "Cafes");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user