From 5ae350e25b6649b8b3e0ae6cef3f8fb24c121a4c Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Sun, 31 May 2026 20:53:33 +0330 Subject: [PATCH] fix: auto-create default branch on cafe registration + backfill existing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - VerifyRegisterAsync: create a Branch named after the café alongside the Café and Owner, so new owners can use the dashboard immediately without hitting the "select a branch" gate - PlatformDataSeeder: EnsureDefaultBranchesAsync runs on every boot and creates a default branch for any existing café that has none (covers cafés registered before this fix) Co-Authored-By: Claude Opus 4.7 --- src/Meezi.API/Services/AuthService.cs | 10 +++++ .../Data/PlatformDataSeeder.cs | 38 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/Meezi.API/Services/AuthService.cs b/src/Meezi.API/Services/AuthService.cs index 92034c4..1a9da1d 100644 --- a/src/Meezi.API/Services/AuthService.cs +++ b/src/Meezi.API/Services/AuthService.cs @@ -367,6 +367,15 @@ public class AuthService : IAuthService PlanTier = PlanTier.Free, }; + // Auto-create a default main branch so the owner can start using the + // dashboard immediately without hitting the "select a branch" gate. + var defaultBranch = new Branch + { + CafeId = cafe.Id, + Name = cafeName, + IsActive = true, + }; + var owner = new Employee { CafeId = cafe.Id, @@ -376,6 +385,7 @@ public class AuthService : IAuthService }; _db.Cafes.Add(cafe); + _db.Branches.Add(defaultBranch); _db.Employees.Add(owner); await _db.SaveChangesAsync(cancellationToken); diff --git a/src/Meezi.Infrastructure/Data/PlatformDataSeeder.cs b/src/Meezi.Infrastructure/Data/PlatformDataSeeder.cs index 5534019..78b81da 100644 --- a/src/Meezi.Infrastructure/Data/PlatformDataSeeder.cs +++ b/src/Meezi.Infrastructure/Data/PlatformDataSeeder.cs @@ -125,8 +125,46 @@ public static class PlatformDataSeeder await EnsureCatalogUpgradesAsync(db, logger); } + /// + /// Ensures every café has at least one active branch. Idempotent. + /// Creates a default branch named after the café for any café that has none. + /// + private static async Task EnsureDefaultBranchesAsync(AppDbContext db, ILogger logger) + { + // Load café IDs that have zero branches in one query + var cafeIdsWithBranches = await db.Branches + .Where(b => b.DeletedAt == null) + .Select(b => b.CafeId) + .Distinct() + .ToListAsync(); + + var cafesWithoutBranch = await db.Cafes + .Where(c => c.DeletedAt == null && !cafeIdsWithBranches.Contains(c.Id)) + .Select(c => new { c.Id, c.Name }) + .ToListAsync(); + + if (cafesWithoutBranch.Count == 0) return; + + foreach (var cafe in cafesWithoutBranch) + { + db.Branches.Add(new Branch + { + CafeId = cafe.Id, + Name = cafe.Name, + IsActive = true, + }); + } + + await db.SaveChangesAsync(); + logger.LogInformation("Created default branch for {Count} café(s) that had none", cafesWithoutBranch.Count); + } + private static async Task EnsureCatalogUpgradesAsync(AppDbContext db, ILogger logger) { + // Ensure every café has at least one branch. Cafés registered before the + // auto-branch feature was added are patched on the first boot after upgrade. + await EnsureDefaultBranchesAsync(db, logger); + var featureAdds = new[] { ("menu_3d", "منوی سه‌بعدی", "3D menu", "growth"),