diff --git a/LiteCharms.Features.MidrandBooks.Seed/Configuration/CdnSettings.cs b/LiteCharms.Features.MidrandBooks.Seed/Configuration/CdnSettings.cs index af16232..6eb1107 100644 --- a/LiteCharms.Features.MidrandBooks.Seed/Configuration/CdnSettings.cs +++ b/LiteCharms.Features.MidrandBooks.Seed/Configuration/CdnSettings.cs @@ -5,4 +5,10 @@ public class CdnSettings public string? BaseCdn { get; set; } public string[]? BookCovers { get; set; } + + public string[]? Authors { get; set; } + + public string[]? AuthorThumbnails { get; set; } + + public string[]? BookThumbnails { get; set; } } diff --git a/LiteCharms.Features.MidrandBooks.Seed/ProductsSeederService.cs b/LiteCharms.Features.MidrandBooks.Seed/ProductsSeederService.cs index a506bf3..9dfc582 100644 --- a/LiteCharms.Features.MidrandBooks.Seed/ProductsSeederService.cs +++ b/LiteCharms.Features.MidrandBooks.Seed/ProductsSeederService.cs @@ -65,8 +65,19 @@ public class ProductsSeederService(ProductService productService, AuthorService "Unlocking Creative Flow Under Pressure" ); - // Defensive Length Processing to avoid Entity Framework / Postgres string truncation crashes - var rawTitle = $"{faker.Company.CatchPhrase()} with {bookTopic}"; + // Dynamic raw title generation formulas executed via random function picker + var titlePatterns = new Func[] + { + () => $"{faker.Company.CatchPhrase()} with {bookTopic}", + () => $"The {faker.Commerce.ProductAdjective()} Guide to {bookTopic}", + () => $"Mastering {bookTopic}: A {faker.Company.Bs()} Blueprint", + () => $"{bookTopic} for the Modern {faker.Name.JobTitle()}", + () => $"Advanced {bookTopic}: Demystifying the {faker.Company.CatchPhrase()}", + () => $"{faker.Random.Replace("###")} Blueprints for {bookTopic}" + }; + + // Pick a format template and resolve it down to raw string text + var rawTitle = faker.PickRandom(titlePatterns)(); var bookTitle = rawTitle.Length > 255 ? rawTitle[..252] + "..." : rawTitle; var rawSummary = $"A comprehensive guide to mastering {bookTopic}. Learn modern implementation techniques through real-world software engineering paradigms."; @@ -80,6 +91,21 @@ public class ProductsSeederService(ProductService productService, AuthorService var authorLastName = faker.Name.LastName(); var publisherCompany = faker.Company.CompanyName(); + // Safe bounded random picking for book thumbnails + string? pickedBookThumbnail = null; + string? pickedBookThumbnail1 = null; + string? pickedBookThumbnail2 = null; + string? pickedBookThumbnail3 = null; + string? pickedBookThumbnail4 = null; + if (cdnSettings.BookThumbnails is not null && cdnSettings.BookThumbnails.Length > 0) + { + pickedBookThumbnail = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.BookThumbnails)}"; + pickedBookThumbnail1 = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.BookThumbnails)}"; + pickedBookThumbnail2 = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.BookThumbnails)}"; + pickedBookThumbnail3 = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.BookThumbnails)}"; + pickedBookThumbnail4 = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.BookThumbnails)}"; + } + // Step 1: Add Product var productCreateResult = await productService.CreateProductAsync(new Products.Models.CreateProduct { @@ -95,7 +121,8 @@ public class ProductsSeederService(ProductService productService, AuthorService Manufacturer = $"{authorFirstName} {authorLastName} / {publisherCompany}", SerialNumber = faker.Phone.PhoneNumber("978-##########") }, - Categories = ["Coding", "Computers", "IT"] + Categories = ["Coding", "Computers", "IT"], + ThumbnailUrls = pickedBookThumbnail is not null ? [pickedBookThumbnail, pickedBookThumbnail1!, pickedBookThumbnail2!, pickedBookThumbnail3!, pickedBookThumbnail4!] : null }, stoppingToken); if (productCreateResult.IsFailed) @@ -116,7 +143,6 @@ public class ProductsSeederService(ProductService productService, AuthorService // Step 3: Create Product Price var productPriceCreateResult = await productService.CreateProductPriceAsync(productId: productCreateResult.Value, request: new Products.Models.CreateProductPrice { - // Generates fair, dynamic prices in Rands between R150 and R650, snapped neatly to integers Amount = Math.Round(faker.Random.Decimal(150m, 650m), 2), Discount = 0.0m }, stoppingToken); @@ -127,6 +153,34 @@ public class ProductsSeederService(ProductService productService, AuthorService break; } + // Safe bounded picking for Authors (Real Avatars) + string authorAvatarUrl = faker.Internet.Avatar(); // Fallback + if (cdnSettings.Authors is not null && cdnSettings.Authors.Length > 0) + { + authorAvatarUrl = $"{cdnSettings.BaseCdn}{faker.PickRandom(cdnSettings.Authors)}"; + } + + // Safe bounded picking for Author Thumbnails (Cartoon Avatars) + string? authorThumbnailUrl = null; + if (cdnSettings.AuthorThumbnails is not null && cdnSettings.AuthorThumbnails.Length > 0) + { + var selectedThumb = faker.PickRandom(cdnSettings.AuthorThumbnails); + authorThumbnailUrl = $"{cdnSettings.BaseCdn}{selectedThumb}.jpg"; + } + + // Synthesize a highly dynamic, organic opening bio statement + var professionalBackgrounds = new[] + { + $"{authorFirstName} {authorLastName} is an award-winning {faker.Name.JobDescriptor()} {faker.Name.JobTitle()} with over {faker.Random.Number(5, 25)} years of core engineering domain expertise.", + $"As a veteran systems consultant and practicing {faker.Name.JobTitle()}, {authorFirstName} has spent decades leading digital infrastructure transformations and managing complex topologies.", + $"Operating from modern innovation hubs, {authorFirstName} {authorLastName} specializes in global product strategies and serves as an authority in {faker.Name.JobDescriptor()} computing.", + $"With a rich professional background as a principal {faker.Name.JobTitle()} at {publisherCompany}, {authorFirstName} has spent a lifetime refining the system workflows highlighted here." + }; + + // Pick a randomized context hook and append a 2-paragraph contextual narrative block + var biographyPrefix = faker.PickRandom(professionalBackgrounds); + var authorBiography = $"{biographyPrefix} {faker.Lorem.Paragraph(2)}"; + // Step 4: Create Author var authorCreateResult = await authorService.CreateAuthorAsync(request: new Authors.Models.CreateAuthor { @@ -137,7 +191,7 @@ public class ProductsSeederService(ProductService productService, AuthorService PublisherType = faker.PickRandom(), Email = faker.Internet.Email(authorFirstName, authorLastName), Website = faker.Internet.Url(), - ImageUrl = faker.Internet.Avatar(), + ImageUrl = authorAvatarUrl, SocialMedia = [ new Models.SocialMedia @@ -155,8 +209,8 @@ public class ProductsSeederService(ProductService productService, AuthorService Url = $"https://github.com/tech-{authorFirstName.ToLower(culture)}" } ], - Biography = $"{authorFirstName} {authorLastName} is a veteran technologist and systems architect with over a decade of domain expertise. " + faker.Lorem.Paragraph(2), - ThumbnailImageUrl = null + Biography = authorBiography, + ThumbnailImageUrl = authorThumbnailUrl }, stoppingToken); if (authorCreateResult.IsFailed) diff --git a/LiteCharms.Features.MidrandBooks.Seed/appsettings.json b/LiteCharms.Features.MidrandBooks.Seed/appsettings.json index 1dc7baa..ce89459 100644 --- a/LiteCharms.Features.MidrandBooks.Seed/appsettings.json +++ b/LiteCharms.Features.MidrandBooks.Seed/appsettings.json @@ -23,6 +23,239 @@ "d44a3c04-f124-4f0b-8301-3841ae2fd439_1764780121224.webp", "e6ba52f208914285bcdf1966cfb08f6f.jpg", "fa9cbbe6-f947-4f83-8e98-61d2661f43e0_1764841636705.webp" - ] + ], + "Authors": [ + "authors/uifaces-human-avatar.jpg", + "authors/uifaces-human-avatar-1.jpg", + "authors/uifaces-human-avatar-2.jpg", + "authors/uifaces-human-avatar-3.jpg", + "authors/uifaces-human-avatar-4.jpg", + "authors/uifaces-human-avatar-5.jpg", + "authors/uifaces-human-avatar-6.jpg", + "authors/uifaces-human-avatar-7.jpg", + "authors/uifaces-human-avatar-8.jpg", + "authors/uifaces-human-avatar-9.jpg", + "authors/uifaces-human-avatar-10.jpg", + "authors/uifaces-human-avatar-11.jpg", + "authors/uifaces-human-avatar-12.jpg", + "authors/uifaces-human-avatar-13.jpg", + "authors/uifaces-human-avatar-14.jpg", + "authors/uifaces-human-avatar-15.jpg", + "authors/uifaces-human-avatar-16.jpg" + ], + "AuthorThumbnails": [ + "authors/thumbnails/uifaces-cartoon-avatar-1", + "authors/thumbnails/uifaces-cartoon-avatar-2", + "authors/thumbnails/uifaces-cartoon-avatar-3", + "authors/thumbnails/uifaces-cartoon-avatar-4", + "authors/thumbnails/uifaces-cartoon-avatar-5", + "authors/thumbnails/uifaces-cartoon-avatar-6", + "authors/thumbnails/uifaces-cartoon-avatar-7", + "authors/thumbnails/uifaces-cartoon-avatar-8", + "authors/thumbnails/uifaces-cartoon-avatar-9", + "authors/thumbnails/uifaces-cartoon-avatar-10" + ], + "BookThumbnails": [ + "thumbnails/book_thumbnail_001.jpg", + "thumbnails/book_thumbnail_002.jpg", + "thumbnails/book_thumbnail_003.jpg", + "thumbnails/book_thumbnail_004.jpg", + "thumbnails/book_thumbnail_005.jpg", + "thumbnails/book_thumbnail_006.jpg", + "thumbnails/book_thumbnail_007.jpg", + "thumbnails/book_thumbnail_008.jpg", + "thumbnails/book_thumbnail_009.jpg", + "thumbnails/book_thumbnail_010.jpg", + "thumbnails/book_thumbnail_011.jpg", + "thumbnails/book_thumbnail_012.jpg", + "thumbnails/book_thumbnail_013.jpg", + "thumbnails/book_thumbnail_014.jpg", + "thumbnails/book_thumbnail_015.jpg", + "thumbnails/book_thumbnail_016.jpg", + "thumbnails/book_thumbnail_017.jpg", + "thumbnails/book_thumbnail_018.jpg", + "thumbnails/book_thumbnail_019.jpg", + "thumbnails/book_thumbnail_020.jpg", + "thumbnails/book_thumbnail_021.jpg", + "thumbnails/book_thumbnail_022.jpg", + "thumbnails/book_thumbnail_023.jpg", + "thumbnails/book_thumbnail_024.jpg", + "thumbnails/book_thumbnail_025.jpg", + "thumbnails/book_thumbnail_026.jpg", + "thumbnails/book_thumbnail_027.jpg", + "thumbnails/book_thumbnail_028.jpg", + "thumbnails/book_thumbnail_029.jpg", + "thumbnails/book_thumbnail_030.jpg", + "thumbnails/book_thumbnail_031.jpg", + "thumbnails/book_thumbnail_032.jpg", + "thumbnails/book_thumbnail_033.jpg", + "thumbnails/book_thumbnail_034.jpg", + "thumbnails/book_thumbnail_035.jpg", + "thumbnails/book_thumbnail_036.jpg", + "thumbnails/book_thumbnail_037.jpg", + "thumbnails/book_thumbnail_038.jpg", + "thumbnails/book_thumbnail_039.jpg", + "thumbnails/book_thumbnail_040.jpg", + "thumbnails/book_thumbnail_041.jpg", + "thumbnails/book_thumbnail_042.jpg", + "thumbnails/book_thumbnail_043.jpg", + "thumbnails/book_thumbnail_044.jpg", + "thumbnails/book_thumbnail_045.jpg", + "thumbnails/book_thumbnail_046.jpg", + "thumbnails/book_thumbnail_047.jpg", + "thumbnails/book_thumbnail_048.jpg", + "thumbnails/book_thumbnail_049.jpg", + "thumbnails/book_thumbnail_050.jpg", + "thumbnails/book_thumbnail_051.jpg", + "thumbnails/book_thumbnail_052.jpg", + "thumbnails/book_thumbnail_053.jpg", + "thumbnails/book_thumbnail_054.jpg", + "thumbnails/book_thumbnail_055.jpg", + "thumbnails/book_thumbnail_056.jpg", + "thumbnails/book_thumbnail_057.jpg", + "thumbnails/book_thumbnail_058.jpg", + "thumbnails/book_thumbnail_059.jpg", + "thumbnails/book_thumbnail_060.jpg", + "thumbnails/book_thumbnail_061.jpg", + "thumbnails/book_thumbnail_062.jpg", + "thumbnails/book_thumbnail_063.jpg", + "thumbnails/book_thumbnail_064.jpg", + "thumbnails/book_thumbnail_065.jpg", + "thumbnails/book_thumbnail_066.jpg", + "thumbnails/book_thumbnail_067.jpg", + "thumbnails/book_thumbnail_068.jpg", + "thumbnails/book_thumbnail_069.jpg", + "thumbnails/book_thumbnail_070.jpg", + "thumbnails/book_thumbnail_071.jpg", + "thumbnails/book_thumbnail_072.jpg", + "thumbnails/book_thumbnail_073.jpg", + "thumbnails/book_thumbnail_074.jpg", + "thumbnails/book_thumbnail_075.jpg", + "thumbnails/book_thumbnail_076.jpg", + "thumbnails/book_thumbnail_077.jpg", + "thumbnails/book_thumbnail_078.jpg", + "thumbnails/book_thumbnail_079.jpg", + "thumbnails/book_thumbnail_080.jpg", + "thumbnails/book_thumbnail_081.jpg", + "thumbnails/book_thumbnail_082.jpg", + "thumbnails/book_thumbnail_083.jpg", + "thumbnails/book_thumbnail_084.jpg", + "thumbnails/book_thumbnail_085.jpg", + "thumbnails/book_thumbnail_086.jpg", + "thumbnails/book_thumbnail_087.jpg", + "thumbnails/book_thumbnail_088.jpg", + "thumbnails/book_thumbnail_089.jpg", + "thumbnails/book_thumbnail_090.jpg", + "thumbnails/book_thumbnail_091.jpg", + "thumbnails/book_thumbnail_092.jpg", + "thumbnails/book_thumbnail_093.jpg", + "thumbnails/book_thumbnail_094.jpg", + "thumbnails/book_thumbnail_095.jpg", + "thumbnails/book_thumbnail_096.jpg", + "thumbnails/book_thumbnail_097.jpg", + "thumbnails/book_thumbnail_098.jpg", + "thumbnails/book_thumbnail_099.jpg", + "thumbnails/book_thumbnail_100.jpg", + "thumbnails/book_thumbnail_101.jpg", + "thumbnails/book_thumbnail_102.jpg", + "thumbnails/book_thumbnail_103.jpg", + "thumbnails/book_thumbnail_104.jpg", + "thumbnails/book_thumbnail_105.jpg", + "thumbnails/book_thumbnail_106.jpg", + "thumbnails/book_thumbnail_107.jpg", + "thumbnails/book_thumbnail_108.jpg", + "thumbnails/book_thumbnail_109.jpg", + "thumbnails/book_thumbnail_110.jpg", + "thumbnails/book_thumbnail_111.jpg", + "thumbnails/book_thumbnail_112.jpg", + "thumbnails/book_thumbnail_113.jpg", + "thumbnails/book_thumbnail_114.jpg", + "thumbnails/book_thumbnail_115.jpg", + "thumbnails/book_thumbnail_116.jpg", + "thumbnails/book_thumbnail_117.jpg", + "thumbnails/book_thumbnail_118.jpg", + "thumbnails/book_thumbnail_119.jpg", + "thumbnails/book_thumbnail_120.jpg", + "thumbnails/book_thumbnail_121.jpg", + "thumbnails/book_thumbnail_122.jpg", + "thumbnails/book_thumbnail_123.jpg", + "thumbnails/book_thumbnail_124.jpg", + "thumbnails/book_thumbnail_125.jpg", + "thumbnails/book_thumbnail_126.jpg", + "thumbnails/book_thumbnail_127.jpg", + "thumbnails/book_thumbnail_128.jpg", + "thumbnails/book_thumbnail_129.jpg", + "thumbnails/book_thumbnail_130.jpg", + "thumbnails/book_thumbnail_131.jpg", + "thumbnails/book_thumbnail_132.jpg", + "thumbnails/book_thumbnail_133.jpg", + "thumbnails/book_thumbnail_134.jpg", + "thumbnails/book_thumbnail_135.jpg", + "thumbnails/book_thumbnail_136.jpg", + "thumbnails/book_thumbnail_137.jpg", + "thumbnails/book_thumbnail_138.jpg", + "thumbnails/book_thumbnail_139.jpg", + "thumbnails/book_thumbnail_140.jpg", + "thumbnails/book_thumbnail_141.jpg", + "thumbnails/book_thumbnail_142.jpg", + "thumbnails/book_thumbnail_143.jpg", + "thumbnails/book_thumbnail_144.jpg", + "thumbnails/book_thumbnail_145.jpg", + "thumbnails/book_thumbnail_146.jpg", + "thumbnails/book_thumbnail_147.jpg", + "thumbnails/book_thumbnail_148.jpg", + "thumbnails/book_thumbnail_149.jpg", + "thumbnails/book_thumbnail_150.jpg", + "thumbnails/book_thumbnail_151.jpg", + "thumbnails/book_thumbnail_152.jpg", + "thumbnails/book_thumbnail_153.jpg", + "thumbnails/book_thumbnail_154.jpg", + "thumbnails/book_thumbnail_155.jpg", + "thumbnails/book_thumbnail_156.jpg", + "thumbnails/book_thumbnail_157.jpg", + "thumbnails/book_thumbnail_158.jpg", + "thumbnails/book_thumbnail_159.jpg", + "thumbnails/book_thumbnail_160.jpg", + "thumbnails/book_thumbnail_161.jpg", + "thumbnails/book_thumbnail_162.jpg", + "thumbnails/book_thumbnail_163.jpg", + "thumbnails/book_thumbnail_164.jpg", + "thumbnails/book_thumbnail_165.jpg", + "thumbnails/book_thumbnail_166.jpg", + "thumbnails/book_thumbnail_167.jpg", + "thumbnails/book_thumbnail_168.jpg", + "thumbnails/book_thumbnail_169.jpg", + "thumbnails/book_thumbnail_170.jpg", + "thumbnails/book_thumbnail_171.jpg", + "thumbnails/book_thumbnail_172.jpg", + "thumbnails/book_thumbnail_173.jpg", + "thumbnails/book_thumbnail_174.jpg", + "thumbnails/book_thumbnail_175.jpg", + "thumbnails/book_thumbnail_176.jpg", + "thumbnails/book_thumbnail_177.jpg", + "thumbnails/book_thumbnail_178.jpg", + "thumbnails/book_thumbnail_179.jpg", + "thumbnails/book_thumbnail_180.jpg", + "thumbnails/book_thumbnail_181.jpg", + "thumbnails/book_thumbnail_182.jpg", + "thumbnails/book_thumbnail_183.jpg", + "thumbnails/book_thumbnail_184.jpg", + "thumbnails/book_thumbnail_185.jpg", + "thumbnails/book_thumbnail_186.jpg", + "thumbnails/book_thumbnail_187.jpg", + "thumbnails/book_thumbnail_188.jpg", + "thumbnails/book_thumbnail_189.jpg", + "thumbnails/book_thumbnail_190.jpg", + "thumbnails/book_thumbnail_191.jpg", + "thumbnails/book_thumbnail_192.jpg", + "thumbnails/book_thumbnail_193.jpg", + "thumbnails/book_thumbnail_194.jpg", + "thumbnails/book_thumbnail_195.jpg", + "thumbnails/book_thumbnail_196.jpg", + "thumbnails/book_thumbnail_197.jpg", + "thumbnails/book_thumbnail_198.jpg", + "thumbnails/book_thumbnail_199.jpg", + "thumbnails/book_thumbnail_200.jpg" + ] } -} +} \ No newline at end of file