Phase 1.5: EF Migration + Data Seed + Backfill

MIGRATION (AddPackageBasedSystem):
- Adds 11 new columns to Packages table
- Creates PackageFeatures table (Package×ClubFeature junction)
- Adds PackageId FK to: ClubMembershipCycles, WeeklyCommissionPools,
  UserCommissionPayouts, NetworkWeeklyBalances, UserWalletChangeLogs
- Adds First/LastActivationDate, First/LastPackageId to ClubMemberships
- Drops old unique indexes, creates new composite unique indexes:
  (WeekDef,Package), (User,WeekDef,Package)

DATA MIGRATION (embedded in EF migration):
1. Seeds Golden Package (Id=1): Price=56M, ActivationFee=25.2M,
   DiscountMultiplier=2.0, MagicWalletMultiplier=2.5, MaxBalancesPerLeg=300,
   MaxNetworkLevel=15, MagicWalletMaxDeposit=1B, MagicWalletMaxCredit=2.5B
2. Backfills PackageId=1 on all existing commission/network records
3. Backfills ClubMembership First/Last fields from existing ActivatedAt

FIXES:
- ClubMembership First/Last fields now nullable (DateTime?, long?)
  for backward compat with existing records
- UserPackagePurchaseConfiguration: .WithMany() → .WithMany(p => p.Purchases)
  to prevent shadow FK PackageId1

Build: 0 errors, 73 warnings
This commit is contained in:
masoodafar-web
2026-02-25 22:49:12 +03:30
parent ae92ab8697
commit a9cd2fd67a
6 changed files with 6033 additions and 14 deletions
@@ -0,0 +1,90 @@
-- =============================================
-- Data Migration: Package-Based System
-- Date: 2026-02-25
-- Description: Seeds golden package and backfills
-- existing records with PackageId = 1
-- NOTE: This is automatically executed in the EF Migration
-- (AddPackageBasedSystem). This file is for reference only.
-- =============================================
USE [YourDatabaseName]; -- Replace with actual DB name
GO
-- 1. Seed Golden Package (Id=1)
SET IDENTITY_INSERT [CMS].[Packages] ON;
IF NOT EXISTS (SELECT 1 FROM [CMS].[Packages] WHERE [Id] = 1)
BEGIN
INSERT INTO [CMS].[Packages]
([Id], [Title], [Description], [ImagePath], [Price],
[SortOrder], [IsActive], [IsBasePackage],
[SupportsDayaPurchase], [SupportsDirectPurchase],
[ActivationFee], [DiscountMultiplier], [MagicWalletMultiplier],
[MaxBalancesPerLeg], [MaxNetworkLevel],
[MagicWalletMaxDeposit], [MagicWalletMaxCredit],
[Created], [IsDeleted])
VALUES
(1, N'پکیج طلایی', N'پکیج اصلی باشگاه مشتریان کارا بازار سلامت',
N'/images/packages/golden.png', 56000000,
1, 1, 1,
1, 1,
25200000, 2.0, 2.5,
300, 15,
1000000000, 2500000000,
GETUTCDATE(), 0);
PRINT 'Golden Package (Id=1) seeded successfully.';
END
ELSE
BEGIN
PRINT 'Golden Package (Id=1) already exists. Skipping seed.';
END
SET IDENTITY_INSERT [CMS].[Packages] OFF;
GO
-- 2. Backfill PackageId on commission/network tables
UPDATE [CMS].[WeeklyCommissionPools] SET [PackageId] = 1 WHERE [PackageId] = 0;
PRINT CONCAT('WeeklyCommissionPools updated: ', @@ROWCOUNT, ' rows');
UPDATE [CMS].[UserCommissionPayouts] SET [PackageId] = 1 WHERE [PackageId] = 0;
PRINT CONCAT('UserCommissionPayouts updated: ', @@ROWCOUNT, ' rows');
UPDATE [CMS].[NetworkWeeklyBalances] SET [PackageId] = 1 WHERE [PackageId] = 0;
PRINT CONCAT('NetworkWeeklyBalances updated: ', @@ROWCOUNT, ' rows');
UPDATE [CMS].[ClubMembershipCycles] SET [PackageId] = 1 WHERE [PackageId] = 0;
PRINT CONCAT('ClubMembershipCycles updated: ', @@ROWCOUNT, ' rows');
GO
-- 3. Backfill ClubMembership First/Last Activation from existing ActivatedAt
UPDATE cm SET
cm.[FirstActivationDate] = cm.[ActivatedAt],
cm.[LastActivationDate] = cm.[ActivatedAt],
cm.[FirstPackageId] = 1,
cm.[LastPackageId] = 1
FROM [CMS].[ClubMemberships] cm
WHERE cm.[ActivatedAt] IS NOT NULL
AND cm.[FirstActivationDate] IS NULL;
PRINT CONCAT('ClubMemberships backfilled: ', @@ROWCOUNT, ' rows');
GO
-- 4. Verification Queries
SELECT 'Packages' AS [Table], COUNT(*) AS [Total],
SUM(CASE WHEN [IsBasePackage] = 1 THEN 1 ELSE 0 END) AS [BasePackages]
FROM [CMS].[Packages] WHERE [IsDeleted] = 0;
SELECT 'WeeklyCommissionPools' AS [Table],
COUNT(*) AS [Total],
SUM(CASE WHEN [PackageId] = 0 THEN 1 ELSE 0 END) AS [MissingPackageId]
FROM [CMS].[WeeklyCommissionPools] WHERE [IsDeleted] = 0;
SELECT 'ClubMemberships' AS [Table],
COUNT(*) AS [Total],
SUM(CASE WHEN [FirstPackageId] IS NOT NULL THEN 1 ELSE 0 END) AS [WithFirstPackage],
SUM(CASE WHEN [LastActivationDate] IS NOT NULL THEN 1 ELSE 0 END) AS [WithLastActivation]
FROM [CMS].[ClubMemberships] WHERE [IsDeleted] = 0;
PRINT 'Data migration completed successfully.';
GO